@openstax/ts-utils 1.34.0 → 1.34.1

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 (503) 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 +67 -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 +154 -0
  126. package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -0
  127. package/{packages/utils/src/types.ts → dist/cjs/types.d.ts} +6 -34
  128. package/dist/cjs/types.js +2 -0
  129. package/dist/esm/assertions/index.d.ts +89 -0
  130. package/{packages/utils/src/assertions/index.ts → dist/esm/assertions/index.js} +49 -64
  131. package/dist/esm/aws/ssmService.d.ts +5 -0
  132. package/dist/esm/aws/ssmService.js +6 -0
  133. package/dist/esm/config/awsParameterConfig.d.ts +10 -0
  134. package/dist/esm/config/awsParameterConfig.js +22 -0
  135. package/dist/esm/config/envConfig.d.ts +24 -0
  136. package/dist/esm/config/envConfig.js +53 -0
  137. package/dist/esm/config/index.d.ts +48 -0
  138. package/dist/esm/config/index.js +17 -0
  139. package/dist/esm/config/lambdaParameterConfig.d.ts +12 -0
  140. package/dist/esm/config/lambdaParameterConfig.js +38 -0
  141. package/dist/esm/config/replaceConfig.d.ts +14 -0
  142. package/{packages/utils/src/config/replaceConfig.ts → dist/esm/config/replaceConfig.js} +6 -16
  143. package/dist/esm/config/resolveConfigValue.d.ts +5 -0
  144. package/dist/esm/config/resolveConfigValue.js +8 -0
  145. package/dist/esm/errors/index.d.ts +88 -0
  146. package/{packages/utils/src/errors/index.ts → dist/esm/errors/index.js} +41 -57
  147. package/dist/esm/fetch/fetchStatusRetry.d.ts +8 -0
  148. package/dist/esm/fetch/fetchStatusRetry.js +23 -0
  149. package/dist/esm/fetch/index.d.ts +64 -0
  150. package/dist/esm/fetch/index.js +46 -0
  151. package/dist/esm/guards/index.d.ts +38 -0
  152. package/dist/esm/guards/index.js +36 -0
  153. package/dist/esm/index.d.ts +4 -0
  154. package/dist/esm/index.js +4 -0
  155. package/dist/esm/middleware/apiErrorHandler.d.ts +24 -0
  156. package/dist/esm/middleware/apiErrorHandler.js +38 -0
  157. package/dist/esm/middleware/apiSlowResponseMiddleware.d.ts +23 -0
  158. package/dist/esm/middleware/apiSlowResponseMiddleware.js +50 -0
  159. package/dist/esm/middleware/index.d.ts +47 -0
  160. package/dist/esm/middleware/index.js +44 -0
  161. package/dist/esm/middleware/lambdaCorsResponseMiddleware.d.ts +20 -0
  162. package/dist/esm/middleware/lambdaCorsResponseMiddleware.js +40 -0
  163. package/dist/esm/middleware/throwNotFoundMiddleware.d.ts +4 -0
  164. package/dist/esm/middleware/throwNotFoundMiddleware.js +10 -0
  165. package/dist/esm/misc/hashValue.d.ts +10 -0
  166. package/dist/esm/misc/hashValue.js +13 -0
  167. package/dist/esm/misc/helpers.d.ts +124 -0
  168. package/dist/esm/misc/helpers.js +199 -0
  169. package/dist/esm/misc/merge.d.ts +21 -0
  170. package/dist/esm/misc/merge.js +40 -0
  171. package/dist/esm/misc/partitionSequence.d.ts +35 -0
  172. package/{packages/utils/src/misc/partitionSequence.ts → dist/esm/misc/partitionSequence.js} +15 -23
  173. package/dist/esm/pagination/index.d.ts +91 -0
  174. package/dist/esm/pagination/index.js +77 -0
  175. package/dist/esm/routing/helpers.d.ts +57 -0
  176. package/{packages/utils/src/routing/helpers.ts → dist/esm/routing/helpers.js} +30 -42
  177. package/dist/esm/routing/index.d.ts +290 -0
  178. package/dist/esm/routing/index.js +246 -0
  179. package/dist/esm/routing/validators/zod.d.ts +4 -0
  180. package/dist/esm/routing/validators/zod.js +10 -0
  181. package/dist/esm/services/accountsGateway/index.d.ts +92 -0
  182. package/dist/esm/services/accountsGateway/index.js +131 -0
  183. package/dist/esm/services/apiGateway/index.d.ts +68 -0
  184. package/dist/esm/services/apiGateway/index.js +77 -0
  185. package/dist/esm/services/authProvider/browser.d.ts +40 -0
  186. package/dist/esm/services/authProvider/browser.js +151 -0
  187. package/dist/esm/services/authProvider/decryption.d.ts +19 -0
  188. package/dist/esm/services/authProvider/decryption.js +69 -0
  189. package/dist/esm/services/authProvider/index.d.ts +63 -0
  190. package/dist/esm/services/authProvider/index.js +26 -0
  191. package/dist/esm/services/authProvider/subrequest.d.ts +13 -0
  192. package/dist/esm/services/authProvider/subrequest.js +45 -0
  193. package/dist/esm/services/authProvider/utils/decryptAndVerify.d.ts +28 -0
  194. package/dist/esm/services/authProvider/utils/decryptAndVerify.js +85 -0
  195. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +26 -0
  196. package/dist/esm/services/authProvider/utils/embeddedAuthProvider.js +40 -0
  197. package/dist/esm/services/authProvider/utils/userRoleValidator.d.ts +13 -0
  198. package/dist/esm/services/authProvider/utils/userRoleValidator.js +33 -0
  199. package/dist/esm/services/authProvider/utils/userSubrequest.d.ts +3 -0
  200. package/dist/esm/services/authProvider/utils/userSubrequest.js +6 -0
  201. package/dist/esm/services/documentStore/dynamoEncoding.d.ts +10 -0
  202. package/dist/esm/services/documentStore/dynamoEncoding.js +45 -0
  203. package/dist/esm/services/documentStore/fileSystemAssert.d.ts +1 -0
  204. package/dist/esm/services/documentStore/fileSystemAssert.js +10 -0
  205. package/dist/esm/services/documentStore/index.d.ts +14 -0
  206. package/dist/esm/services/documentStore/index.js +1 -0
  207. package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +31 -0
  208. package/dist/esm/services/documentStore/unversioned/dynamodb.js +226 -0
  209. package/dist/esm/services/documentStore/unversioned/file-system.d.ts +32 -0
  210. package/dist/esm/services/documentStore/unversioned/file-system.js +174 -0
  211. package/dist/esm/services/documentStore/unversioned/index.d.ts +2 -0
  212. package/dist/esm/services/documentStore/unversioned/index.js +1 -0
  213. package/dist/esm/services/documentStore/versioned/dynamodb.d.ts +25 -0
  214. package/dist/esm/services/documentStore/versioned/dynamodb.js +139 -0
  215. package/dist/esm/services/documentStore/versioned/file-system.d.ts +25 -0
  216. package/dist/esm/services/documentStore/versioned/file-system.js +69 -0
  217. package/dist/esm/services/documentStore/versioned/index.d.ts +17 -0
  218. package/dist/esm/services/documentStore/versioned/index.js +1 -0
  219. package/dist/esm/services/exercisesGateway/index.d.ts +67 -0
  220. package/dist/esm/services/exercisesGateway/index.js +70 -0
  221. package/dist/esm/services/fileServer/index.d.ts +30 -0
  222. package/dist/esm/services/fileServer/index.js +13 -0
  223. package/dist/esm/services/fileServer/localFileServer.d.ts +13 -0
  224. package/dist/esm/services/fileServer/localFileServer.js +125 -0
  225. package/dist/esm/services/fileServer/s3FileServer.d.ts +14 -0
  226. package/dist/esm/services/fileServer/s3FileServer.js +124 -0
  227. package/dist/esm/services/launchParams/index.d.ts +2 -0
  228. package/dist/esm/services/launchParams/index.js +2 -0
  229. package/dist/esm/services/launchParams/signer.d.ts +23 -0
  230. package/dist/esm/services/launchParams/signer.js +51 -0
  231. package/dist/esm/services/launchParams/verifier.d.ts +21 -0
  232. package/dist/esm/services/launchParams/verifier.js +92 -0
  233. package/dist/esm/services/logger/console.d.ts +4 -0
  234. package/{packages/utils/src/services/logger/console.ts → dist/esm/services/logger/console.js} +2 -5
  235. package/dist/esm/services/logger/index.d.ts +39 -0
  236. package/dist/esm/services/logger/index.js +27 -0
  237. package/dist/esm/services/lrsGateway/addStatementDefaultFields.d.ts +5 -0
  238. package/dist/esm/services/lrsGateway/addStatementDefaultFields.js +14 -0
  239. package/dist/esm/services/lrsGateway/attempt-utils.d.ts +72 -0
  240. package/dist/esm/services/lrsGateway/attempt-utils.js +261 -0
  241. package/dist/esm/services/lrsGateway/file-system.d.ts +15 -0
  242. package/dist/esm/services/lrsGateway/file-system.js +110 -0
  243. package/dist/esm/services/lrsGateway/index.d.ts +122 -0
  244. package/dist/esm/services/lrsGateway/index.js +111 -0
  245. package/dist/esm/services/lrsGateway/xapiUtils.d.ts +71 -0
  246. package/dist/esm/services/lrsGateway/xapiUtils.js +134 -0
  247. package/dist/esm/services/postgresConnection/index.d.ts +28 -0
  248. package/dist/esm/services/postgresConnection/index.js +58 -0
  249. package/dist/esm/services/searchProvider/index.d.ts +67 -0
  250. package/dist/esm/services/searchProvider/index.js +1 -0
  251. package/dist/esm/services/searchProvider/memorySearchTheBadWay.d.ts +20 -0
  252. package/dist/esm/services/searchProvider/memorySearchTheBadWay.js +187 -0
  253. package/dist/esm/services/searchProvider/openSearch.d.ts +28 -0
  254. package/dist/esm/services/searchProvider/openSearch.js +150 -0
  255. package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -0
  256. package/dist/esm/types.d.ts +31 -0
  257. package/dist/esm/types.js +1 -0
  258. package/package.json +228 -12
  259. package/.cfnlintrc +0 -2
  260. package/.github/CODEOWNERS +0 -1
  261. package/.github/workflows/ci.yml +0 -36
  262. package/.github/workflows/lint.yml +0 -55
  263. package/.nvmrc +0 -1
  264. package/.syncignore +0 -4
  265. package/.syncpackrc +0 -18
  266. package/CONTRIBUTING.md +0 -96
  267. package/LICENSE +0 -661
  268. package/Procfile +0 -1
  269. package/app.json +0 -23
  270. package/cspell.json +0 -32
  271. package/deploy/constants.env +0 -21
  272. package/deploy/deploy.bash +0 -157
  273. package/deploy/deployment-alt-region.cfn.yml +0 -70
  274. package/deploy/deployment.cfn.yml +0 -650
  275. package/deploy/destroy-deployment.bash +0 -23
  276. package/deploy/shared.cfn.yml +0 -94
  277. package/docs/lambda-build.md +0 -35
  278. package/packages/frontend/README.md +0 -46
  279. package/packages/frontend/package.json +0 -101
  280. package/packages/frontend/public/favicon.ico +0 -0
  281. package/packages/frontend/public/index.html +0 -107
  282. package/packages/frontend/public/maintenance.html +0 -59
  283. package/packages/frontend/public/manifest.json +0 -15
  284. package/packages/frontend/public/robots.txt +0 -3
  285. package/packages/frontend/script/make-certificate.bash +0 -49
  286. package/packages/frontend/script/server/cli.js +0 -11
  287. package/packages/frontend/script/server/index.js +0 -47
  288. package/packages/frontend/script/start.bash +0 -22
  289. package/packages/frontend/script/trust-localhost.bash +0 -7
  290. package/packages/frontend/src/auth/authProvider.ts +0 -10
  291. package/packages/frontend/src/auth/useAuth.ts +0 -33
  292. package/packages/frontend/src/components/Pagination.tsx +0 -26
  293. package/packages/frontend/src/configProvider/index.ts +0 -53
  294. package/packages/frontend/src/configProvider/use.ts +0 -41
  295. package/packages/frontend/src/core/context/services.spec.tsx +0 -39
  296. package/packages/frontend/src/core/context/services.tsx +0 -16
  297. package/packages/frontend/src/core/index.spec.ts +0 -7
  298. package/packages/frontend/src/core/index.ts +0 -20
  299. package/packages/frontend/src/core/services.tsx +0 -14
  300. package/packages/frontend/src/core/types.ts +0 -3
  301. package/packages/frontend/src/example/api.ts +0 -28
  302. package/packages/frontend/src/example/components/Layout.tsx +0 -23
  303. package/packages/frontend/src/example/screens/Home.spec.tsx +0 -68
  304. package/packages/frontend/src/example/screens/Home.tsx +0 -78
  305. package/packages/frontend/src/example/screens/ThingList.spec.tsx +0 -60
  306. package/packages/frontend/src/example/screens/ThingList.tsx +0 -75
  307. package/packages/frontend/src/example/screens/ThingView.spec.tsx +0 -71
  308. package/packages/frontend/src/example/screens/ThingView.tsx +0 -47
  309. package/packages/frontend/src/example/screens/index.ts +0 -9
  310. package/packages/frontend/src/index.css +0 -159
  311. package/packages/frontend/src/index.tsx +0 -67
  312. package/packages/frontend/src/react-app-env.d.ts +0 -1
  313. package/packages/frontend/src/routing/components/RouteLink.spec.tsx +0 -55
  314. package/packages/frontend/src/routing/components/RouteLink.tsx +0 -35
  315. package/packages/frontend/src/routing/middleware.ts +0 -6
  316. package/packages/frontend/src/routing/useQuery.ts +0 -14
  317. package/packages/frontend/src/setupProxy.js +0 -19
  318. package/packages/frontend/src/setupTests.ts +0 -9
  319. package/packages/frontend/src/tests/testServices.tsx +0 -23
  320. package/packages/frontend/tsconfig.json +0 -27
  321. package/packages/lambda/.eslintrc.js +0 -64
  322. package/packages/lambda/jest-global-setup.js +0 -3
  323. package/packages/lambda/jest-setup-after-env.js +0 -1
  324. package/packages/lambda/jest.config.js +0 -31
  325. package/packages/lambda/jest.resolver.js +0 -17
  326. package/packages/lambda/package.json +0 -68
  327. package/packages/lambda/script/build.bash +0 -19
  328. package/packages/lambda/script/bundle-functions.bash +0 -10
  329. package/packages/lambda/script/lambdaLocalProxy.js +0 -16
  330. package/packages/lambda/script/lambdaLocalProxy.spec.ts +0 -147
  331. package/packages/lambda/script/utils/getRouteData.ts +0 -7
  332. package/packages/lambda/script/utils/routeDataLoader.js +0 -8
  333. package/packages/lambda/script/utils/routeDataLoader.spec.ts +0 -8
  334. package/packages/lambda/src/functions/serviceApi/core/index.ts +0 -7
  335. package/packages/lambda/src/functions/serviceApi/core/request.spec.ts +0 -38
  336. package/packages/lambda/src/functions/serviceApi/core/request.ts +0 -42
  337. package/packages/lambda/src/functions/serviceApi/core/routes.spec.ts +0 -7
  338. package/packages/lambda/src/functions/serviceApi/core/routes.ts +0 -10
  339. package/packages/lambda/src/functions/serviceApi/core/services.ts +0 -9
  340. package/packages/lambda/src/functions/serviceApi/core/types.ts +0 -13
  341. package/packages/lambda/src/functions/serviceApi/entry/lambda/https-xray.ts +0 -4
  342. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.spec.ts +0 -48
  343. package/packages/lambda/src/functions/serviceApi/entry/lambda/index.ts +0 -58
  344. package/packages/lambda/src/functions/serviceApi/entry/lambda/services.ts +0 -36
  345. package/packages/lambda/src/functions/serviceApi/entry/local.ts +0 -71
  346. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.spec.ts +0 -16
  347. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentSearchMiddleware.ts +0 -41
  348. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.spec.ts +0 -78
  349. package/packages/lambda/src/functions/serviceApi/versions/v0/example/documentStoreMiddleware.ts +0 -70
  350. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.spec.ts +0 -306
  351. package/packages/lambda/src/functions/serviceApi/versions/v0/example/routes.ts +0 -176
  352. package/packages/lambda/src/functions/serviceApi/versions/v0/index.spec.ts +0 -263
  353. package/packages/lambda/src/functions/serviceApi/versions/v0/index.ts +0 -134
  354. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.spec.ts +0 -23
  355. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/authMiddleware.ts +0 -32
  356. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.spec.ts +0 -10
  357. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/configMiddleware.ts +0 -7
  358. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.spec.ts +0 -13
  359. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/frontendFileServerMiddleware.ts +0 -23
  360. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.spec.ts +0 -9
  361. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/paginationMiddleware.ts +0 -9
  362. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.spec.ts +0 -12
  363. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/searchMiddleware.ts +0 -21
  364. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.spec.ts +0 -21
  365. package/packages/lambda/src/functions/serviceApi/versions/v0/middleware/userRoleValidatorMiddleware.ts +0 -18
  366. package/packages/lambda/tsconfig.json +0 -30
  367. package/packages/lambda/webpack.config.js +0 -97
  368. package/packages/utils/.eslintrc.js +0 -64
  369. package/packages/utils/README.md +0 -118
  370. package/packages/utils/jest-global-setup.js +0 -3
  371. package/packages/utils/jest.config.js +0 -25
  372. package/packages/utils/jest.resolver.js +0 -17
  373. package/packages/utils/package.json +0 -238
  374. package/packages/utils/src/assertions/index.spec.ts +0 -126
  375. package/packages/utils/src/aws/ssmService.ts +0 -7
  376. package/packages/utils/src/config/awsParameterConfig.ts +0 -24
  377. package/packages/utils/src/config/envConfig.ts +0 -58
  378. package/packages/utils/src/config/index.spec.ts +0 -165
  379. package/packages/utils/src/config/lambdaParameterConfig.ts +0 -49
  380. package/packages/utils/src/config/resolveConfigValue.ts +0 -10
  381. package/packages/utils/src/errors/index.spec.ts +0 -35
  382. package/packages/utils/src/fetch/fetchStatusRetry.spec.ts +0 -197
  383. package/packages/utils/src/fetch/fetchStatusRetry.ts +0 -33
  384. package/packages/utils/src/fetch/index.spec.ts +0 -34
  385. package/packages/utils/src/fetch/index.ts +0 -87
  386. package/packages/utils/src/guards/index.spec.ts +0 -58
  387. package/packages/utils/src/index.spec.ts +0 -471
  388. package/packages/utils/src/middleware/apiErrorHandler.spec.ts +0 -65
  389. package/packages/utils/src/middleware/apiErrorHandler.ts +0 -67
  390. package/packages/utils/src/middleware/apiSlowResponseMiddleware.spec.ts +0 -184
  391. package/packages/utils/src/middleware/apiSlowResponseMiddleware.ts +0 -71
  392. package/packages/utils/src/middleware/index.spec.ts +0 -99
  393. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.spec.ts +0 -103
  394. package/packages/utils/src/middleware/lambdaCorsResponseMiddleware.ts +0 -52
  395. package/packages/utils/src/middleware/throwNotFoundMiddleware.spec.ts +0 -20
  396. package/packages/utils/src/middleware/throwNotFoundMiddleware.ts +0 -11
  397. package/packages/utils/src/misc/hashValue.ts +0 -18
  398. package/packages/utils/src/misc/helpers.ts +0 -259
  399. package/packages/utils/src/misc/merge.ts +0 -48
  400. package/packages/utils/src/pagination/index.spec.ts +0 -150
  401. package/packages/utils/src/pagination/index.ts +0 -117
  402. package/packages/utils/src/routing/index.spec.ts +0 -553
  403. package/packages/utils/src/routing/index.ts +0 -424
  404. package/packages/utils/src/routing/validators/zod.spec.ts +0 -16
  405. package/packages/utils/src/routing/validators/zod.ts +0 -14
  406. package/packages/utils/src/services/accountsGateway/README.md +0 -3
  407. package/packages/utils/src/services/accountsGateway/index.spec.ts +0 -518
  408. package/packages/utils/src/services/accountsGateway/index.ts +0 -251
  409. package/packages/utils/src/services/apiGateway/README.md +0 -93
  410. package/packages/utils/src/services/apiGateway/index.spec.ts +0 -254
  411. package/packages/utils/src/services/apiGateway/index.ts +0 -189
  412. package/packages/utils/src/services/authProvider/README.md +0 -21
  413. package/packages/utils/src/services/authProvider/browser.spec.ts +0 -391
  414. package/packages/utils/src/services/authProvider/browser.ts +0 -209
  415. package/packages/utils/src/services/authProvider/decryption.spec.ts +0 -337
  416. package/packages/utils/src/services/authProvider/decryption.ts +0 -98
  417. package/packages/utils/src/services/authProvider/index.ts +0 -93
  418. package/packages/utils/src/services/authProvider/stub.spec.ts +0 -29
  419. package/packages/utils/src/services/authProvider/subrequest.spec.ts +0 -105
  420. package/packages/utils/src/services/authProvider/subrequest.ts +0 -68
  421. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.spec.ts +0 -128
  422. package/packages/utils/src/services/authProvider/utils/decryptAndVerify.ts +0 -106
  423. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.spec.ts +0 -26
  424. package/packages/utils/src/services/authProvider/utils/embeddedAuthProvider.ts +0 -57
  425. package/packages/utils/src/services/authProvider/utils/userRoleValidator.spec.ts +0 -135
  426. package/packages/utils/src/services/authProvider/utils/userRoleValidator.ts +0 -49
  427. package/packages/utils/src/services/authProvider/utils/userSubrequest.spec.ts +0 -26
  428. package/packages/utils/src/services/authProvider/utils/userSubrequest.ts +0 -10
  429. package/packages/utils/src/services/documentStore/dynamoEncoding.ts +0 -57
  430. package/packages/utils/src/services/documentStore/fileSystemAssert.spec.ts +0 -43
  431. package/packages/utils/src/services/documentStore/fileSystemAssert.ts +0 -10
  432. package/packages/utils/src/services/documentStore/unversioned/README.md +0 -13
  433. package/packages/utils/src/services/documentStore/unversioned/dynamodb.spec.ts +0 -859
  434. package/packages/utils/src/services/documentStore/unversioned/dynamodb.ts +0 -243
  435. package/packages/utils/src/services/documentStore/unversioned/file-system.spec.ts +0 -629
  436. package/packages/utils/src/services/documentStore/unversioned/file-system.ts +0 -194
  437. package/packages/utils/src/services/documentStore/versioned/README.md +0 -13
  438. package/packages/utils/src/services/documentStore/versioned/dynamodb.spec.ts +0 -376
  439. package/packages/utils/src/services/documentStore/versioned/dynamodb.ts +0 -167
  440. package/packages/utils/src/services/documentStore/versioned/file-system.spec.ts +0 -262
  441. package/packages/utils/src/services/documentStore/versioned/file-system.ts +0 -90
  442. package/packages/utils/src/services/documentStore/versioned/index.ts +0 -25
  443. package/packages/utils/src/services/exercisesGateway/README.md +0 -5
  444. package/packages/utils/src/services/exercisesGateway/index.spec.ts +0 -326
  445. package/packages/utils/src/services/exercisesGateway/index.ts +0 -163
  446. package/packages/utils/src/services/fileServer/index.spec.ts +0 -88
  447. package/packages/utils/src/services/fileServer/index.ts +0 -43
  448. package/packages/utils/src/services/fileServer/localFileServer.spec.ts +0 -182
  449. package/packages/utils/src/services/fileServer/localFileServer.ts +0 -159
  450. package/packages/utils/src/services/fileServer/s3FileServer.spec.ts +0 -266
  451. package/packages/utils/src/services/fileServer/s3FileServer.ts +0 -155
  452. package/packages/utils/src/services/launchParams/index.spec.ts +0 -366
  453. package/packages/utils/src/services/launchParams/signer.ts +0 -73
  454. package/packages/utils/src/services/launchParams/verifier.ts +0 -120
  455. package/packages/utils/src/services/logger/console.spec.ts +0 -29
  456. package/packages/utils/src/services/logger/index.spec.ts +0 -65
  457. package/packages/utils/src/services/lrsGateway/README.md +0 -5
  458. package/packages/utils/src/services/lrsGateway/addStatementDefaultFields.ts +0 -22
  459. package/packages/utils/src/services/lrsGateway/attempt-utils.spec.ts +0 -847
  460. package/packages/utils/src/services/lrsGateway/attempt-utils.ts +0 -358
  461. package/packages/utils/src/services/lrsGateway/file-system.spec.ts +0 -363
  462. package/packages/utils/src/services/lrsGateway/file-system.ts +0 -165
  463. package/packages/utils/src/services/lrsGateway/index.spec.ts +0 -194
  464. package/packages/utils/src/services/lrsGateway/index.ts +0 -257
  465. package/packages/utils/src/services/lrsGateway/xapiUtils.spec.ts +0 -887
  466. package/packages/utils/src/services/lrsGateway/xapiUtils.ts +0 -262
  467. package/packages/utils/src/services/postgresConnection/index.spec.ts +0 -170
  468. package/packages/utils/src/services/postgresConnection/index.ts +0 -84
  469. package/packages/utils/src/services/searchProvider/README.md +0 -3
  470. package/packages/utils/src/services/searchProvider/index.ts +0 -59
  471. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.spec.ts +0 -526
  472. package/packages/utils/src/services/searchProvider/memorySearchTheBadWay.ts +0 -223
  473. package/packages/utils/src/services/searchProvider/openSearch.spec.ts +0 -926
  474. package/packages/utils/src/services/searchProvider/openSearch.ts +0 -195
  475. package/packages/utils/tsconfig.json +0 -31
  476. package/packages/utils/tsconfig.without-specs.cjs.json +0 -7
  477. package/packages/utils/tsconfig.without-specs.esm.json +0 -7
  478. package/packages/utils/tsconfig.without-specs.json +0 -6
  479. package/scripts/build.bash +0 -24
  480. package/scripts/ci.bash +0 -10
  481. package/scripts/start.bash +0 -29
  482. /package/{packages/utils/src/index.ts → dist/cjs/index.d.ts} +0 -0
  483. /package/{packages/utils/src/services/launchParams/index.ts → dist/cjs/services/launchParams/index.d.ts} +0 -0
  484. /package/{packages/utils/script → script}/bin/copy-from-template.bash +0 -0
  485. /package/{packages/utils/script → script}/bin/delete-stack.bash +0 -0
  486. /package/{packages/utils/script → script}/bin/deploy.bash +0 -0
  487. /package/{packages/utils/script → script}/bin/destroy-deployment.bash +0 -0
  488. /package/{packages/utils/script → script}/bin/empty-bucket.bash +0 -0
  489. /package/{packages/utils/script → script}/bin/get-arg.bash +0 -0
  490. /package/{packages/utils/script → script}/bin/get-deployed-environments.bash +0 -0
  491. /package/{packages/utils/script → script}/bin/get-env-param.bash +0 -0
  492. /package/{packages/utils/script → script}/bin/get-kwarg.bash +0 -0
  493. /package/{packages/utils/script → script}/bin/get-stack-param.bash +0 -0
  494. /package/{packages/utils/script → script}/bin/has-flag.bash +0 -0
  495. /package/{packages/utils/script → script}/bin/init-constants-script.bash +0 -0
  496. /package/{packages/utils/script → script}/bin/init-params-script.bash +0 -0
  497. /package/{packages/utils/script → script}/bin/stack-exists.bash +0 -0
  498. /package/{packages/utils/script → script}/bin/update-utils.bash +0 -0
  499. /package/{packages/utils/script → script}/bin/upload-pager-duty-endpoints.bash +0 -0
  500. /package/{packages/utils/script → script}/bin/upload-params.bash +0 -0
  501. /package/{packages/utils/script → script}/bin/which.bash +0 -0
  502. /package/{packages/utils/script → script}/bin-entry.bash +0 -0
  503. /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
+ };