@openstax/ts-utils 1.34.0 → 1.35.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 (507) hide show
  1. package/README.md +90 -62
  2. package/dist/cjs/assertions/index.d.ts +89 -0
  3. package/dist/cjs/assertions/index.js +157 -0
  4. package/dist/cjs/aws/ssmService.d.ts +5 -0
  5. package/dist/cjs/aws/ssmService.js +9 -0
  6. package/dist/cjs/config/awsParameterConfig.d.ts +10 -0
  7. package/dist/cjs/config/awsParameterConfig.js +26 -0
  8. package/dist/cjs/config/envConfig.d.ts +24 -0
  9. package/dist/cjs/config/envConfig.js +57 -0
  10. package/{packages/utils/src/config/index.ts → dist/cjs/config/index.d.ts} +13 -29
  11. package/dist/cjs/config/index.js +35 -0
  12. package/dist/cjs/config/lambdaParameterConfig.d.ts +12 -0
  13. package/dist/cjs/config/lambdaParameterConfig.js +45 -0
  14. package/dist/cjs/config/replaceConfig.d.ts +14 -0
  15. package/dist/cjs/config/replaceConfig.js +22 -0
  16. package/dist/cjs/config/resolveConfigValue.d.ts +5 -0
  17. package/dist/cjs/config/resolveConfigValue.js +12 -0
  18. package/dist/cjs/errors/index.d.ts +88 -0
  19. package/dist/cjs/errors/index.js +123 -0
  20. package/dist/cjs/fetch/fetchStatusRetry.d.ts +8 -0
  21. package/dist/cjs/fetch/fetchStatusRetry.js +27 -0
  22. package/dist/cjs/fetch/index.d.ts +64 -0
  23. package/dist/cjs/fetch/index.js +55 -0
  24. package/{packages/utils/src/guards/index.ts → dist/cjs/guards/index.d.ts} +7 -10
  25. package/dist/cjs/guards/index.js +44 -0
  26. package/dist/cjs/index.js +20 -0
  27. package/dist/cjs/middleware/apiErrorHandler.d.ts +24 -0
  28. package/dist/cjs/middleware/apiErrorHandler.js +42 -0
  29. package/dist/cjs/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  30. package/dist/cjs/middleware/apiSlowResponseMiddleware.js +54 -0
  31. package/{packages/utils/src/middleware/index.ts → dist/cjs/middleware/index.d.ts} +5 -53
  32. package/dist/cjs/middleware/index.js +48 -0
  33. package/dist/cjs/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  34. package/dist/cjs/middleware/lambdaCorsResponseMiddleware.js +44 -0
  35. package/dist/cjs/middleware/throwNotFoundMiddleware.d.ts +4 -0
  36. package/dist/cjs/middleware/throwNotFoundMiddleware.js +14 -0
  37. package/dist/cjs/misc/hashValue.d.ts +10 -0
  38. package/dist/cjs/misc/hashValue.js +17 -0
  39. package/dist/cjs/misc/helpers.d.ts +124 -0
  40. package/dist/cjs/misc/helpers.js +214 -0
  41. package/dist/cjs/misc/merge.d.ts +21 -0
  42. package/dist/cjs/misc/merge.js +45 -0
  43. package/dist/cjs/misc/partitionSequence.d.ts +35 -0
  44. package/dist/cjs/misc/partitionSequence.js +55 -0
  45. package/dist/cjs/pagination/index.d.ts +91 -0
  46. package/dist/cjs/pagination/index.js +83 -0
  47. package/dist/cjs/routing/helpers.d.ts +57 -0
  48. package/dist/cjs/routing/helpers.js +90 -0
  49. package/dist/cjs/routing/index.d.ts +290 -0
  50. package/dist/cjs/routing/index.js +295 -0
  51. package/dist/cjs/routing/validators/zod.d.ts +4 -0
  52. package/dist/cjs/routing/validators/zod.js +14 -0
  53. package/dist/cjs/services/accountsGateway/index.d.ts +92 -0
  54. package/dist/cjs/services/accountsGateway/index.js +138 -0
  55. package/dist/cjs/services/apiGateway/index.d.ts +68 -0
  56. package/dist/cjs/services/apiGateway/index.js +118 -0
  57. package/dist/cjs/services/authProvider/browser.d.ts +40 -0
  58. package/dist/cjs/services/authProvider/browser.js +155 -0
  59. package/dist/cjs/services/authProvider/decryption.d.ts +19 -0
  60. package/dist/cjs/services/authProvider/decryption.js +73 -0
  61. package/dist/cjs/services/authProvider/index.d.ts +63 -0
  62. package/dist/cjs/services/authProvider/index.js +34 -0
  63. package/dist/cjs/services/authProvider/subrequest.d.ts +13 -0
  64. package/dist/cjs/services/authProvider/subrequest.js +49 -0
  65. package/dist/cjs/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  66. package/dist/cjs/services/authProvider/utils/decryptAndVerify.js +91 -0
  67. package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  68. package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.js +47 -0
  69. package/dist/cjs/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  70. package/dist/cjs/services/authProvider/utils/userRoleValidator.js +37 -0
  71. package/dist/cjs/services/authProvider/utils/userSubrequest.d.ts +3 -0
  72. package/dist/cjs/services/authProvider/utils/userSubrequest.js +13 -0
  73. package/dist/cjs/services/documentStore/dynamoEncoding.d.ts +10 -0
  74. package/dist/cjs/services/documentStore/dynamoEncoding.js +52 -0
  75. package/dist/cjs/services/documentStore/fileSystemAssert.d.ts +1 -0
  76. package/dist/cjs/services/documentStore/fileSystemAssert.js +14 -0
  77. package/{packages/utils/src/services/documentStore/index.ts → dist/cjs/services/documentStore/index.d.ts} +8 -8
  78. package/dist/cjs/services/documentStore/index.js +2 -0
  79. package/dist/cjs/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  80. package/dist/cjs/services/documentStore/unversioned/dynamodb.js +233 -0
  81. package/dist/cjs/services/documentStore/unversioned/file-system.d.ts +32 -0
  82. package/dist/cjs/services/documentStore/unversioned/file-system.js +214 -0
  83. package/{packages/utils/src/services/documentStore/unversioned/index.ts → dist/cjs/services/documentStore/unversioned/index.d.ts} +0 -2
  84. package/dist/cjs/services/documentStore/unversioned/index.js +2 -0
  85. package/dist/cjs/services/documentStore/versioned/dynamodb.d.ts +25 -0
  86. package/dist/cjs/services/documentStore/versioned/dynamodb.js +143 -0
  87. package/dist/cjs/services/documentStore/versioned/file-system.d.ts +25 -0
  88. package/dist/cjs/services/documentStore/versioned/file-system.js +73 -0
  89. package/dist/cjs/services/documentStore/versioned/index.d.ts +17 -0
  90. package/dist/cjs/services/documentStore/versioned/index.js +2 -0
  91. package/dist/cjs/services/exercisesGateway/index.d.ts +67 -0
  92. package/dist/cjs/services/exercisesGateway/index.js +107 -0
  93. package/dist/cjs/services/fileServer/index.d.ts +30 -0
  94. package/dist/cjs/services/fileServer/index.js +19 -0
  95. package/dist/cjs/services/fileServer/localFileServer.d.ts +13 -0
  96. package/dist/cjs/services/fileServer/localFileServer.js +132 -0
  97. package/dist/cjs/services/fileServer/s3FileServer.d.ts +14 -0
  98. package/dist/cjs/services/fileServer/s3FileServer.js +131 -0
  99. package/dist/cjs/services/launchParams/index.js +7 -0
  100. package/dist/cjs/services/launchParams/signer.d.ts +23 -0
  101. package/dist/cjs/services/launchParams/signer.js +58 -0
  102. package/dist/cjs/services/launchParams/verifier.d.ts +21 -0
  103. package/dist/cjs/services/launchParams/verifier.js +129 -0
  104. package/dist/cjs/services/logger/console.d.ts +4 -0
  105. package/dist/cjs/services/logger/console.js +12 -0
  106. package/{packages/utils/src/services/logger/index.ts → dist/cjs/services/logger/index.d.ts} +9 -23
  107. package/dist/cjs/services/logger/index.js +31 -0
  108. package/dist/cjs/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  109. package/dist/cjs/services/lrsGateway/addStatementDefaultFields.js +21 -0
  110. package/dist/cjs/services/lrsGateway/attempt-utils.d.ts +72 -0
  111. package/dist/cjs/services/lrsGateway/attempt-utils.js +283 -0
  112. package/dist/cjs/services/lrsGateway/file-system.d.ts +15 -0
  113. package/dist/cjs/services/lrsGateway/file-system.js +150 -0
  114. package/dist/cjs/services/lrsGateway/index.d.ts +122 -0
  115. package/dist/cjs/services/lrsGateway/index.js +148 -0
  116. package/dist/cjs/services/lrsGateway/xapiUtils.d.ts +71 -0
  117. package/dist/cjs/services/lrsGateway/xapiUtils.js +145 -0
  118. package/dist/cjs/services/postgresConnection/index.d.ts +28 -0
  119. package/dist/cjs/services/postgresConnection/index.js +65 -0
  120. package/dist/cjs/services/searchProvider/index.d.ts +69 -0
  121. package/dist/cjs/services/searchProvider/index.js +2 -0
  122. package/dist/cjs/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  123. package/dist/cjs/services/searchProvider/memorySearchTheBadWay.js +191 -0
  124. package/dist/cjs/services/searchProvider/openSearch.d.ts +28 -0
  125. package/dist/cjs/services/searchProvider/openSearch.js +162 -0
  126. package/dist/cjs/services/searchProvider/streamIndexer.d.ts +17 -0
  127. package/dist/cjs/services/searchProvider/streamIndexer.js +41 -0
  128. package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -0
  129. package/{packages/utils/src/types.ts → dist/cjs/types.d.ts} +6 -34
  130. package/dist/cjs/types.js +2 -0
  131. package/dist/esm/assertions/index.d.ts +89 -0
  132. package/{packages/utils/src/assertions/index.ts → dist/esm/assertions/index.js} +49 -64
  133. package/dist/esm/aws/ssmService.d.ts +5 -0
  134. package/dist/esm/aws/ssmService.js +6 -0
  135. package/dist/esm/config/awsParameterConfig.d.ts +10 -0
  136. package/dist/esm/config/awsParameterConfig.js +22 -0
  137. package/dist/esm/config/envConfig.d.ts +24 -0
  138. package/dist/esm/config/envConfig.js +53 -0
  139. package/dist/esm/config/index.d.ts +48 -0
  140. package/dist/esm/config/index.js +17 -0
  141. package/dist/esm/config/lambdaParameterConfig.d.ts +12 -0
  142. package/dist/esm/config/lambdaParameterConfig.js +38 -0
  143. package/dist/esm/config/replaceConfig.d.ts +14 -0
  144. package/{packages/utils/src/config/replaceConfig.ts → dist/esm/config/replaceConfig.js} +6 -16
  145. package/dist/esm/config/resolveConfigValue.d.ts +5 -0
  146. package/dist/esm/config/resolveConfigValue.js +8 -0
  147. package/dist/esm/errors/index.d.ts +88 -0
  148. package/{packages/utils/src/errors/index.ts → dist/esm/errors/index.js} +41 -57
  149. package/dist/esm/fetch/fetchStatusRetry.d.ts +8 -0
  150. package/dist/esm/fetch/fetchStatusRetry.js +23 -0
  151. package/dist/esm/fetch/index.d.ts +64 -0
  152. package/dist/esm/fetch/index.js +46 -0
  153. package/dist/esm/guards/index.d.ts +38 -0
  154. package/dist/esm/guards/index.js +36 -0
  155. package/dist/esm/index.d.ts +4 -0
  156. package/dist/esm/index.js +4 -0
  157. package/dist/esm/middleware/apiErrorHandler.d.ts +24 -0
  158. package/dist/esm/middleware/apiErrorHandler.js +38 -0
  159. package/dist/esm/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  160. package/dist/esm/middleware/apiSlowResponseMiddleware.js +50 -0
  161. package/dist/esm/middleware/index.d.ts +47 -0
  162. package/dist/esm/middleware/index.js +44 -0
  163. package/dist/esm/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  164. package/dist/esm/middleware/lambdaCorsResponseMiddleware.js +40 -0
  165. package/dist/esm/middleware/throwNotFoundMiddleware.d.ts +4 -0
  166. package/dist/esm/middleware/throwNotFoundMiddleware.js +10 -0
  167. package/dist/esm/misc/hashValue.d.ts +10 -0
  168. package/dist/esm/misc/hashValue.js +13 -0
  169. package/dist/esm/misc/helpers.d.ts +124 -0
  170. package/dist/esm/misc/helpers.js +199 -0
  171. package/dist/esm/misc/merge.d.ts +21 -0
  172. package/dist/esm/misc/merge.js +40 -0
  173. package/dist/esm/misc/partitionSequence.d.ts +35 -0
  174. package/{packages/utils/src/misc/partitionSequence.ts → dist/esm/misc/partitionSequence.js} +15 -23
  175. package/dist/esm/pagination/index.d.ts +91 -0
  176. package/dist/esm/pagination/index.js +77 -0
  177. package/dist/esm/routing/helpers.d.ts +57 -0
  178. package/{packages/utils/src/routing/helpers.ts → dist/esm/routing/helpers.js} +30 -42
  179. package/dist/esm/routing/index.d.ts +290 -0
  180. package/dist/esm/routing/index.js +246 -0
  181. package/dist/esm/routing/validators/zod.d.ts +4 -0
  182. package/dist/esm/routing/validators/zod.js +10 -0
  183. package/dist/esm/services/accountsGateway/index.d.ts +92 -0
  184. package/dist/esm/services/accountsGateway/index.js +131 -0
  185. package/dist/esm/services/apiGateway/index.d.ts +68 -0
  186. package/dist/esm/services/apiGateway/index.js +77 -0
  187. package/dist/esm/services/authProvider/browser.d.ts +40 -0
  188. package/dist/esm/services/authProvider/browser.js +151 -0
  189. package/dist/esm/services/authProvider/decryption.d.ts +19 -0
  190. package/dist/esm/services/authProvider/decryption.js +69 -0
  191. package/dist/esm/services/authProvider/index.d.ts +63 -0
  192. package/dist/esm/services/authProvider/index.js +26 -0
  193. package/dist/esm/services/authProvider/subrequest.d.ts +13 -0
  194. package/dist/esm/services/authProvider/subrequest.js +45 -0
  195. package/dist/esm/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  196. package/dist/esm/services/authProvider/utils/decryptAndVerify.js +85 -0
  197. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  198. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.js +40 -0
  199. package/dist/esm/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  200. package/dist/esm/services/authProvider/utils/userRoleValidator.js +33 -0
  201. package/dist/esm/services/authProvider/utils/userSubrequest.d.ts +3 -0
  202. package/dist/esm/services/authProvider/utils/userSubrequest.js +6 -0
  203. package/dist/esm/services/documentStore/dynamoEncoding.d.ts +10 -0
  204. package/dist/esm/services/documentStore/dynamoEncoding.js +45 -0
  205. package/dist/esm/services/documentStore/fileSystemAssert.d.ts +1 -0
  206. package/dist/esm/services/documentStore/fileSystemAssert.js +10 -0
  207. package/dist/esm/services/documentStore/index.d.ts +14 -0
  208. package/dist/esm/services/documentStore/index.js +1 -0
  209. package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  210. package/dist/esm/services/documentStore/unversioned/dynamodb.js +226 -0
  211. package/dist/esm/services/documentStore/unversioned/file-system.d.ts +32 -0
  212. package/dist/esm/services/documentStore/unversioned/file-system.js +174 -0
  213. package/dist/esm/services/documentStore/unversioned/index.d.ts +2 -0
  214. package/dist/esm/services/documentStore/unversioned/index.js +1 -0
  215. package/dist/esm/services/documentStore/versioned/dynamodb.d.ts +25 -0
  216. package/dist/esm/services/documentStore/versioned/dynamodb.js +139 -0
  217. package/dist/esm/services/documentStore/versioned/file-system.d.ts +25 -0
  218. package/dist/esm/services/documentStore/versioned/file-system.js +69 -0
  219. package/dist/esm/services/documentStore/versioned/index.d.ts +17 -0
  220. package/dist/esm/services/documentStore/versioned/index.js +1 -0
  221. package/dist/esm/services/exercisesGateway/index.d.ts +67 -0
  222. package/dist/esm/services/exercisesGateway/index.js +70 -0
  223. package/dist/esm/services/fileServer/index.d.ts +30 -0
  224. package/dist/esm/services/fileServer/index.js +13 -0
  225. package/dist/esm/services/fileServer/localFileServer.d.ts +13 -0
  226. package/dist/esm/services/fileServer/localFileServer.js +125 -0
  227. package/dist/esm/services/fileServer/s3FileServer.d.ts +14 -0
  228. package/dist/esm/services/fileServer/s3FileServer.js +124 -0
  229. package/dist/esm/services/launchParams/index.d.ts +2 -0
  230. package/dist/esm/services/launchParams/index.js +2 -0
  231. package/dist/esm/services/launchParams/signer.d.ts +23 -0
  232. package/dist/esm/services/launchParams/signer.js +51 -0
  233. package/dist/esm/services/launchParams/verifier.d.ts +21 -0
  234. package/dist/esm/services/launchParams/verifier.js +92 -0
  235. package/dist/esm/services/logger/console.d.ts +4 -0
  236. package/{packages/utils/src/services/logger/console.ts → dist/esm/services/logger/console.js} +2 -5
  237. package/dist/esm/services/logger/index.d.ts +39 -0
  238. package/dist/esm/services/logger/index.js +27 -0
  239. package/dist/esm/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  240. package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +14 -0
  241. package/dist/esm/services/lrsGateway/attempt-utils.d.ts +72 -0
  242. package/dist/esm/services/lrsGateway/attempt-utils.js +261 -0
  243. package/dist/esm/services/lrsGateway/file-system.d.ts +15 -0
  244. package/dist/esm/services/lrsGateway/file-system.js +110 -0
  245. package/dist/esm/services/lrsGateway/index.d.ts +122 -0
  246. package/dist/esm/services/lrsGateway/index.js +111 -0
  247. package/dist/esm/services/lrsGateway/xapiUtils.d.ts +71 -0
  248. package/dist/esm/services/lrsGateway/xapiUtils.js +134 -0
  249. package/dist/esm/services/postgresConnection/index.d.ts +28 -0
  250. package/dist/esm/services/postgresConnection/index.js +58 -0
  251. package/dist/esm/services/searchProvider/index.d.ts +69 -0
  252. package/dist/esm/services/searchProvider/index.js +1 -0
  253. package/dist/esm/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  254. package/dist/esm/services/searchProvider/memorySearchTheBadWay.js +187 -0
  255. package/dist/esm/services/searchProvider/openSearch.d.ts +28 -0
  256. package/dist/esm/services/searchProvider/openSearch.js +158 -0
  257. package/dist/esm/services/searchProvider/streamIndexer.d.ts +17 -0
  258. package/dist/esm/services/searchProvider/streamIndexer.js +37 -0
  259. package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -0
  260. package/dist/esm/types.d.ts +31 -0
  261. package/dist/esm/types.js +1 -0
  262. package/package.json +234 -12
  263. package/.cfnlintrc +0 -2
  264. package/.github/CODEOWNERS +0 -1
  265. package/.github/workflows/ci.yml +0 -36
  266. package/.github/workflows/lint.yml +0 -55
  267. package/.nvmrc +0 -1
  268. package/.syncignore +0 -4
  269. package/.syncpackrc +0 -18
  270. package/CONTRIBUTING.md +0 -96
  271. package/LICENSE +0 -661
  272. package/Procfile +0 -1
  273. package/app.json +0 -23
  274. package/cspell.json +0 -32
  275. package/deploy/constants.env +0 -21
  276. package/deploy/deploy.bash +0 -157
  277. package/deploy/deployment-alt-region.cfn.yml +0 -70
  278. package/deploy/deployment.cfn.yml +0 -650
  279. package/deploy/destroy-deployment.bash +0 -23
  280. package/deploy/shared.cfn.yml +0 -94
  281. package/docs/lambda-build.md +0 -35
  282. package/packages/frontend/README.md +0 -46
  283. package/packages/frontend/package.json +0 -101
  284. package/packages/frontend/public/favicon.ico +0 -0
  285. package/packages/frontend/public/index.html +0 -107
  286. package/packages/frontend/public/maintenance.html +0 -59
  287. package/packages/frontend/public/manifest.json +0 -15
  288. package/packages/frontend/public/robots.txt +0 -3
  289. package/packages/frontend/script/make-certificate.bash +0 -49
  290. package/packages/frontend/script/server/cli.js +0 -11
  291. package/packages/frontend/script/server/index.js +0 -47
  292. package/packages/frontend/script/start.bash +0 -22
  293. package/packages/frontend/script/trust-localhost.bash +0 -7
  294. package/packages/frontend/src/auth/authProvider.ts +0 -10
  295. package/packages/frontend/src/auth/useAuth.ts +0 -33
  296. package/packages/frontend/src/components/Pagination.tsx +0 -26
  297. package/packages/frontend/src/configProvider/index.ts +0 -53
  298. package/packages/frontend/src/configProvider/use.ts +0 -41
  299. package/packages/frontend/src/core/context/services.spec.tsx +0 -39
  300. package/packages/frontend/src/core/context/services.tsx +0 -16
  301. package/packages/frontend/src/core/index.spec.ts +0 -7
  302. package/packages/frontend/src/core/index.ts +0 -20
  303. package/packages/frontend/src/core/services.tsx +0 -14
  304. package/packages/frontend/src/core/types.ts +0 -3
  305. package/packages/frontend/src/example/api.ts +0 -28
  306. package/packages/frontend/src/example/components/Layout.tsx +0 -23
  307. package/packages/frontend/src/example/screens/Home.spec.tsx +0 -68
  308. package/packages/frontend/src/example/screens/Home.tsx +0 -78
  309. package/packages/frontend/src/example/screens/ThingList.spec.tsx +0 -60
  310. package/packages/frontend/src/example/screens/ThingList.tsx +0 -75
  311. package/packages/frontend/src/example/screens/ThingView.spec.tsx +0 -71
  312. package/packages/frontend/src/example/screens/ThingView.tsx +0 -47
  313. package/packages/frontend/src/example/screens/index.ts +0 -9
  314. package/packages/frontend/src/index.css +0 -159
  315. package/packages/frontend/src/index.tsx +0 -67
  316. package/packages/frontend/src/react-app-env.d.ts +0 -1
  317. package/packages/frontend/src/routing/components/RouteLink.spec.tsx +0 -55
  318. package/packages/frontend/src/routing/components/RouteLink.tsx +0 -35
  319. package/packages/frontend/src/routing/middleware.ts +0 -6
  320. package/packages/frontend/src/routing/useQuery.ts +0 -14
  321. package/packages/frontend/src/setupProxy.js +0 -19
  322. package/packages/frontend/src/setupTests.ts +0 -9
  323. package/packages/frontend/src/tests/testServices.tsx +0 -23
  324. package/packages/frontend/tsconfig.json +0 -27
  325. package/packages/lambda/.eslintrc.js +0 -64
  326. package/packages/lambda/jest-global-setup.js +0 -3
  327. package/packages/lambda/jest-setup-after-env.js +0 -1
  328. package/packages/lambda/jest.config.js +0 -31
  329. package/packages/lambda/jest.resolver.js +0 -17
  330. package/packages/lambda/package.json +0 -68
  331. package/packages/lambda/script/build.bash +0 -19
  332. package/packages/lambda/script/bundle-functions.bash +0 -10
  333. package/packages/lambda/script/lambdaLocalProxy.js +0 -16
  334. package/packages/lambda/script/lambdaLocalProxy.spec.ts +0 -147
  335. package/packages/lambda/script/utils/getRouteData.ts +0 -7
  336. package/packages/lambda/script/utils/routeDataLoader.js +0 -8
  337. package/packages/lambda/script/utils/routeDataLoader.spec.ts +0 -8
  338. package/packages/lambda/src/functions/serviceApi/core/index.ts +0 -7
  339. package/packages/lambda/src/functions/serviceApi/core/request.spec.ts +0 -38
  340. package/packages/lambda/src/functions/serviceApi/core/request.ts +0 -42
  341. package/packages/lambda/src/functions/serviceApi/core/routes.spec.ts +0 -7
  342. package/packages/lambda/src/functions/serviceApi/core/routes.ts +0 -10
  343. package/packages/lambda/src/functions/serviceApi/core/services.ts +0 -9
  344. package/packages/lambda/src/functions/serviceApi/core/types.ts +0 -13
  345. package/packages/lambda/src/functions/serviceApi/entry/lambda/https-xray.ts +0 -4
  346. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.spec.ts +0 -48
  347. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.ts +0 -58
  348. package/packages/lambda/src/functions/serviceApi/entry/lambda/services.ts +0 -36
  349. package/packages/lambda/src/functions/serviceApi/entry/local.ts +0 -71
  350. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.spec.ts +0 -16
  351. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.ts +0 -41
  352. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.spec.ts +0 -78
  353. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.ts +0 -70
  354. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.spec.ts +0 -306
  355. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.ts +0 -176
  356. package/packages/lambda/src/functions/serviceApi/versions/v0/index.spec.ts +0 -263
  357. package/packages/lambda/src/functions/serviceApi/versions/v0/index.ts +0 -134
  358. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.spec.ts +0 -23
  359. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.ts +0 -32
  360. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.spec.ts +0 -10
  361. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.ts +0 -7
  362. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.spec.ts +0 -13
  363. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.ts +0 -23
  364. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.spec.ts +0 -9
  365. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.ts +0 -9
  366. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.spec.ts +0 -12
  367. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.ts +0 -21
  368. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.spec.ts +0 -21
  369. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.ts +0 -18
  370. package/packages/lambda/tsconfig.json +0 -30
  371. package/packages/lambda/webpack.config.js +0 -97
  372. package/packages/utils/.eslintrc.js +0 -64
  373. package/packages/utils/README.md +0 -118
  374. package/packages/utils/jest-global-setup.js +0 -3
  375. package/packages/utils/jest.config.js +0 -25
  376. package/packages/utils/jest.resolver.js +0 -17
  377. package/packages/utils/package.json +0 -238
  378. package/packages/utils/src/assertions/index.spec.ts +0 -126
  379. package/packages/utils/src/aws/ssmService.ts +0 -7
  380. package/packages/utils/src/config/awsParameterConfig.ts +0 -24
  381. package/packages/utils/src/config/envConfig.ts +0 -58
  382. package/packages/utils/src/config/index.spec.ts +0 -165
  383. package/packages/utils/src/config/lambdaParameterConfig.ts +0 -49
  384. package/packages/utils/src/config/resolveConfigValue.ts +0 -10
  385. package/packages/utils/src/errors/index.spec.ts +0 -35
  386. package/packages/utils/src/fetch/fetchStatusRetry.spec.ts +0 -197
  387. package/packages/utils/src/fetch/fetchStatusRetry.ts +0 -33
  388. package/packages/utils/src/fetch/index.spec.ts +0 -34
  389. package/packages/utils/src/fetch/index.ts +0 -87
  390. package/packages/utils/src/guards/index.spec.ts +0 -58
  391. package/packages/utils/src/index.spec.ts +0 -471
  392. package/packages/utils/src/middleware/apiErrorHandler.spec.ts +0 -65
  393. package/packages/utils/src/middleware/apiErrorHandler.ts +0 -67
  394. package/packages/utils/src/middleware/apiSlowResponseMiddleware.spec.ts +0 -184
  395. package/packages/utils/src/middleware/apiSlowResponseMiddleware.ts +0 -71
  396. package/packages/utils/src/middleware/index.spec.ts +0 -99
  397. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.spec.ts +0 -103
  398. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.ts +0 -52
  399. package/packages/utils/src/middleware/throwNotFoundMiddleware.spec.ts +0 -20
  400. package/packages/utils/src/middleware/throwNotFoundMiddleware.ts +0 -11
  401. package/packages/utils/src/misc/hashValue.ts +0 -18
  402. package/packages/utils/src/misc/helpers.ts +0 -259
  403. package/packages/utils/src/misc/merge.ts +0 -48
  404. package/packages/utils/src/pagination/index.spec.ts +0 -150
  405. package/packages/utils/src/pagination/index.ts +0 -117
  406. package/packages/utils/src/routing/index.spec.ts +0 -553
  407. package/packages/utils/src/routing/index.ts +0 -424
  408. package/packages/utils/src/routing/validators/zod.spec.ts +0 -16
  409. package/packages/utils/src/routing/validators/zod.ts +0 -14
  410. package/packages/utils/src/services/accountsGateway/README.md +0 -3
  411. package/packages/utils/src/services/accountsGateway/index.spec.ts +0 -518
  412. package/packages/utils/src/services/accountsGateway/index.ts +0 -251
  413. package/packages/utils/src/services/apiGateway/README.md +0 -93
  414. package/packages/utils/src/services/apiGateway/index.spec.ts +0 -254
  415. package/packages/utils/src/services/apiGateway/index.ts +0 -189
  416. package/packages/utils/src/services/authProvider/README.md +0 -21
  417. package/packages/utils/src/services/authProvider/browser.spec.ts +0 -391
  418. package/packages/utils/src/services/authProvider/browser.ts +0 -209
  419. package/packages/utils/src/services/authProvider/decryption.spec.ts +0 -337
  420. package/packages/utils/src/services/authProvider/decryption.ts +0 -98
  421. package/packages/utils/src/services/authProvider/index.ts +0 -93
  422. package/packages/utils/src/services/authProvider/stub.spec.ts +0 -29
  423. package/packages/utils/src/services/authProvider/subrequest.spec.ts +0 -105
  424. package/packages/utils/src/services/authProvider/subrequest.ts +0 -68
  425. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.spec.ts +0 -128
  426. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.ts +0 -106
  427. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.spec.ts +0 -26
  428. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.ts +0 -57
  429. package/packages/utils/src/services/authProvider/utils/userRoleValidator.spec.ts +0 -135
  430. package/packages/utils/src/services/authProvider/utils/userRoleValidator.ts +0 -49
  431. package/packages/utils/src/services/authProvider/utils/userSubrequest.spec.ts +0 -26
  432. package/packages/utils/src/services/authProvider/utils/userSubrequest.ts +0 -10
  433. package/packages/utils/src/services/documentStore/dynamoEncoding.ts +0 -57
  434. package/packages/utils/src/services/documentStore/fileSystemAssert.spec.ts +0 -43
  435. package/packages/utils/src/services/documentStore/fileSystemAssert.ts +0 -10
  436. package/packages/utils/src/services/documentStore/unversioned/README.md +0 -13
  437. package/packages/utils/src/services/documentStore/unversioned/dynamodb.spec.ts +0 -859
  438. package/packages/utils/src/services/documentStore/unversioned/dynamodb.ts +0 -243
  439. package/packages/utils/src/services/documentStore/unversioned/file-system.spec.ts +0 -629
  440. package/packages/utils/src/services/documentStore/unversioned/file-system.ts +0 -194
  441. package/packages/utils/src/services/documentStore/versioned/README.md +0 -13
  442. package/packages/utils/src/services/documentStore/versioned/dynamodb.spec.ts +0 -376
  443. package/packages/utils/src/services/documentStore/versioned/dynamodb.ts +0 -167
  444. package/packages/utils/src/services/documentStore/versioned/file-system.spec.ts +0 -262
  445. package/packages/utils/src/services/documentStore/versioned/file-system.ts +0 -90
  446. package/packages/utils/src/services/documentStore/versioned/index.ts +0 -25
  447. package/packages/utils/src/services/exercisesGateway/README.md +0 -5
  448. package/packages/utils/src/services/exercisesGateway/index.spec.ts +0 -326
  449. package/packages/utils/src/services/exercisesGateway/index.ts +0 -163
  450. package/packages/utils/src/services/fileServer/index.spec.ts +0 -88
  451. package/packages/utils/src/services/fileServer/index.ts +0 -43
  452. package/packages/utils/src/services/fileServer/localFileServer.spec.ts +0 -182
  453. package/packages/utils/src/services/fileServer/localFileServer.ts +0 -159
  454. package/packages/utils/src/services/fileServer/s3FileServer.spec.ts +0 -266
  455. package/packages/utils/src/services/fileServer/s3FileServer.ts +0 -155
  456. package/packages/utils/src/services/launchParams/index.spec.ts +0 -366
  457. package/packages/utils/src/services/launchParams/signer.ts +0 -73
  458. package/packages/utils/src/services/launchParams/verifier.ts +0 -120
  459. package/packages/utils/src/services/logger/console.spec.ts +0 -29
  460. package/packages/utils/src/services/logger/index.spec.ts +0 -65
  461. package/packages/utils/src/services/lrsGateway/README.md +0 -5
  462. package/packages/utils/src/services/lrsGateway/addStatementDefaultFields.ts +0 -22
  463. package/packages/utils/src/services/lrsGateway/attempt-utils.spec.ts +0 -847
  464. package/packages/utils/src/services/lrsGateway/attempt-utils.ts +0 -358
  465. package/packages/utils/src/services/lrsGateway/file-system.spec.ts +0 -363
  466. package/packages/utils/src/services/lrsGateway/file-system.ts +0 -165
  467. package/packages/utils/src/services/lrsGateway/index.spec.ts +0 -194
  468. package/packages/utils/src/services/lrsGateway/index.ts +0 -257
  469. package/packages/utils/src/services/lrsGateway/xapiUtils.spec.ts +0 -887
  470. package/packages/utils/src/services/lrsGateway/xapiUtils.ts +0 -262
  471. package/packages/utils/src/services/postgresConnection/index.spec.ts +0 -170
  472. package/packages/utils/src/services/postgresConnection/index.ts +0 -84
  473. package/packages/utils/src/services/searchProvider/README.md +0 -3
  474. package/packages/utils/src/services/searchProvider/index.ts +0 -59
  475. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.spec.ts +0 -526
  476. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.ts +0 -223
  477. package/packages/utils/src/services/searchProvider/openSearch.spec.ts +0 -926
  478. package/packages/utils/src/services/searchProvider/openSearch.ts +0 -195
  479. package/packages/utils/tsconfig.json +0 -31
  480. package/packages/utils/tsconfig.without-specs.cjs.json +0 -7
  481. package/packages/utils/tsconfig.without-specs.esm.json +0 -7
  482. package/packages/utils/tsconfig.without-specs.json +0 -6
  483. package/scripts/build.bash +0 -24
  484. package/scripts/ci.bash +0 -10
  485. package/scripts/start.bash +0 -29
  486. /package/{packages/utils/src/index.ts → dist/cjs/index.d.ts} +0 -0
  487. /package/{packages/utils/src/services/launchParams/index.ts → dist/cjs/services/launchParams/index.d.ts} +0 -0
  488. /package/{packages/utils/script → script}/bin/copy-from-template.bash +0 -0
  489. /package/{packages/utils/script → script}/bin/delete-stack.bash +0 -0
  490. /package/{packages/utils/script → script}/bin/deploy.bash +0 -0
  491. /package/{packages/utils/script → script}/bin/destroy-deployment.bash +0 -0
  492. /package/{packages/utils/script → script}/bin/empty-bucket.bash +0 -0
  493. /package/{packages/utils/script → script}/bin/get-arg.bash +0 -0
  494. /package/{packages/utils/script → script}/bin/get-deployed-environments.bash +0 -0
  495. /package/{packages/utils/script → script}/bin/get-env-param.bash +0 -0
  496. /package/{packages/utils/script → script}/bin/get-kwarg.bash +0 -0
  497. /package/{packages/utils/script → script}/bin/get-stack-param.bash +0 -0
  498. /package/{packages/utils/script → script}/bin/has-flag.bash +0 -0
  499. /package/{packages/utils/script → script}/bin/init-constants-script.bash +0 -0
  500. /package/{packages/utils/script → script}/bin/init-params-script.bash +0 -0
  501. /package/{packages/utils/script → script}/bin/stack-exists.bash +0 -0
  502. /package/{packages/utils/script → script}/bin/update-utils.bash +0 -0
  503. /package/{packages/utils/script → script}/bin/upload-pager-duty-endpoints.bash +0 -0
  504. /package/{packages/utils/script → script}/bin/upload-params.bash +0 -0
  505. /package/{packages/utils/script → script}/bin/which.bash +0 -0
  506. /package/{packages/utils/script → script}/bin-entry.bash +0 -0
  507. /package/{packages/utils/script → script}/build.bash +0 -0
@@ -1,65 +0,0 @@
1
- import { ForbiddenError, InvalidRequestError, NotFoundError, SessionExpiredError, UnauthorizedError, ValidationError } from '../errors';
2
- import { createCoreLogger, Logger } from '../services/logger';
3
- import { createErrorHandler } from './apiErrorHandler';
4
-
5
- describe('errorHandler', () => {
6
- let logSpy: jest.SpyInstance;
7
- let logger: Logger;
8
-
9
- beforeEach(() => {
10
- logSpy = jest.fn();
11
- logger = createCoreLogger(logSpy as any);
12
- });
13
-
14
- afterEach(() => {
15
- jest.clearAllMocks();
16
- });
17
-
18
- it('handles InvalidRequestError with 400', async () => {
19
- expect(await createErrorHandler()(new InvalidRequestError(), logger)).toEqual(expect.objectContaining({statusCode: 400}));
20
- });
21
-
22
- it('handles UnauthorizedError with 401', async() => {
23
- expect(await createErrorHandler()(new UnauthorizedError(), logger)).toEqual(expect.objectContaining({statusCode: 401}));
24
- });
25
-
26
- it('handles ForbiddenError with 403', async() => {
27
- expect(await createErrorHandler()(new ForbiddenError(), logger)).toEqual(expect.objectContaining({statusCode: 403}));
28
- });
29
-
30
- it('handles NotFoundError with 404', async () => {
31
- expect(await createErrorHandler()(new NotFoundError(), logger)).toEqual(expect.objectContaining({statusCode: 404}));
32
- });
33
-
34
- it('handles ValidationError with 422', async () => {
35
- const error = new ValidationError({field: 'value'});
36
- expect(await createErrorHandler()(error, logger)).toMatchInlineSnapshot(`
37
- {
38
- "body": "{"field":"value"}",
39
- "data": {
40
- "field": "value",
41
- },
42
- "headers": {
43
- "content-type": "application/json",
44
- },
45
- "statusCode": 422,
46
- }
47
- `);
48
- });
49
-
50
- it('handles SessionExpired error with 440', async() => {
51
- expect(await createErrorHandler()(new SessionExpiredError(), logger)).toEqual(expect.objectContaining(({
52
- statusCode: 440,
53
- body: '440 SessionExpiredError'
54
- })));
55
- });
56
-
57
- it('handles unknown error with 500', async() => {
58
- expect(await createErrorHandler()(new Error(), logger)).toEqual(expect.objectContaining({statusCode: 500}));
59
- });
60
-
61
- it('logs unknown error', async () => {
62
- await createErrorHandler()(new Error(), logger);
63
- expect(logSpy).toHaveBeenCalled();
64
- });
65
- });
@@ -1,67 +0,0 @@
1
- import {
2
- ForbiddenError,
3
- InvalidRequestError,
4
- isAppError,
5
- NotFoundError,
6
- SessionExpiredError,
7
- UnauthorizedError,
8
- ValidationError,
9
- } from '../errors';
10
- import type { ApiResponse } from '../routing';
11
- import { apiJsonResponse, apiTextResponse } from '../routing';
12
- import type { Logger } from '../services/logger';
13
- import { Level } from '../services/logger';
14
-
15
- export type DefaultErrors = {
16
- InvalidRequestError: InvalidRequestError;
17
- UnauthorizedError: UnauthorizedError;
18
- ForbiddenError: ForbiddenError;
19
- NotFoundError: NotFoundError;
20
- ValidationError: ValidationError;
21
- SessionExpiredError: SessionExpiredError;
22
- };
23
-
24
- export type Handlers<E> = {
25
- [T in keyof E]?: (e: E[T], logger: Logger) => ApiResponse<number, any>;
26
- };
27
-
28
- export const defaultHandlers: Handlers<DefaultErrors> = {
29
- InvalidRequestError: (e) => apiTextResponse(400, `400 ${e.message}`),
30
- UnauthorizedError: (e) => apiTextResponse(401, `401 ${e.message}`),
31
- ForbiddenError: (e) => apiTextResponse(403, `403 ${e.message}`),
32
- NotFoundError: (e) => apiTextResponse(404, `404 ${e.message}`),
33
- ValidationError: (e) => apiJsonResponse(422, e.getData()),
34
- SessionExpiredError: (e) => apiTextResponse(440, `440 ${e.message}`),
35
- };
36
-
37
- /**
38
- * Creates an error handler. Provides default handlers for `UnauthorizedError`,
39
- * `SessionExpiredError`, `NotFoundError`, and `InvalidRequestError`. User-specified
40
- * handlers can be added to these. If no handler is found, the error is logged and
41
- * a 500 text response is returned.
42
- *
43
- * @param inputHandlers a map of errors to handler functions
44
- */
45
- export const createErrorHandler = <Errors = DefaultErrors>(inputHandlers?: Handlers<Errors>) => {
46
- const handlers = {...defaultHandlers, ...inputHandlers};
47
-
48
- return async(e: Error, logger: Logger) => {
49
- const name = isAppError(e) ? e.constructor.TYPE : e.constructor.name;
50
- const handler = handlers[name as keyof typeof handlers];
51
- const logLevel = handler ? Level.Info : Level.Error;
52
-
53
- logger.logEvent(logLevel, {
54
- name: e.name,
55
- message: e.message,
56
- stack: e.stack,
57
- });
58
-
59
- if (handler) {
60
- // convincing typescript that this error is the right kind for the handler
61
- // we looked up based on the errors name is very annoying
62
- return handler(e as any, logger);
63
- }
64
-
65
- return apiTextResponse(500, '500 Error');
66
- };
67
- };
@@ -1,184 +0,0 @@
1
- import { NotFoundError } from '../errors';
2
- import { ApiResponse, apiTextResponse } from '../routing';
3
- import { createCoreLogger, Level, LogEvent, Logger } from '../services/logger';
4
- import { createSlowResponseMiddleware } from './apiSlowResponseMiddleware';
5
-
6
- const insideOutPromise = <T>() => {
7
- let resolve: (value: T | PromiseLike<T>) => void = () => null;
8
- let reject: (reason?: any) => void = () => null;
9
-
10
- const promise = new Promise<T>((res, rej) => {
11
- resolve = res;
12
- reject = rej;
13
- });
14
-
15
- return {resolve, reject, promise};
16
- };
17
-
18
- describe('createSlowResponseMiddleware', () => {
19
- let logger: Logger;
20
- let logFn: jest.SpyInstance;
21
- let timeoutSpy: jest.SpyInstance;
22
- let clearTimeoutSpy: jest.SpyInstance;
23
- let nowSpy: jest.SpyInstance;
24
-
25
- beforeEach(() => {
26
- logFn = jest.fn();
27
- logger = createCoreLogger(logFn as any as LogEvent);
28
- timeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(() => 7 as any);
29
- clearTimeoutSpy = jest.spyOn(global, 'clearTimeout').mockImplementation(() => null);
30
- nowSpy = jest.spyOn(Date, 'now');
31
- });
32
-
33
- afterEach(() => {
34
- timeoutSpy.mockReset();
35
- clearTimeoutSpy.mockReset();
36
- nowSpy.mockReset();
37
- });
38
-
39
- it('does nothing when response is undefined', () => {
40
- expect(createSlowResponseMiddleware({
41
- logResponseSlowerThan: '1000',
42
- timeoutResponseAfter: '5000'
43
- })()(undefined, {logger})).toBeUndefined();
44
- expect(logFn).not.toHaveBeenCalled();
45
- expect(timeoutSpy).not.toHaveBeenCalled();
46
- expect(clearTimeoutSpy).not.toHaveBeenCalled();
47
- });
48
-
49
- it('works without a timeout', () => {
50
- expect(createSlowResponseMiddleware({
51
- logResponseSlowerThan: '1000',
52
- timeoutResponseAfter: ''
53
- })()(undefined, {logger})).toBeUndefined();
54
- expect(logFn).not.toHaveBeenCalled();
55
- expect(timeoutSpy).not.toHaveBeenCalled();
56
- expect(clearTimeoutSpy).not.toHaveBeenCalled();
57
- });
58
-
59
- it('returns response with no timeout', async() => {
60
- const {resolve, promise} = insideOutPromise<ApiResponse<number, string>>();
61
-
62
- const result = createSlowResponseMiddleware({
63
- logResponseSlowerThan: '1000',
64
- timeoutResponseAfter: ''
65
- })()(promise, {logger});
66
-
67
- const response = apiTextResponse(200, 'done');
68
- resolve(response);
69
-
70
- expect(await result).toBe(response);
71
- expect(logFn).not.toHaveBeenCalled();
72
- expect(timeoutSpy).not.toHaveBeenCalled();
73
- expect(clearTimeoutSpy).not.toHaveBeenCalled();
74
- });
75
-
76
- it('logs slow response with no timeout', async() => {
77
- const {resolve, promise} = insideOutPromise<ApiResponse<number, string>>();
78
- nowSpy.mockReturnValue(10000);
79
-
80
- const result = createSlowResponseMiddleware({
81
- logResponseSlowerThan: '1000',
82
- timeoutResponseAfter: ''
83
- })()(promise, {logger});
84
-
85
- nowSpy.mockReturnValue(12000);
86
- const response = apiTextResponse(200, 'done');
87
- resolve(response);
88
-
89
- expect(await result).toBe(response);
90
- expect(logFn).toHaveBeenCalledWith(Level.Warn, {context: {}, message: 'slow response', time: 2000});
91
- expect(timeoutSpy).not.toHaveBeenCalled();
92
- expect(clearTimeoutSpy).not.toHaveBeenCalled();
93
- });
94
-
95
- it('logs slow response with timeout', async() => {
96
- const {resolve, promise} = insideOutPromise<ApiResponse<number, string>>();
97
- nowSpy.mockReturnValue(10000);
98
- timeoutSpy.mockReturnValue(10);
99
-
100
- const result = createSlowResponseMiddleware({
101
- logResponseSlowerThan: '1000',
102
- timeoutResponseAfter: '5000'
103
- })()(promise, {logger});
104
-
105
- nowSpy.mockReturnValue(12000);
106
- const response = apiTextResponse(200, 'done');
107
- resolve(response);
108
-
109
- expect(await result).toBe(response);
110
- expect(logFn).toHaveBeenCalledWith(Level.Warn, {context: {}, message: 'slow response', time: 2000});
111
- expect(timeoutSpy).toHaveBeenCalledTimes(1);
112
- expect(timeoutSpy).toHaveBeenCalledWith(expect.anything(), 5000);
113
- expect(clearTimeoutSpy).toHaveBeenCalledTimes(1);
114
- expect(clearTimeoutSpy).toHaveBeenCalledWith(10);
115
- });
116
-
117
- it('returns timeout', async() => {
118
- const {promise} = insideOutPromise<ApiResponse<number, string>>();
119
-
120
- const result = createSlowResponseMiddleware({
121
- logResponseSlowerThan: '1000',
122
- timeoutResponseAfter: '5000'
123
- })()(promise, {logger});
124
-
125
-
126
- // clear config loading
127
- await new Promise(setImmediate);
128
-
129
- expect(timeoutSpy).toHaveBeenCalledTimes(1);
130
- expect(timeoutSpy).toHaveBeenCalledWith(expect.anything(), 5000);
131
-
132
- expect(clearTimeoutSpy).not.toHaveBeenCalled();
133
- timeoutSpy.mock.calls[0][0]();
134
-
135
- expect(await result).toEqual(apiTextResponse(504, '504 Gateway Timeout'));
136
- expect(logFn).toHaveBeenCalledWith(Level.Error, {context: {}, message: 'request processing timed out'});
137
- });
138
-
139
- it('does not log a timeout when the response promise resolves in time', async() => {
140
- const {resolve, promise} = insideOutPromise<ApiResponse<number, string>>();
141
-
142
- const result = createSlowResponseMiddleware({
143
- logResponseSlowerThan: '1000',
144
- timeoutResponseAfter: '5000'
145
- })()(promise, {logger});
146
-
147
- // clear config loading
148
- await new Promise(setImmediate);
149
-
150
- const response = apiTextResponse(200, 'done');
151
- resolve(response);
152
-
153
- expect(timeoutSpy).toHaveBeenCalledTimes(1);
154
- expect(timeoutSpy).toHaveBeenCalledWith(expect.anything(), 5000);
155
-
156
- expect(await result).toEqual(response);
157
-
158
- expect(clearTimeoutSpy).toHaveBeenCalledWith(7);
159
- expect(logFn).not.toHaveBeenCalled();
160
- });
161
-
162
- it('does not log a timeout when the response promise rejects in time', async() => {
163
- const {reject, promise} = insideOutPromise<ApiResponse<number, string>>();
164
-
165
- const result = createSlowResponseMiddleware({
166
- logResponseSlowerThan: '1000',
167
- timeoutResponseAfter: '5000'
168
- })()(promise, {logger});
169
-
170
- // clear config loading
171
- await new Promise(setImmediate);
172
-
173
- const error = new NotFoundError();
174
- reject(error);
175
-
176
- expect(timeoutSpy).toHaveBeenCalledTimes(1);
177
- expect(timeoutSpy).toHaveBeenCalledWith(expect.anything(), 5000);
178
-
179
- await expect(result).rejects.toThrow(error);
180
-
181
- expect(clearTimeoutSpy).toHaveBeenCalledWith(7);
182
- expect(logFn).not.toHaveBeenCalled();
183
- });
184
- });
@@ -1,71 +0,0 @@
1
- import type { ConfigProviderForConfig } from '../config';
2
- import { resolveConfigValue } from '../config/resolveConfigValue';
3
- import { once } from '../misc/helpers';
4
- import type { ApiResponse } from '../routing';
5
- import { apiTextResponse } from '../routing';
6
- import type { Logger } from '../services/logger';
7
- import { Level } from '../services/logger';
8
-
9
- type Config = {
10
- logResponseSlowerThan: string;
11
- timeoutResponseAfter: string;
12
- };
13
-
14
- /**
15
- * Creates response middleware that logs slow responses and times out responses that take too long. lambda functions have a timeout setting, but when a lambda times out there is no way to log anything helpful before it exists. this middleware allows the logger context to show up for timeout requests. just make sure that the `timeoutResponseAfter` is set to something slightly shorter than the lambda timeout so that it has time to run.
16
- *
17
- * @param config
18
- * @param config.logResponseSlowerThan the config that specifies the threshold for a slow response
19
- * @param config.timeoutResponseAfter the config that specifies the timeout for a response
20
- * @example
21
- * createSlowResponseMiddleware({
22
- * logResponseSlowerThan: envConfig('LOG_SLOW_RESPONSE', 'runtime', '1000'),
23
- * timeoutResponseAfter: envConfig('RESPONSE_TIMEOUT', 'runtime', '28000'),
24
- * });
25
- */
26
- export const createSlowResponseMiddleware = (config: ConfigProviderForConfig<Config>) => {
27
- const getSlowThreshold = once(() => resolveConfigValue(config.logResponseSlowerThan).then(result => parseInt(result, 10)));
28
- const getTimeoutAfter = once(() => resolveConfigValue(config.timeoutResponseAfter).then(result => parseInt(result, 10)));
29
-
30
- return () => (
31
- response: Promise<ApiResponse<number, any>> | undefined, {logger}: {logger: Logger}
32
- ): Promise<ApiResponse<number, string>> | undefined => {
33
- const start = Date.now();
34
-
35
- if (!response) {
36
- return response;
37
- }
38
-
39
- return Promise.all([getSlowThreshold(), getTimeoutAfter()]).then(([slowThreshold, timeoutAfter]) => {
40
-
41
- let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
42
-
43
- const timeoutPromise = isNaN(timeoutAfter)
44
- ? undefined
45
- : new Promise<ApiResponse<number, string>>(resolve => timeout = setTimeout(() => {
46
- logger.logEvent(Level.Error, {
47
- message: 'request processing timed out',
48
- });
49
- resolve(apiTextResponse(504, '504 Gateway Timeout'));
50
- }, timeoutAfter))
51
- ;
52
-
53
- const requestPromise = response.finally(() => {
54
- const time = Date.now() - start;
55
-
56
- if (timeout !== undefined) {
57
- clearTimeout(timeout);
58
- }
59
-
60
- if (time > slowThreshold) {
61
- logger.logEvent(Level.Warn, {
62
- message: 'slow response',
63
- time,
64
- });
65
- }
66
- });
67
-
68
- return timeoutPromise ? Promise.race([timeoutPromise, requestPromise]) : requestPromise;
69
- });
70
- };
71
- };
@@ -1,99 +0,0 @@
1
- import { makeComposeMiddleware } from '.';
2
-
3
- describe('composeMiddleware', () => {
4
- it('composes middleware', () => {
5
- const provider1 = () => <M extends {thing1: string}>(middleware: M) => ({...middleware, thing2: `${middleware.thing1}-copy`});
6
- const provider2 = () => <M extends {thing2: string}>({thing2, ...middleware}: M) => ({...middleware, thing2: thing2.length, thing3: `${thing2}-copy`});
7
-
8
- const composeMiddleware = makeComposeMiddleware<{}, {thing1: string; thing7: string}>();
9
-
10
- const middleware = composeMiddleware(
11
- provider1,
12
- provider2
13
- );
14
-
15
- const result = middleware({})({thing1: 'first', thing7: 'seven'});
16
-
17
- // just trying to make TS complain if these are the wrong type or result is never
18
- result.thing1.length;
19
- result.thing2.toFixed;
20
- result.thing3.length;
21
- result.thing7.length;
22
-
23
- expect(result).toEqual({
24
- thing1: 'first',
25
- thing2: 10,
26
- thing3: 'first-copy-copy',
27
- thing7: 'seven',
28
- });
29
- });
30
-
31
- it('composes middleware arguments', () => {
32
- const provider1 = () => <M extends {thing1: string}>(middleware: M, argument: string) => ({...middleware, thing2: `${middleware.thing1}-${argument}`});
33
- const provider2 = () => <M extends {thing2: string}>(middleware: M) => ({...middleware, thing3: `${middleware.thing2}-copy`});
34
-
35
- const composeMiddleware = makeComposeMiddleware<{}, {thing1: string; thing7: string}>();
36
-
37
- const middleware = composeMiddleware(
38
- provider1,
39
- provider2
40
- );
41
-
42
- const result = middleware({})({thing1: 'first', thing7: 'seven'}, 'extra value');
43
-
44
- // just trying to make TS complain if these are the wrong type or result is never
45
- result.thing1.length;
46
- result.thing2.length;
47
- result.thing3.length;
48
- result.thing7.length;
49
-
50
-
51
- expect(result).toEqual({
52
- thing1: 'first',
53
- thing2: 'first-extra value',
54
- thing3: 'first-extra value-copy',
55
- thing7: 'seven',
56
- });
57
- });
58
-
59
- it('transforms optional data', () => {
60
- const provider1 = () => (middleware: {thing: string} | undefined) => middleware || {thing: 'default'};
61
- const provider2 = () => (middleware: {thing: string}) => middleware;
62
-
63
- const composeMiddleware = makeComposeMiddleware<{}, {thing: string} | undefined>();
64
-
65
- const middleware = composeMiddleware(
66
- provider1,
67
- provider2,
68
- );
69
-
70
- // just trying to make TS complain if these are the wrong type or result is never
71
- middleware({})(undefined).thing.length;
72
- middleware({})({thing: 'first'}).thing.length;
73
-
74
- expect(middleware({})(undefined).thing).toBe('default');
75
- expect(middleware({})({thing: 'first'}).thing).toBe('first');
76
- });
77
-
78
- it('transforms non-hash data', () => {
79
- const default0 = () => (middleware: number | undefined) => middleware || 0;
80
- const add2 = () => (middleware: number) => middleware + 2;
81
- const doubleIt = () => (middleware: number) => middleware * 2;
82
-
83
- const composeMiddleware = makeComposeMiddleware<{}, number | undefined>();
84
-
85
- const middleware = composeMiddleware(
86
- default0,
87
- add2,
88
- doubleIt,
89
- add2
90
- );
91
-
92
- // just trying to make TS complain if these are the wrong type or result is never
93
- middleware({})(undefined).toFixed;
94
- middleware({})(2).toFixed;
95
-
96
- expect(middleware({})(undefined)).toBe(6);
97
- expect(middleware({})(2)).toBe(10);
98
- });
99
- });
@@ -1,103 +0,0 @@
1
- import { APIGatewayProxyEventV2 } from 'aws-lambda';
2
- import { apiJsonResponse } from '../routing';
3
- import { createLambdaCorsResponseMiddleware } from './lambdaCorsResponseMiddleware';
4
-
5
- describe('createLambdaCorsResponseMiddleware', () => {
6
- it('adds cors headers for openstax subdomains', async() => {
7
- const request = {
8
- cookies: [],
9
- headers: {
10
- origin: 'https://neato.openstax.org'
11
- },
12
- requestContext: {
13
- http: {
14
- method: 'GET'
15
- }
16
- }
17
- } as unknown as APIGatewayProxyEventV2;
18
-
19
- const response = await createLambdaCorsResponseMiddleware({corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'})()(
20
- Promise.resolve(apiJsonResponse(200, {})), {request}
21
- );
22
-
23
- expect(response?.headers?.['Access-Control-Allow-Origin']).toBe('https://neato.openstax.org');
24
- expect(response?.headers?.['Access-Control-Allow-Methods']).toBe('POST, GET, PUT, PATCH, DELETE, OPTIONS');
25
- });
26
-
27
- it('adds cors headers for openstax apex', async() => {
28
- const request = {
29
- cookies: [],
30
- headers: {
31
- origin: 'https://openstax.org'
32
- },
33
- requestContext: {
34
- http: {
35
- method: 'GET'
36
- }
37
- }
38
- } as unknown as APIGatewayProxyEventV2;
39
-
40
- const response = await createLambdaCorsResponseMiddleware({corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'})()(
41
- Promise.resolve(apiJsonResponse(200, {})), {request}
42
- );
43
-
44
- expect(response?.headers?.['Access-Control-Allow-Origin']).toBe('https://openstax.org');
45
- expect(response?.headers?.['Access-Control-Allow-Methods']).toBe('POST, GET, PUT, PATCH, DELETE, OPTIONS');
46
- });
47
-
48
- it('omits headers without origin', async() => {
49
- const request = {
50
- cookies: [],
51
- headers: {
52
- },
53
- requestContext: {
54
- http: {
55
- method: 'GET'
56
- }
57
- }
58
- } as unknown as APIGatewayProxyEventV2;
59
-
60
- const response = await createLambdaCorsResponseMiddleware({corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'})()(
61
- Promise.resolve(apiJsonResponse(200, {})), {request}
62
- );
63
-
64
- expect(response?.headers?.['Access-Control-Allow-Origin']).toBeUndefined();
65
- expect(response?.headers?.['Access-Control-Allow-Methods']).toBeUndefined();
66
- });
67
-
68
- it('forwards undefined response if its not options', async() => {
69
- const request = {
70
- cookies: [],
71
- headers: {
72
- },
73
- requestContext: {
74
- http: {
75
- method: 'GET'
76
- }
77
- }
78
- } as unknown as APIGatewayProxyEventV2;
79
-
80
- const response = await createLambdaCorsResponseMiddleware({corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'})()(undefined, {request});
81
-
82
- expect(response).toBeUndefined();
83
- });
84
-
85
- it('responds to options', async() => {
86
- const request = {
87
- cookies: [],
88
- headers: {
89
- origin: 'https://openstax.org'
90
- },
91
- requestContext: {
92
- http: {
93
- method: 'OPTIONS'
94
- }
95
- }
96
- } as unknown as APIGatewayProxyEventV2;
97
-
98
- const response = await createLambdaCorsResponseMiddleware({corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'})()(undefined, {request});
99
-
100
- expect(response?.headers?.['Access-Control-Allow-Origin']).toBe('https://openstax.org');
101
- expect(response?.headers?.['Access-Control-Allow-Methods']).toBe('POST, GET, PUT, PATCH, DELETE, OPTIONS');
102
- });
103
- });
@@ -1,52 +0,0 @@
1
- import { APIGatewayProxyEventV2 } from 'aws-lambda';
2
- import { ConfigProviderForConfig } from '../config';
3
- import { resolveConfigValue } from '../config/resolveConfigValue';
4
- import { once } from '../misc/helpers';
5
- import { ApiResponse, apiTextResponse } from '../routing';
6
-
7
- type Config = {
8
- corsAllowedHostRegex: string;
9
- };
10
-
11
- /**
12
- * Creates response middleware that adds CORS headers to responses from approved hosts.
13
- *
14
- * @param config the config object
15
- * @param config.corsAllowedHostRegex the config that specifies the regex for allowed hosts
16
- * @example
17
- * createLambdaCorsResponseMiddleware({
18
- * corsAllowedHostRegex: '(openstax.org|herokuapp.com)$'
19
- * }),
20
- */
21
- export const createLambdaCorsResponseMiddleware = (config: ConfigProviderForConfig<Config>) => () => (responsePromise: Promise<ApiResponse<number, any>> | undefined, {request}: {request: APIGatewayProxyEventV2}): Promise<ApiResponse<number, any>> | undefined => {
22
- const getAllowedHostRegex = once(() => resolveConfigValue(config.corsAllowedHostRegex));
23
-
24
- const cors = async () => {
25
- const allowedHost = await getAllowedHostRegex();
26
-
27
- if (request.headers.origin && request.headers.origin !== 'null' && new URL(request.headers.origin).hostname.match(new RegExp(allowedHost))) {
28
- return {
29
- 'Access-Control-Allow-Origin': request.headers.origin,
30
- 'Access-Control-Allow-Credentials': 'true',
31
- 'Access-Control-Allow-Headers': 'content-type, x-request-id',
32
- 'Access-Control-Allow-Methods': 'POST, GET, PUT, PATCH, DELETE, OPTIONS',
33
- };
34
- }
35
- };
36
-
37
- if (responsePromise) {
38
- return responsePromise.then(async response => {
39
- response.headers = {
40
- ...await cors(),
41
- ...response.headers
42
- };
43
- return response;
44
- });
45
- }
46
-
47
- if (request.requestContext.http.method === 'OPTIONS') {
48
- return cors().then(headers => apiTextResponse(200, '', headers));
49
- }
50
-
51
- return responsePromise;
52
- };
@@ -1,20 +0,0 @@
1
- import { NotFoundError } from '../errors';
2
- import { createThrowNotFoundMiddleware } from './throwNotFoundMiddleware';
3
-
4
-
5
- describe('throwNotFoundMiddleware', () => {
6
- it('defaults to 404', async() => {
7
- const default404MiddlewareNoResponse = () => createThrowNotFoundMiddleware<any>()()(undefined);
8
-
9
- // Normally caught by the default errorHandler
10
- expect(default404MiddlewareNoResponse).toThrow(NotFoundError);
11
- expect(default404MiddlewareNoResponse).toThrow('not found');
12
- });
13
-
14
- it('keeps response', async() => {
15
- const initial = {};
16
- const response = await createThrowNotFoundMiddleware<any>()()(Promise.resolve(initial));
17
-
18
- expect(response).toBe(initial);
19
- });
20
- });
@@ -1,11 +0,0 @@
1
- import { NotFoundError } from '../errors';
2
-
3
- /**
4
- * Creates response middleware that throws a `NotFoundError` if the response is undefined.
5
- */
6
- export const createThrowNotFoundMiddleware = <Ro>() => () => (response: Promise<Ro> | undefined): Promise<Ro> => {
7
- if (!response) {
8
- throw new NotFoundError('not found');
9
- }
10
- return response;
11
- };