@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,261 @@
1
+ /*
2
+ * the structure of xapi statements for handling multiple attempts of an activity
3
+ * including the option of a parent activity/attempt such that a new attempt
4
+ * of a parent activity inherently creates a new attempt scope for sub-activities
5
+ * is done by convention using certain context and verb pieces of a statement.
6
+ * this module provides helpers for creating and retrieving statements according
7
+ * to this convention.
8
+ */
9
+ import formatISODuration from 'date-fns/formatISODuration';
10
+ import intervalToDuration from 'date-fns/intervalToDuration';
11
+ import isAfter from 'date-fns/isAfter';
12
+ import isBefore from 'date-fns/isBefore';
13
+ import parseISO from 'date-fns/parseISO';
14
+ var Verb;
15
+ (function (Verb) {
16
+ Verb["Attempted"] = "http://adlnet.gov/expapi/verbs/attempted";
17
+ Verb["Completed"] = "http://adlnet.gov/expapi/verbs/completed";
18
+ })(Verb || (Verb = {}));
19
+ export const matchAttempt = (statement) => statement.verb.id === Verb.Attempted;
20
+ export const matchAttemptCompleted = (attempt) => (statement) => {
21
+ var _a, _b;
22
+ return statement.verb.id === Verb.Completed
23
+ && statement.context !== undefined
24
+ && ((_a = statement.context.statement) === null || _a === void 0 ? void 0 : _a.id) === attempt.id
25
+ && statement.context.registration === ((_b = attempt.context) === null || _b === void 0 ? void 0 : _b.registration);
26
+ };
27
+ export const resolveAttempts = (statements, options) => statements.filter(statement => {
28
+ var _a;
29
+ return matchAttempt(statement)
30
+ && (!(options === null || options === void 0 ? void 0 : options.activityIRI) || statement.object.id === options.activityIRI)
31
+ && (!(options === null || options === void 0 ? void 0 : options.parentActivityAttempt) || ((_a = statement.context) === null || _a === void 0 ? void 0 : _a.registration) === options.parentActivityAttempt);
32
+ });
33
+ export const resolveCompletedForAttempt = (statements, attempt, activityIRI) => statements.find(statement => matchAttemptCompleted(attempt)(statement)
34
+ && (!activityIRI || statement.object.id === activityIRI));
35
+ export const oldestStatement = (statements) => statements.reduce((result, statement) => result && isBefore(parseISO('stored' in result && result.stored ? result.stored : result.timestamp), parseISO(statement.timestamp)) ? result : statement, statements[0]);
36
+ export const mostRecentStatement = (statements) => statements.reduce((result, statement) => result && isAfter(parseISO('stored' in result && result.stored ? result.stored : result.timestamp), parseISO(statement.timestamp)) ? result : statement, statements[0]);
37
+ export const resolveAttemptInfo = (statements, options) => {
38
+ // TODO optimize. i'm 100% that this could all be done in one iteration but i'm not messing around with that for now.
39
+ const attempts = resolveAttempts(statements, options);
40
+ /* attempts that have a completed statement */
41
+ const resolveAttemptsWithCompleted = (statements, attempts, activityIRI) => attempts.reduce((acc, attempt) => {
42
+ const completed = resolveCompletedForAttempt(statements, attempt, activityIRI);
43
+ if (completed)
44
+ acc.push({ attempt, completed });
45
+ return acc;
46
+ }, []);
47
+ const completedPairs = resolveAttemptsWithCompleted(statements, attempts, options === null || options === void 0 ? void 0 : options.activityIRI);
48
+ const completedAttempts = completedPairs.map(p => p.attempt);
49
+ /* the last attempt sorted by timestamp */
50
+ const currentAttempt = (options === null || options === void 0 ? void 0 : options.currentAttempt)
51
+ ? attempts.find(attempt => attempt.id === options.currentAttempt)
52
+ : (options === null || options === void 0 ? void 0 : options.currentPreference) === 'oldest'
53
+ ? oldestStatement(attempts)
54
+ : mostRecentStatement(attempts);
55
+ /* all statements for the current attempt (doesn't include the attempt or completed statements) */
56
+ const currentAttemptStatements = currentAttempt ? statements.filter(statement => {
57
+ var _a;
58
+ return (!(options === null || options === void 0 ? void 0 : options.activityIRI) || statement.object.id === options.activityIRI)
59
+ && ((_a = statement.context) === null || _a === void 0 ? void 0 : _a.registration) === currentAttempt.id;
60
+ }) : [];
61
+ const currentAttemptCompleted = currentAttempt && resolveCompletedForAttempt(statements, currentAttempt, options === null || options === void 0 ? void 0 : options.activityIRI);
62
+ const mostRecentPair = completedPairs.reduce((cur, pair) => {
63
+ if (!cur)
64
+ return pair;
65
+ return isAfter(parseISO(cur.attempt.timestamp), parseISO(pair.attempt.timestamp)) ? cur : pair;
66
+ }, undefined);
67
+ /*
68
+ * the structure allows for the possibility of multiple incomplete attempts.
69
+ * the implementation can choose at its discretion to ignore the currentAttempt
70
+ * and instead make a new one, for instance if the implementation desires
71
+ * an attempt timeout feature
72
+ */
73
+ const hasScaledScore = (p) => {
74
+ var _a;
75
+ return p.completed.result !== undefined &&
76
+ typeof ((_a = p.completed.result.score) === null || _a === void 0 ? void 0 : _a.scaled) === 'number';
77
+ };
78
+ // Filter to only scored pairs with scaled.
79
+ const scoredPairs = completedPairs.filter(hasScaledScore);
80
+ const bestPair = scoredPairs.reduce((best, pair) => {
81
+ if (!best)
82
+ return pair;
83
+ return pair.completed.result.score.scaled > best.completed.result.score.scaled
84
+ ? pair
85
+ : best;
86
+ }, undefined);
87
+ return {
88
+ attempts: attempts.length,
89
+ bestCompletedAttempt: bestPair === null || bestPair === void 0 ? void 0 : bestPair.attempt,
90
+ bestCompletedAttemptCompleted: bestPair === null || bestPair === void 0 ? void 0 : bestPair.completed,
91
+ completedAttempts: completedAttempts.length,
92
+ currentAttempt,
93
+ currentAttemptCompleted,
94
+ currentAttemptStatements,
95
+ mostRecentAttemptWithCompleted: mostRecentPair === null || mostRecentPair === void 0 ? void 0 : mostRecentPair.attempt,
96
+ mostRecentAttemptWithCompletedCompleted: mostRecentPair === null || mostRecentPair === void 0 ? void 0 : mostRecentPair.completed,
97
+ };
98
+ };
99
+ /*
100
+ * loads all statements (for this actor) that have the given activityIRI as the object.id or the context.contextActivities.parent.id
101
+ *
102
+ * note: if you filter on attempt you're only gonna get the `Attempted` statements from the child activities, subsequent child activity
103
+ * statements would then have to be fetched using
104
+ * `gateway.getAllXapiStatements({ activity: childActivityIRI, registration: childAttemptStatementID })`.
105
+ * this is because child activities could have multiple attempts under one attempt on the parent activity.
106
+ */
107
+ export const loadStatementsForActivityAndFirstChildren = (gateway, activityIRI, options) => {
108
+ const { attempt, ...partialOptions } = options ? options : { attempt: undefined };
109
+ const getOptions = attempt ? { registration: attempt, ...partialOptions } : partialOptions;
110
+ return gateway.getAllXapiStatements({
111
+ activity: activityIRI,
112
+ related_activities: true,
113
+ ...getOptions,
114
+ });
115
+ };
116
+ export const loadActivityAttemptInfo = async (gateway, activityIRI, options) => {
117
+ const { parentActivityAttempt, ...partialOptions } = options ? options : { parentActivityAttempt: undefined };
118
+ const loadOptions = parentActivityAttempt ? { ...partialOptions, registration: parentActivityAttempt } : partialOptions;
119
+ return resolveAttemptInfo(await gateway.getAllXapiStatements({ ...loadOptions, activity: activityIRI }), { ...options, activityIRI });
120
+ };
121
+ export const createStatement = (verb, activity, attempt, parentActivityIRI) => {
122
+ return {
123
+ context: {
124
+ ...(parentActivityIRI ? {
125
+ contextActivities: {
126
+ parent: [
127
+ {
128
+ id: parentActivityIRI,
129
+ objectType: 'Activity',
130
+ },
131
+ ],
132
+ },
133
+ } : {}),
134
+ registration: attempt,
135
+ },
136
+ object: {
137
+ definition: {
138
+ extensions: {
139
+ ...activity.extensions
140
+ },
141
+ name: {
142
+ 'en-US': activity.name,
143
+ },
144
+ type: activity.type,
145
+ },
146
+ id: activity.iri,
147
+ objectType: 'Activity'
148
+ },
149
+ verb,
150
+ };
151
+ };
152
+ /*
153
+ * activity:
154
+ * - iri: the IRI formatted id for this activity
155
+ * - type: the IRI formatted activity type (eg: http://id.tincanapi.com/activitytype/school-assignment)
156
+ * - name: the plaintext name of the activity, for reporting
157
+ *
158
+ * parentActivity:
159
+ * - iri: the IRI formatted id for the parent activity
160
+ * - attempt: the statement id for the parent attempt (the object of which should be the parentActivity.iri)
161
+ */
162
+ export const createAttemptStatement = (activity, parentActivity) => {
163
+ return {
164
+ ...((parentActivity === null || parentActivity === void 0 ? void 0 : parentActivity.iri) || (parentActivity === null || parentActivity === void 0 ? void 0 : parentActivity.attempt) ? {
165
+ context: {
166
+ ...(parentActivity.iri ? {
167
+ contextActivities: {
168
+ parent: [
169
+ {
170
+ id: parentActivity.iri,
171
+ objectType: 'Activity',
172
+ },
173
+ ],
174
+ },
175
+ } : {}),
176
+ ...(parentActivity.attempt ? {
177
+ registration: parentActivity.attempt,
178
+ } : {})
179
+ },
180
+ } : {}),
181
+ object: {
182
+ definition: {
183
+ extensions: {
184
+ ...activity.extensions
185
+ },
186
+ name: {
187
+ 'en-US': activity.name,
188
+ },
189
+ type: activity.type,
190
+ },
191
+ id: activity.iri,
192
+ objectType: 'Activity'
193
+ },
194
+ verb: {
195
+ display: { 'en-US': 'Attempted' },
196
+ id: Verb.Attempted,
197
+ },
198
+ };
199
+ };
200
+ /* resolves with the statement id */
201
+ export const putAttemptStatement = async (gateway, activity, parentActivity) => {
202
+ return (await gateway.putXapiStatements([createAttemptStatement(activity, parentActivity)]))[0];
203
+ };
204
+ /*
205
+ * creates a statement under the given attempt.
206
+ *
207
+ * `result` optional context for the attempt result (score, selected answer, etc)
208
+ */
209
+ export const createAttemptActivityStatement = (attemptStatement, verb, result) => {
210
+ var _a;
211
+ return {
212
+ context: {
213
+ ...(((_a = attemptStatement.context) === null || _a === void 0 ? void 0 : _a.contextActivities) ? {
214
+ contextActivities: attemptStatement.context.contextActivities,
215
+ } : {}),
216
+ registration: attemptStatement.id,
217
+ },
218
+ object: attemptStatement.object,
219
+ verb: verb,
220
+ ...(result ? { result } : {}),
221
+ };
222
+ };
223
+ export const putAttemptActivityStatement = async (gateway, attemptStatement, verb, result) => {
224
+ return (await gateway.putXapiStatements([createAttemptActivityStatement(attemptStatement, verb, result)]))[0];
225
+ };
226
+ /*
227
+ * creates a statement that completes the given attempt.
228
+ *
229
+ * `result` optional context for the attempt result (score, selected answer, etc)
230
+ */
231
+ export const createCompletedStatement = (attemptStatement, result) => {
232
+ var _a, _b;
233
+ return {
234
+ context: {
235
+ ...(((_a = attemptStatement.context) === null || _a === void 0 ? void 0 : _a.contextActivities) ? {
236
+ contextActivities: attemptStatement.context.contextActivities,
237
+ } : {}),
238
+ ...(((_b = attemptStatement.context) === null || _b === void 0 ? void 0 : _b.registration) ? {
239
+ registration: attemptStatement.context.registration,
240
+ } : {}),
241
+ statement: {
242
+ objectType: 'StatementRef',
243
+ id: attemptStatement.id,
244
+ }
245
+ },
246
+ object: attemptStatement.object,
247
+ verb: {
248
+ display: { 'en-US': 'Completed' },
249
+ id: Verb.Completed,
250
+ },
251
+ result: {
252
+ duration: formatISODuration(intervalToDuration({
253
+ start: parseISO(attemptStatement.timestamp), end: new Date()
254
+ })),
255
+ ...result,
256
+ }
257
+ };
258
+ };
259
+ export const putCompletedStatement = async (gateway, attemptStatement, result) => {
260
+ return (await gateway.putXapiStatements([createCompletedStatement(attemptStatement, result)]))[0];
261
+ };
@@ -0,0 +1,15 @@
1
+ import { ConfigProviderForConfig } from '../../config';
2
+ import { AuthProvider } from '../authProvider';
3
+ import { LrsGateway } from '.';
4
+ type Config = {
5
+ name: string;
6
+ };
7
+ interface Initializer<C> {
8
+ dataDir: string;
9
+ fs?: Pick<typeof import('fs'), 'readFile' | 'writeFile'>;
10
+ configSpace?: C;
11
+ }
12
+ export declare const fileSystemLrsGateway: <C extends string = "fileSystem">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => ({ authProvider }: {
13
+ authProvider: AuthProvider;
14
+ }) => LrsGateway;
15
+ export {};
@@ -0,0 +1,110 @@
1
+ import * as fsModule from 'fs';
2
+ import path from 'path';
3
+ import formatISO from 'date-fns/formatISO';
4
+ import { v4 as uuid } from 'uuid';
5
+ import { assertDefined } from '../../assertions';
6
+ import { resolveConfigValue } from '../../config';
7
+ import { UnauthorizedError } from '../../errors';
8
+ import { ifDefined } from '../../guards';
9
+ const pageSize = 5;
10
+ export const fileSystemLrsGateway = (initializer) => (configProvider) => ({ authProvider }) => {
11
+ const name = resolveConfigValue(configProvider[initializer.configSpace || 'fileSystem'].name);
12
+ const filePath = name.then((fileName) => path.join(initializer.dataDir, fileName));
13
+ const { readFile, writeFile } = ifDefined(initializer.fs, fsModule);
14
+ let data;
15
+ const load = filePath.then(path => new Promise(resolve => {
16
+ readFile(path, (err, readData) => {
17
+ if (err) {
18
+ console.error(err);
19
+ }
20
+ else {
21
+ try {
22
+ data = JSON.parse(readData.toString());
23
+ if (typeof data !== 'object' || !(data instanceof Array)) {
24
+ data = undefined;
25
+ }
26
+ }
27
+ catch (e) {
28
+ console.error(e);
29
+ }
30
+ }
31
+ resolve();
32
+ });
33
+ }));
34
+ let previousSave;
35
+ const putXapiStatements = async (statements) => {
36
+ const user = assertDefined(await authProvider.getUser(), new UnauthorizedError);
37
+ const statementsWithDefaults = statements.map(statement => ({
38
+ ...statement,
39
+ id: uuid(),
40
+ actor: {
41
+ account: {
42
+ homePage: 'https://openstax.org',
43
+ name: user.uuid,
44
+ },
45
+ objectType: 'Agent',
46
+ },
47
+ timestamp: formatISO(new Date()),
48
+ }));
49
+ await load;
50
+ await previousSave;
51
+ const path = await filePath;
52
+ const save = previousSave = new Promise(resolve => {
53
+ data = data || [];
54
+ data.push(...statementsWithDefaults.map(statement => ({ ...statement, stored: statement.timestamp })));
55
+ writeFile(path, JSON.stringify(data, null, 2), () => resolve());
56
+ });
57
+ await save;
58
+ return statementsWithDefaults;
59
+ };
60
+ const getAllXapiStatements = async ({ user, anyUser, fetchUntil, ...options }) => {
61
+ const authUser = await authProvider.getUser();
62
+ await load;
63
+ let filteredData = (data || []).filter(statement => {
64
+ var _a, _b, _c, _d;
65
+ const statementDate = new Date(statement.timestamp);
66
+ const sinceDate = options.since ? new Date(options.since) : null;
67
+ const untilDate = options.until ? new Date(options.until) : null;
68
+ return (anyUser === true || statement.actor.account.name === (user || assertDefined(authUser, new UnauthorizedError()).uuid))
69
+ && (!options.verb || statement.verb.id === options.verb)
70
+ && (!options.registration || ((_a = statement.context) === null || _a === void 0 ? void 0 : _a.registration) === options.registration)
71
+ && (!options.activity || (options.related_activities
72
+ ? ((statement.object.id === options.activity && statement.object.objectType === 'Activity')
73
+ || (!!((_d = (_c = (_b = statement.context) === null || _b === void 0 ? void 0 : _b.contextActivities) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.find(parent => parent.id === options.activity && parent.objectType === 'Activity'))))
74
+ : (statement.object.id === options.activity && statement.object.objectType === 'Activity')))
75
+ && (!sinceDate || statementDate >= sinceDate)
76
+ && (!untilDate || statementDate <= untilDate);
77
+ });
78
+ if (fetchUntil) {
79
+ for (let i = 0; i < filteredData.length; i += pageSize) {
80
+ if (fetchUntil(filteredData.slice(0, i + pageSize))) {
81
+ filteredData = filteredData.slice(0, i + pageSize);
82
+ break;
83
+ }
84
+ }
85
+ }
86
+ return filteredData;
87
+ };
88
+ const getMoreXapiStatements = async (more) => {
89
+ const { args, offset } = JSON.parse(more);
90
+ const allResults = await getAllXapiStatements(...args);
91
+ const end = offset + pageSize;
92
+ return {
93
+ more: allResults.length > end ? JSON.stringify({ args, offset: end }) : '',
94
+ statements: allResults.slice(offset, end)
95
+ };
96
+ };
97
+ const getXapiStatements = async (...args) => {
98
+ const allResults = await getAllXapiStatements(...args);
99
+ return {
100
+ more: allResults.length > pageSize ? JSON.stringify({ args, offset: pageSize }) : '',
101
+ statements: allResults.slice(0, pageSize)
102
+ };
103
+ };
104
+ return {
105
+ putXapiStatements,
106
+ getAllXapiStatements,
107
+ getXapiStatements,
108
+ getMoreXapiStatements,
109
+ };
110
+ };
@@ -0,0 +1,122 @@
1
+ import { ConfigProviderForConfig } from '../../config';
2
+ import { GenericFetch } from '../../fetch';
3
+ import { WithRequired } from '../../types';
4
+ import { AuthProvider } from '../authProvider';
5
+ import { Logger } from '../logger';
6
+ type Config = {
7
+ lrsHost: string;
8
+ lrsAuthorization: string;
9
+ };
10
+ interface Initializer<C> {
11
+ configSpace?: C;
12
+ fetch: GenericFetch;
13
+ }
14
+ export interface XapiStatement {
15
+ actor: {
16
+ account: {
17
+ homePage: 'https://openstax.org';
18
+ name: string;
19
+ };
20
+ objectType: 'Agent';
21
+ };
22
+ id: string;
23
+ context?: {
24
+ contextActivities?: {
25
+ parent?: [
26
+ {
27
+ id: string;
28
+ objectType: 'Activity';
29
+ }
30
+ ];
31
+ };
32
+ statement?: {
33
+ objectType: 'StatementRef';
34
+ id: string;
35
+ };
36
+ registration?: string;
37
+ platform?: string;
38
+ };
39
+ object: {
40
+ definition?: {
41
+ extensions?: {
42
+ [key: string]: string;
43
+ };
44
+ name: {
45
+ [key: string]: string;
46
+ };
47
+ type: string;
48
+ };
49
+ id: string;
50
+ objectType: 'Activity';
51
+ };
52
+ result?: {
53
+ score?: {
54
+ scaled?: number;
55
+ raw?: number;
56
+ min?: number;
57
+ max?: number;
58
+ };
59
+ success?: boolean;
60
+ completion?: boolean;
61
+ response?: string;
62
+ duration?: string;
63
+ extensions?: {
64
+ [key: string]: string;
65
+ };
66
+ };
67
+ verb: {
68
+ display?: {
69
+ [key: string]: string;
70
+ };
71
+ id: string;
72
+ };
73
+ timestamp: string;
74
+ stored?: string;
75
+ }
76
+ export type SavedXapiStatement = WithRequired<XapiStatement, 'stored'>;
77
+ export type EagerXapiStatement = Omit<XapiStatement, 'stored'>;
78
+ export type UXapiStatement = XapiStatement | EagerXapiStatement | SavedXapiStatement;
79
+ export type LrsGateway = ReturnType<ReturnType<ReturnType<typeof lrsGateway>>>;
80
+ export type LrsProvider = ReturnType<ReturnType<typeof lrsGateway>>;
81
+ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => ({ authProvider, logger }: {
82
+ authProvider: AuthProvider;
83
+ logger: Logger;
84
+ }) => {
85
+ putXapiStatements: (statements: Array<(Pick<XapiStatement, "object" | "verb" | "context" | "result"> & {
86
+ id?: string;
87
+ }) | UXapiStatement>) => Promise<EagerXapiStatement[]>;
88
+ getXapiStatements: (params: {
89
+ verb?: string;
90
+ activity?: string;
91
+ registration?: string;
92
+ related_activities?: boolean;
93
+ user?: string;
94
+ anyUser?: boolean;
95
+ since?: string;
96
+ until?: string;
97
+ } & {
98
+ ensureSync?: boolean;
99
+ }) => Promise<{
100
+ more: string;
101
+ statements: XapiStatement[];
102
+ }>;
103
+ getMoreXapiStatements: (more: string) => Promise<{
104
+ more: string;
105
+ statements: XapiStatement[];
106
+ }>;
107
+ getAllXapiStatements: ({ fetchUntil, ...params }: ({
108
+ verb?: string;
109
+ activity?: string;
110
+ registration?: string;
111
+ related_activities?: boolean;
112
+ user?: string;
113
+ anyUser?: boolean;
114
+ since?: string;
115
+ until?: string;
116
+ } & {
117
+ ensureSync?: boolean;
118
+ }) & {
119
+ fetchUntil?: (statements: XapiStatement[]) => boolean;
120
+ }) => Promise<XapiStatement[]>;
121
+ };
122
+ export {};
@@ -0,0 +1,111 @@
1
+ import * as queryString from 'query-string';
2
+ import { once } from '../..';
3
+ import { assertDefined } from '../../assertions';
4
+ import { resolveConfigValue } from '../../config';
5
+ import { UnauthorizedError } from '../../errors';
6
+ import { fetchStatusRetry } from '../../fetch/fetchStatusRetry';
7
+ import { ifDefined } from '../../guards';
8
+ import { retryWithDelay } from '../../misc/helpers';
9
+ import { METHOD } from '../../routing';
10
+ import { addStatementDefaultFields } from './addStatementDefaultFields';
11
+ export const lrsGateway = (initializer) => (configProvider) => {
12
+ const config = configProvider[ifDefined(initializer.configSpace, 'lrs')];
13
+ const lrsHost = once(() => resolveConfigValue(config.lrsHost));
14
+ const lrsAuthorization = once(() => resolveConfigValue(config.lrsAuthorization));
15
+ return ({ authProvider, logger }) => {
16
+ const fetcher = fetchStatusRetry(initializer.fetch, {
17
+ logger,
18
+ retries: 2,
19
+ wait: 1000,
20
+ status: [502]
21
+ });
22
+ // Note: This method actually uses POST
23
+ const putXapiStatements = async (statements) => {
24
+ const user = assertDefined(await authProvider.getUser(), new UnauthorizedError);
25
+ const statementsWithDefaults = statements.map(statement => addStatementDefaultFields(statement, user));
26
+ const response = await fetcher((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements', {
27
+ body: JSON.stringify(statementsWithDefaults),
28
+ headers: {
29
+ Authorization: await lrsAuthorization(),
30
+ 'Content-Type': 'application/json',
31
+ 'X-Experience-API-Version': '1.0.0',
32
+ },
33
+ method: METHOD.POST,
34
+ });
35
+ if (![200, 201].includes(response.status)) {
36
+ throw new Error(`Unexpected LRS POST statements response code ${response.status} with body:
37
+
38
+ ${await response.text()}`);
39
+ }
40
+ await response.json();
41
+ return statementsWithDefaults;
42
+ };
43
+ // Note: This code does not currently handle a single statement response,
44
+ // which can return 404 if the statement is not found
45
+ const formatGetXapiStatementsResponse = async (response) => {
46
+ if (response.status !== 200) {
47
+ throw new Error(`Unexpected LRS GET statements response code ${response.status} with body:
48
+
49
+ ${await response.text()}`);
50
+ }
51
+ return response.json();
52
+ };
53
+ const getMoreXapiStatements = async (more) => fetcher((await lrsHost()).replace(/\/+$/, '') + more, {
54
+ headers: {
55
+ Authorization: await lrsAuthorization(),
56
+ 'X-Experience-API-Version': '1.0.0',
57
+ },
58
+ }).then(formatGetXapiStatementsResponse);
59
+ const fetchXapiStatements = async ({ user, anyUser, ...options }) => fetcher((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements?' + queryString.stringify({
60
+ ...options,
61
+ ...(anyUser === true ? {} : {
62
+ agent: JSON.stringify({
63
+ account: {
64
+ homePage: 'https://openstax.org',
65
+ name: user || assertDefined(await authProvider.getUser(), new UnauthorizedError()).uuid,
66
+ },
67
+ objectType: 'Agent',
68
+ }),
69
+ })
70
+ }), {
71
+ headers: {
72
+ Authorization: await lrsAuthorization(),
73
+ 'X-Experience-API-Version': '1.0.0',
74
+ },
75
+ });
76
+ const getXapiStatements = async (params) => {
77
+ const { ensureSync, ...fetchParams } = params;
78
+ if (ensureSync) {
79
+ const date = new Date();
80
+ return retryWithDelay(async (abort) => {
81
+ // this function retries for the consistency, if the fetch errors just abort
82
+ const response = await fetchXapiStatements(fetchParams).catch(abort);
83
+ const consistentThrough = response.headers.get('X-Experience-API-Consistent-Through');
84
+ if (!consistentThrough || new Date(consistentThrough) < date) {
85
+ throw new Error(`xAPI consistent through ${consistentThrough}; not in sync with current date ${date.toISOString()}.`);
86
+ }
87
+ return formatGetXapiStatementsResponse(response);
88
+ }, { retries: 4, logger });
89
+ }
90
+ else {
91
+ return fetchXapiStatements(fetchParams).then(formatGetXapiStatementsResponse);
92
+ }
93
+ };
94
+ const getAllXapiStatements = async ({ fetchUntil, ...params }) => {
95
+ const loadRemaining = async (result) => {
96
+ if (!result.more || (fetchUntil && fetchUntil(result.statements))) {
97
+ return result.statements;
98
+ }
99
+ const { more, statements } = await getMoreXapiStatements(result.more);
100
+ return loadRemaining({ more, statements: [...result.statements, ...statements] });
101
+ };
102
+ return loadRemaining(await getXapiStatements(params));
103
+ };
104
+ return {
105
+ putXapiStatements,
106
+ getXapiStatements,
107
+ getMoreXapiStatements,
108
+ getAllXapiStatements,
109
+ };
110
+ };
111
+ };