@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
@@ -0,0 +1,246 @@
1
+ import * as pathToRegexp from 'path-to-regexp';
2
+ import queryString from 'query-string';
3
+ import { mapFind, memoize } from '../misc/helpers';
4
+ import { createConsoleLogger } from '../services/logger/console';
5
+ /** this utility simplifies the route type to remove stuff that is only
6
+ * relevant internal to the route, like the service types, keeping only
7
+ * the payload type which is necessary for the apiGateway
8
+ *
9
+ * this helps avoid the "type too complicated" error that typescript throws
10
+ * when there are a lot of routes with complex services
11
+ **/
12
+ export const routesList = (routes) => routes;
13
+ /**
14
+ * Makes a createRoute function that can be used to create routes (this is a factory factory). The
15
+ * `makeCreateRoute` function is typically called once in the backend and once in the frontend to
16
+ * set the types for the resulting `createRoute` function -- that latter function is called once
17
+ * per route. E.g. for the backend, the call could look like:
18
+ *
19
+ * ```
20
+ * export const createRoute = makeCreateRoute<AppServices, ApiRouteRequest, {
21
+ * method: METHOD;
22
+ * }>();
23
+ * ```
24
+ *
25
+ * Notes:
26
+ * * The `{method: METHOD}` defines the `Ex` extension type; here, the `method` property is only
27
+ * relevant to backend routes.
28
+ * * when defining the `createRoute` method, only the request input format is defined, the output
29
+ * format is derived from the routes.
30
+ *
31
+ * When calling the resulting `createRoute` function, the only required params of the route are the
32
+ * name, path, and handler. Other params can be added to the type and then later used in the
33
+ * routeMatcher.
34
+ *
35
+ * eg when defining requestServiceProvider in line, the types have a hard time, it helps to put in another argument:
36
+ * ```
37
+ * export const exampleRoute = createRoute({
38
+ * name: 'exampleRoute', method: METHOD.GET, path: '/api/example/:key',
39
+ * requestServiceProvider: composeServiceMiddleware({
40
+ * cookieAuthMiddleware,
41
+ * documentStoreMiddleware,
42
+ * }},
43
+ * async(params: {key: string}, services) => {
44
+ * const result = await services.myDocumentStore.getItem(params.key);
45
+ *
46
+ * if (!result) {
47
+ * throw new NotFoundError('requested item not found');
48
+ * }
49
+ *
50
+ * return apiJsonResponse(200, result);
51
+ * }
52
+ * );
53
+ * ```
54
+ * eg when using a pre-existing provider variable the types work better:
55
+ * ```
56
+ * export const exampleRoute = createRoute({
57
+ * name: 'exampleRoute', method: METHOD.GET, path: '/api/example/:key',
58
+ * requestServiceProvider,
59
+ * handler: async(params: {key: string}, services) => {
60
+ * const result = await services.myDocumentStore.getItem(params.key);
61
+ *
62
+ * if (!result) {
63
+ * throw new NotFoundError('requested item not found');
64
+ * }
65
+ *
66
+ * return apiJsonResponse(200, result);
67
+ * }
68
+ * });
69
+ * ```
70
+ */
71
+ export const makeCreateRoute = () => (...args) => {
72
+ return (args.length === 1
73
+ ? args[0]
74
+ : { ...args[0], handler: args[1] });
75
+ };
76
+ /* begin reverse routing utils */
77
+ /**
78
+ * Makes a renderRouteUrl function that can be used to render route paths (this is a factory
79
+ * factory). The returned function takes a `route`, `params`, and `query` and returns a string
80
+ * with the params and query substituted into the route path.
81
+ *
82
+ * this function is initialized using the Ru type which indicates the specific routes wired into
83
+ * the application, which means that if you try to build a url with a route which is not wired
84
+ * into the router you will get a type error. this is a feature to prevent referencing routes that
85
+ * don't exist or aren't handling requests properly.
86
+ *
87
+ * if you are making a helper function or need to render a route outside your application, you
88
+ * can use the `renderAnyRouteUrl` function
89
+ */
90
+ export const makeRenderRouteUrl = () => (route, params, query = {}) => {
91
+ const getPathForParams = pathToRegexp.compile(route.path, { encode: encodeURIComponent });
92
+ const search = queryString.stringify(query);
93
+ const path = getPathForParams(params) + (search ? `?${search}` : '');
94
+ return path;
95
+ };
96
+ /**
97
+ * A pre-made result from `makeRenderRouteUrl`, this function interpolates parameter and query
98
+ * arguments into a route path.
99
+ *
100
+ * prefer using `renderRouteUrl` initialized with your applications route union
101
+ * when possible to help catch improperly initialized routes.
102
+ *
103
+ * @param route the route that has a `path` to be interpolated
104
+ * @param params the parameters to interpolate into the route path
105
+ * @param query the query parameters to add to the route path
106
+ * @returns the interpolated route path
107
+ */
108
+ export const renderAnyRouteUrl = makeRenderRouteUrl();
109
+ const bindRoute = (services, appBinder, pathExtractor, matcher) => (route) => {
110
+ const getParamsFromPath = pathToRegexp.match(route.path, { decode: decodeURIComponent });
111
+ const boundServiceProvider = route.requestServiceProvider && appBinder(services, route.requestServiceProvider);
112
+ return (request, logger) => {
113
+ const path = pathExtractor(request);
114
+ const match = getParamsFromPath(path);
115
+ if ((!matcher || matcher(request, route)) && match) {
116
+ return {
117
+ name: route.name,
118
+ executor: () => route.handler(match.params, boundServiceProvider ? boundServiceProvider({ request, logger }, { route, params: match.params }) : undefined)
119
+ };
120
+ }
121
+ };
122
+ };
123
+ /**
124
+ * A factory factory for creating request responders (functions that take a request and return a
125
+ * response -- these functions let us implement Lambda `handler` functions).
126
+ *
127
+ * Use it in two steps. First, call it with the general business logic that defines routes, logs,
128
+ * errors, etc:
129
+ * ```
130
+ * const getRequestResponder = makeGetRequestResponder<
131
+ * AppServices, TRoutes, ApiRouteRequest, Promise<ApiRouteResponse>
132
+ * >() // this empty invocation helps typescript mix defined and inferred types
133
+ * ({
134
+ * routes: apiRoutes, // the route definitions
135
+ * pathExtractor, // how to get the path out of the request format
136
+ * routeMatcher, // logic for matching route (beyond path matching, optional)
137
+ * errorHandler, // any special error handling
138
+ * });
139
+ * ```
140
+ * Note here that among other things we're specifying a generic response format that the response
141
+ * and error handling middleware can use, if any routes have responses that don't adhere to this
142
+ * it'll complain about it.
143
+ *
144
+ * Next, we use the `getRequestResponder` to create a responder for a specific lambda entrypoint:
145
+ * ```
146
+ * export const handler: (request: APIGatewayProxyEventV2): Promise<ApiRouteResponse> =>
147
+ * getRequestResponder(
148
+ * lambdaServices, // the AppServices for this entrypoint
149
+ * lambdaMiddleware // environment specific response middleware (like cors)
150
+ * );
151
+ * ```
152
+ */
153
+ export const makeGetRequestResponder = () => ({ routes, pathExtractor, routeMatcher, errorHandler, logExtractor }) => (services, responseMiddleware) => {
154
+ const appBinderImpl = (app, middleware) => middleware(app, appBinder);
155
+ const appBinder = memoize(appBinderImpl);
156
+ const boundRoutes = routes().map(bindRoute(services, appBinder, pathExtractor, routeMatcher));
157
+ const boundResponseMiddleware = responseMiddleware ? responseMiddleware(services) : undefined;
158
+ const appLogger = services.logger || createConsoleLogger();
159
+ // *note* this opaque promise guard is less generic than i hoped so
160
+ // i'm leaving it here instead of the guards file.
161
+ //
162
+ // its less than ideal because it enforces that the handlers return
163
+ // the same type as the parent promise, usually a handler can be either a
164
+ // promise or a non-promise value and the promise figures it out, but those
165
+ // types are getting complicated quickly here.
166
+ const isPromise = (thing) => thing instanceof Promise;
167
+ return (request) => {
168
+ const logger = appLogger.createSubContext();
169
+ if (logExtractor) {
170
+ logger.setContext(logExtractor(request));
171
+ }
172
+ logger.log('begin request');
173
+ try {
174
+ const route = mapFind(boundRoutes, (route) => route(request, logger));
175
+ if (route) {
176
+ logger.log(`route matched ${route.name}`);
177
+ const result = boundResponseMiddleware ?
178
+ boundResponseMiddleware(route.executor(), { request, logger }) : route.executor();
179
+ if (isPromise(result) && errorHandler) {
180
+ const errorHandlerWithMiddleware = (e) => boundResponseMiddleware ?
181
+ boundResponseMiddleware(errorHandler(e, logger), { request, logger }) : errorHandler(e, logger);
182
+ return result.catch(errorHandlerWithMiddleware);
183
+ }
184
+ else {
185
+ return result;
186
+ }
187
+ }
188
+ else if (boundResponseMiddleware) {
189
+ logger.log('no route matched, returning 404');
190
+ return boundResponseMiddleware(undefined, { request, logger });
191
+ }
192
+ }
193
+ catch (e) {
194
+ if (errorHandler && e instanceof Error) {
195
+ return boundResponseMiddleware
196
+ ? boundResponseMiddleware(errorHandler(e, logger), { request, logger })
197
+ : errorHandler(e, logger);
198
+ }
199
+ throw e;
200
+ }
201
+ return undefined;
202
+ };
203
+ };
204
+ /**
205
+ * Returns a JSON response. Handles serializing the data to JSON and setting the content-type header.
206
+ * @param statusCode e.g. 201
207
+ * @param data the object to be serialized to JSON
208
+ * @param headers HTTP headers
209
+ * @example
210
+ * return apiJsonResponse(
211
+ * 200, {
212
+ * message: "hello, world!",
213
+ * foo: "bar",
214
+ * },
215
+ * { 'X-Frame-Options': 'DENY' }
216
+ * );
217
+ */
218
+ export const apiJsonResponse = (statusCode, data, headers) => ({ statusCode, data, body: JSON.stringify(data), headers: { ...headers, 'content-type': 'application/json' } });
219
+ /**
220
+ * Returns a plain text response. Handles setting the content-type header.
221
+ * @param statusCode e.g. 201
222
+ * @param data some string
223
+ * @param headers HTTP headers
224
+ * @example return apiTextResponse(200, 'some text')
225
+ */
226
+ export const apiTextResponse = (statusCode, data, headers) => ({ statusCode, data, body: data, headers: { ...headers, 'content-type': 'text/plain' } });
227
+ /**
228
+ * Returns an HTML response. Handles setting the content-type header.
229
+ * @param statusCode e.g. 201
230
+ * @param data some string
231
+ * @param headers HTTP headers
232
+ * @example return apiHtmlResponse(200, '<b>some text</b>')
233
+ */
234
+ export const apiHtmlResponse = (statusCode, data, headers) => ({ statusCode, data, body: data, headers: { ...headers, 'content-type': 'text/html' } });
235
+ /** HTTP method enum */
236
+ export var METHOD;
237
+ (function (METHOD) {
238
+ METHOD["GET"] = "GET";
239
+ METHOD["HEAD"] = "HEAD";
240
+ METHOD["POST"] = "POST";
241
+ METHOD["PUT"] = "PUT";
242
+ METHOD["PATCH"] = "PATCH";
243
+ METHOD["DELETE"] = "DELETE";
244
+ METHOD["OPTIONS"] = "OPTIONS";
245
+ })(METHOD || (METHOD = {}));
246
+ export * from './helpers';
@@ -0,0 +1,4 @@
1
+ import type { z } from 'zod';
2
+ export declare const zodPayloadValidator: <T extends {}>(validator: z.ZodType<T, T>) => (input: {
3
+ [key: string]: any;
4
+ }) => input is T;
@@ -0,0 +1,10 @@
1
+ /* spell-checker: ignore treeify */
2
+ import { treeifyError } from 'zod';
3
+ import { ValidationError } from '../../errors';
4
+ export const zodPayloadValidator = (validator) => (input) => {
5
+ const result = validator.safeParse(input);
6
+ if (result.success) {
7
+ return true;
8
+ }
9
+ throw new ValidationError(treeifyError(result.error));
10
+ };
@@ -0,0 +1,92 @@
1
+ import { ConfigProviderForConfig } from '../../config';
2
+ import { GenericFetch } from '../../fetch';
3
+ import { JsonCompatibleStruct } from '../../routing';
4
+ import { ApiUser, ConsentPreferences } from '../authProvider';
5
+ import { Logger } from '../logger';
6
+ export type Config = {
7
+ accountsBase: string;
8
+ accountsAuthToken: string;
9
+ };
10
+ interface Initializer<C> {
11
+ configSpace?: C;
12
+ fetch: GenericFetch;
13
+ }
14
+ export type FindUserPayload = ({
15
+ external_id: string;
16
+ } | {
17
+ uuid: string;
18
+ }) & {
19
+ sso?: string;
20
+ };
21
+ export type FindOrCreateUserPayload = {
22
+ external_id: string;
23
+ email?: string;
24
+ already_verified?: boolean;
25
+ first_name?: string;
26
+ last_name?: string;
27
+ full_name?: string;
28
+ salesforce_contact_id?: string;
29
+ faculty_status?: string;
30
+ role?: string;
31
+ school_type?: string;
32
+ is_test?: boolean;
33
+ sso?: string;
34
+ };
35
+ export type FindOrCreateUserResponse = {
36
+ id: number;
37
+ uuid: string;
38
+ external_ids: string[];
39
+ is_test: boolean;
40
+ sso: string;
41
+ };
42
+ export type FindUserResponse = (FindOrCreateUserResponse & {
43
+ external_ids: string[];
44
+ }) | undefined;
45
+ export type LinkUserPayload = {
46
+ userId: number;
47
+ externalId: string;
48
+ };
49
+ export type LinkUserResponse = {
50
+ user_id: number;
51
+ external_id: string;
52
+ };
53
+ export type SearchUsersPayload = {
54
+ q: string;
55
+ order_by?: string;
56
+ };
57
+ export type SearchUsersResponse = {
58
+ items: Array<ApiUser & {
59
+ external_ids: string[];
60
+ } & JsonCompatibleStruct>;
61
+ total_count: number;
62
+ };
63
+ export type UpdateUserPayload = ConsentPreferences;
64
+ export type MappedUserInfo<T> = {
65
+ data: T;
66
+ fullName: string;
67
+ platformUserId?: string;
68
+ uuid: string;
69
+ };
70
+ export declare const accountsGateway: <C extends string = "accounts">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => ({ logger }: {
71
+ logger: Logger;
72
+ }) => {
73
+ findOrCreateUser: (body: FindOrCreateUserPayload) => Promise<FindOrCreateUserResponse>;
74
+ findUser: (body: FindUserPayload) => Promise<FindUserResponse>;
75
+ getUser: (token: string) => Promise<ApiUser & JsonCompatibleStruct>;
76
+ linkUser: (body: LinkUserPayload) => Promise<LinkUserResponse>;
77
+ mapUserUuids: <T>(userUuidsMap: {
78
+ [uuid: string]: T;
79
+ }, platformId?: string) => Promise<{
80
+ data: T;
81
+ fullName: string;
82
+ platformUserId: string | undefined;
83
+ uuid: string;
84
+ }[]>;
85
+ searchUsers: (payload: SearchUsersPayload) => Promise<SearchUsersResponse>;
86
+ updateUser: (token: string, body: UpdateUserPayload) => Promise<ApiUser & JsonCompatibleStruct>;
87
+ getUserMap: <R>(userUuids: Set<string>, mapper: ((user: ApiUser) => R)) => Promise<Map<string, R>>;
88
+ mapUserData: <T, R>(input: T[], getUserUuid: (item: T) => string, mapper: ((user: ApiUser | undefined, item: T) => R)) => Promise<R[]>;
89
+ mapUsersData: <T, R_1>(input: T[], getUserUuids: (item: T) => string[], mapper: ((users: Map<string, ApiUser | undefined>, item: T) => R_1)) => Promise<R_1[]>;
90
+ };
91
+ export type AccountsGateway = ReturnType<ReturnType<ReturnType<typeof accountsGateway>>>;
92
+ export {};
@@ -0,0 +1,131 @@
1
+ import { chunk, isEqual } from 'lodash';
2
+ import queryString from 'query-string';
3
+ import { resolveConfigValue } from '../../config';
4
+ import { ifDefined, isDefined } from '../../guards';
5
+ import { once } from '../../misc/helpers';
6
+ import { METHOD } from '../../routing';
7
+ import { Level } from '../logger';
8
+ class ApiError extends Error {
9
+ constructor(message, status) {
10
+ super(message);
11
+ this.status = status;
12
+ }
13
+ }
14
+ export const accountsGateway = (initializer) => (configProvider) => {
15
+ const config = configProvider[ifDefined(initializer.configSpace, 'accounts')];
16
+ const accountsBase = once(() => resolveConfigValue(config.accountsBase));
17
+ const accountsAuthToken = once(() => resolveConfigValue(config.accountsAuthToken));
18
+ return ({ logger }) => {
19
+ const request = async (method, path, options, statuses = [200, 201]) => {
20
+ const host = (await accountsBase()).replace(/\/+$/, '');
21
+ const url = `${host}/api/${path}`;
22
+ const config = {
23
+ headers: {
24
+ Authorization: `Bearer ${options.token || await accountsAuthToken()}`,
25
+ },
26
+ method,
27
+ };
28
+ if (options.body) {
29
+ config.body = JSON.stringify(options.body);
30
+ }
31
+ const response = await initializer.fetch(url, config);
32
+ if (!statuses.includes(response.status)) {
33
+ throw new ApiError(`Received unexpected status code ${response.status} for Accounts API call: ${method} ${url}`, response.status);
34
+ }
35
+ return response.json();
36
+ };
37
+ const findOrCreateUser = async (body) => request(METHOD.POST, 'user/find-or-create', { body });
38
+ const findUser = async (body) => {
39
+ try {
40
+ return await request(METHOD.POST, 'user/find', { body });
41
+ }
42
+ catch (error) {
43
+ if (error instanceof ApiError && error.status === 404) {
44
+ return undefined;
45
+ }
46
+ else {
47
+ throw error;
48
+ }
49
+ }
50
+ };
51
+ const getUser = async (token) => request(METHOD.GET, 'user', { token });
52
+ const linkUser = async (body) => request(METHOD.POST, 'user/external-ids', {
53
+ body: {
54
+ external_id: body.externalId,
55
+ user_id: body.userId,
56
+ }
57
+ });
58
+ const searchUsers = async (payload) => request(METHOD.GET, `users?${queryString.stringify(payload)}`, {});
59
+ const updateUser = async (token, body) => request(METHOD.PUT, 'user', { body, token });
60
+ const getPlatformUserId = (externalIds, platformId) => {
61
+ for (const externalId of externalIds) {
62
+ const [userPlatformId, userId] = externalId.split('/', 2);
63
+ if (userPlatformId === platformId) {
64
+ return userId;
65
+ }
66
+ }
67
+ };
68
+ /*
69
+ * If a platformId is given, returns an array where
70
+ * the first element is the user id from the platform
71
+ * and the second is the value from the map
72
+ * Otherwise, returns an array where
73
+ * the first element is the user's full_name
74
+ * and the second is the value from the map
75
+ */
76
+ const mapUserUuids = async (userUuidsMap, platformId) => {
77
+ const results = await mapUserData(Object.entries(userUuidsMap), ([id]) => id, (user, [, data]) => {
78
+ if (!user)
79
+ return undefined;
80
+ const platformUserId = platformId ? getPlatformUserId(user.external_ids, platformId) : undefined;
81
+ if (platformId && !platformUserId) {
82
+ logger.logEvent(Level.Warn, {
83
+ message: 'Accounts user has no external_id matching the given platformId',
84
+ accountsUuid: user.uuid,
85
+ platformId,
86
+ });
87
+ }
88
+ if (!user.full_name) {
89
+ logger.logEvent(Level.Warn, {
90
+ message: 'Accounts user has no full_name',
91
+ accountsUuid: user.uuid,
92
+ });
93
+ }
94
+ return { data, fullName: user.full_name, platformUserId, uuid: user.uuid };
95
+ });
96
+ return results.filter(isDefined);
97
+ };
98
+ const getUserMap = async (userUuids, mapper) => {
99
+ if (userUuids.size === 0)
100
+ return new Map();
101
+ const chunked = chunk([...userUuids], 10);
102
+ const results = await Promise.all(chunked.map(async (inputChunk) => {
103
+ const { items } = await searchUsers({ q: inputChunk.map(userUuid => `uuid:${userUuid}`).join(' ')
104
+ });
105
+ const accountsUuids = items.map((user) => user.uuid);
106
+ if (!isEqual(accountsUuids.sort(), inputChunk.sort())) {
107
+ logger.logEvent(Level.Warn, {
108
+ message: 'Unexpected Accounts user search results',
109
+ uuids: inputChunk,
110
+ accountsUuids,
111
+ });
112
+ }
113
+ return items;
114
+ }));
115
+ return new Map(results.flat(1).map(user => [user.uuid, mapper(user)]));
116
+ };
117
+ const mapUserData = async (input, getUserUuid, mapper) => {
118
+ const userMap = await getUserMap(new Set(input.flatMap(getUserUuid)), user => user);
119
+ return input.map(item => mapper(userMap.get(getUserUuid(item)), item));
120
+ };
121
+ const mapUsersData = async (input, getUserUuids, mapper) => {
122
+ const userMap = await getUserMap(new Set(input.flatMap(getUserUuids)), user => user);
123
+ return input.map(item => {
124
+ const userUuids = getUserUuids(item);
125
+ const itemUserMap = new Map(userUuids.map(uuid => [uuid, userMap.get(uuid)]));
126
+ return mapper(itemUserMap, item);
127
+ });
128
+ };
129
+ return { findOrCreateUser, findUser, getUser, linkUser, mapUserUuids, searchUsers, updateUser, getUserMap, mapUserData, mapUsersData };
130
+ };
131
+ };
@@ -0,0 +1,68 @@
1
+ import { Headers } from 'node-fetch';
2
+ import { ConfigProviderForConfig } from '../../config';
3
+ import { ConfigForFetch, GenericFetch, Response } from '../../fetch';
4
+ import { AnyRoute, ApiResponse, OutputForRoute, ParamsForRoute, PayloadForRoute, QueryParams } from '../../routing';
5
+ import { UnwrapPromise } from '../../types';
6
+ import { Logger } from '../logger';
7
+ export type TResponsePayload<R> = R extends ApiResponse<any, infer P> ? P : never;
8
+ export type TResponseStatus<R> = R extends ApiResponse<infer S, any> ? S : never;
9
+ export type RouteClient<R> = {
10
+ (config: {
11
+ fetchConfig?: any;
12
+ query?: QueryParams;
13
+ } & (ParamsForRoute<R> extends undefined ? {} : {
14
+ params: ParamsForRoute<R>;
15
+ }) & (PayloadForRoute<R> extends undefined ? {} : {
16
+ payload: PayloadForRoute<R>;
17
+ })): Promise<UnsafeApiClientResponse<UnwrapPromise<OutputForRoute<R>>>>;
18
+ renderUrl: (config: {
19
+ query?: QueryParams;
20
+ } & (ParamsForRoute<R> extends undefined ? {} : {
21
+ params: ParamsForRoute<R>;
22
+ })) => Promise<string>;
23
+ };
24
+ export interface AcceptStatus<Ro> {
25
+ <S extends TResponseStatus<Ro>[]>(...args: S): Promise<ApiClientResponse<Extract<Ro, Record<'statusCode', S[number]>>>>;
26
+ <S extends number[]>(...args: S): Promise<ApiClientResponse<any>>;
27
+ }
28
+ export type UnsafeApiClientResponse<Ro> = {
29
+ headers: Headers;
30
+ load: () => Promise<any>;
31
+ status: number;
32
+ acceptStatus: AcceptStatus<Ro>;
33
+ };
34
+ export type ApiClientResponse<Ro> = Ro extends any ? {
35
+ headers: Headers;
36
+ status: TResponseStatus<Ro>;
37
+ load: () => Promise<TResponsePayload<Ro>>;
38
+ } : never;
39
+ export type ExpandRoute<T> = T extends ((...args: infer A) => infer R) & {
40
+ renderUrl: (...args: infer Ar) => Promise<string>;
41
+ } ? ((...args: A) => R) & {
42
+ renderUrl: (...args: Ar) => Promise<string>;
43
+ } : never;
44
+ export type MapRoutesToClient<Ru> = [Ru] extends [AnyRoute<Ru>] ? {
45
+ [N in Ru['name']]: ExpandRoute<RouteClient<Extract<Ru, Record<'name', N>>>>;
46
+ } : never;
47
+ export type MapRoutesToConfig<Ru> = [Ru] extends [AnyRoute<Ru>] ? {
48
+ [_N in Ru['name']]: {
49
+ path: string;
50
+ method: string;
51
+ };
52
+ } : never;
53
+ /** Pulls the content out of a response based on the content type */
54
+ export declare const loadResponse: (response: Response) => () => Promise<any>;
55
+ export interface MakeApiGateway<F> {
56
+ <Ru>(config: ConfigProviderForConfig<{
57
+ apiBase: string;
58
+ }>, routes: MapRoutesToConfig<Ru>, app?: {
59
+ authProvider?: {
60
+ getAuthorizedFetchConfig: () => Promise<ConfigForFetch<F>>;
61
+ };
62
+ logger?: Logger;
63
+ launchToken?: string;
64
+ }): MapRoutesToClient<Ru>;
65
+ }
66
+ export declare const createApiGateway: <F extends GenericFetch>(initializer: {
67
+ fetch: F;
68
+ }) => MakeApiGateway<F>;
@@ -0,0 +1,77 @@
1
+ import * as pathToRegexp from 'path-to-regexp';
2
+ import queryString from 'query-string';
3
+ import { v4 as uuid } from 'uuid';
4
+ import { merge } from '../..';
5
+ import { resolveConfigValue } from '../../config';
6
+ import { SessionExpiredError, UnauthorizedError } from '../../errors';
7
+ import { fetchStatusRetry } from '../../fetch/fetchStatusRetry';
8
+ import { Level } from '../logger';
9
+ /** Pulls the content out of a response based on the content type */
10
+ export const loadResponse = (response) => () => {
11
+ const [contentType] = (response.headers.get('content-type') || '').split(';');
12
+ switch (contentType) {
13
+ case 'text/plain':
14
+ return response.text();
15
+ case 'application/json':
16
+ return response.json();
17
+ default:
18
+ throw new Error(`unknown content type ${contentType}`);
19
+ }
20
+ };
21
+ const makeRouteClient = (initializer, config, route, app) => {
22
+ /* TODO this duplicates code with makeRenderRouteUrl, reuse that */
23
+ const renderUrl = async ({ params, query }) => {
24
+ const apiBase = await resolveConfigValue(config.apiBase);
25
+ const getPathForParams = pathToRegexp.compile(route.path, { encode: encodeURIComponent });
26
+ const search = query && queryString.stringify(query);
27
+ return apiBase.replace(/\/+$/, '') + getPathForParams(params || {}) + (search ? `?${search}` : '');
28
+ };
29
+ const routeClient = async ({ params, payload, query, fetchConfig }) => {
30
+ var _a, _b;
31
+ const { fetch } = initializer;
32
+ const url = await renderUrl({ params, query });
33
+ const body = payload ? JSON.stringify(payload) : undefined;
34
+ const baseOptions = merge((await ((_a = app === null || app === void 0 ? void 0 : app.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthorizedFetchConfig())) || {}, fetchConfig || {});
35
+ const requestId = uuid();
36
+ const requestLogger = (_b = app === null || app === void 0 ? void 0 : app.logger) === null || _b === void 0 ? void 0 : _b.createSubContext();
37
+ requestLogger === null || requestLogger === void 0 ? void 0 : requestLogger.setContext({ requestId, url, timeStamp: new Date().getTime() });
38
+ const fetcher = fetchStatusRetry(fetch, { retries: 1, status: [502], logger: requestLogger });
39
+ requestLogger === null || requestLogger === void 0 ? void 0 : requestLogger.log('Request Initiated', Level.Info);
40
+ return fetcher(url, merge(baseOptions, {
41
+ method: route.method,
42
+ body,
43
+ headers: {
44
+ ...fetchConfig === null || fetchConfig === void 0 ? void 0 : fetchConfig.headers,
45
+ ...(body ? { 'content-type': 'application/json' } : {}),
46
+ 'x-request-id': requestId,
47
+ ...((app === null || app === void 0 ? void 0 : app.launchToken) ? {
48
+ 'x-launch-token': app.launchToken,
49
+ } : {}),
50
+ }
51
+ })).then(response => {
52
+ if (response.status === 401) {
53
+ throw new UnauthorizedError();
54
+ }
55
+ if (response.status === 440) {
56
+ throw new SessionExpiredError();
57
+ }
58
+ return {
59
+ status: response.status,
60
+ acceptStatus: async (...status) => {
61
+ if (!status.includes(response.status)) {
62
+ throw new Error(`unexpected HTTP ${response.status} response from api: ${await response.text()}`);
63
+ }
64
+ return { status: response.status, headers: response.headers, load: loadResponse(response) };
65
+ },
66
+ headers: response.headers,
67
+ load: loadResponse(response),
68
+ };
69
+ });
70
+ };
71
+ routeClient.renderUrl = renderUrl;
72
+ return routeClient;
73
+ };
74
+ export const createApiGateway = (initializer) => (config, routes, app) => {
75
+ return Object.fromEntries(Object.entries(routes)
76
+ .map(([key, routeConfig]) => ([key, makeRouteClient(initializer, config, routeConfig, app)])));
77
+ };
@@ -0,0 +1,40 @@
1
+ import { ConfigProviderForConfig } from '../../config';
2
+ import { GenericFetch } from '../../fetch';
3
+ import { UserData } from './utils/embeddedAuthProvider';
4
+ import { ApiUser, AuthProvider } from '.';
5
+ type Config = {
6
+ accountsBase: string;
7
+ };
8
+ interface Initializer<C> {
9
+ configSpace?: C;
10
+ window: Window;
11
+ }
12
+ export type EventHandler = (e: {
13
+ data: any;
14
+ origin: string;
15
+ source: Pick<Window, 'postMessage'>;
16
+ }) => void;
17
+ export interface Window {
18
+ fetch: GenericFetch;
19
+ parent: Pick<Window, 'postMessage'>;
20
+ location: {
21
+ search: string;
22
+ };
23
+ document: {
24
+ referrer: string;
25
+ };
26
+ postMessage: (data: any, origin: string) => void;
27
+ addEventListener: (event: 'message', callback: EventHandler) => void;
28
+ removeEventListener: (event: 'message', callback: EventHandler) => void;
29
+ }
30
+ export type UpdatableUserFields = Partial<Pick<ApiUser, 'consent_preferences' | 'first_name' | 'last_name'>>;
31
+ export type BrowserAuthProvider = AuthProvider & {
32
+ getAuthorizedUrl: (urlString: string) => string;
33
+ getAuthorizedLinkUrl: (urlString: string) => string;
34
+ getAuthorizedEmbedUrl: (urlString: string, extraParams?: {
35
+ [key: string]: string;
36
+ }) => string;
37
+ updateUser: (updates: UpdatableUserFields) => Promise<UserData<ApiUser>>;
38
+ };
39
+ export declare const browserAuthProvider: <C extends string = "auth">({ window, configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => BrowserAuthProvider;
40
+ export {};