@researchdatabox/redbox-core 5.1.0-beta.12568 → 5.1.0-beta.13939

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 (385) hide show
  1. package/browser/redoc-library-loader.cjs +20 -0
  2. package/browser/redoc-standalone.js +143 -0
  3. package/dist/CoreBase.d.ts +43 -0
  4. package/dist/CoreBase.d.ts.map +1 -0
  5. package/dist/CoreBase.js +101 -0
  6. package/dist/CoreController.d.ts +23 -31
  7. package/dist/CoreController.d.ts.map +1 -1
  8. package/dist/CoreController.js +142 -131
  9. package/dist/CoreService.d.ts +13 -33
  10. package/dist/CoreService.d.ts.map +1 -1
  11. package/dist/CoreService.js +69 -95
  12. package/dist/HarvestRunService.d.ts +9 -1
  13. package/dist/HarvestRunService.d.ts.map +1 -1
  14. package/dist/HarvestRunService.js +1 -1
  15. package/dist/RecordRouteForm.d.ts +49 -0
  16. package/dist/RecordRouteForm.d.ts.map +1 -0
  17. package/dist/RecordRouteForm.js +188 -0
  18. package/dist/RecordSaveResponse.d.ts +4 -0
  19. package/dist/RecordSaveResponse.d.ts.map +1 -1
  20. package/dist/RecordSaveResponse.js +3 -2
  21. package/dist/action-execution/executor.d.ts +1 -1
  22. package/dist/action-execution/executor.d.ts.map +1 -1
  23. package/dist/action-execution/executor.js +19 -20
  24. package/dist/action-execution/legacy-result.d.ts +1 -1
  25. package/dist/action-execution/legacy-result.d.ts.map +1 -1
  26. package/dist/action-execution/legacy-result.js +43 -10
  27. package/dist/action-execution/types.d.ts +3 -3
  28. package/dist/action-execution/types.d.ts.map +1 -1
  29. package/dist/api-routes/groups/harvest-runs.d.ts +1 -0
  30. package/dist/api-routes/groups/harvest-runs.d.ts.map +1 -1
  31. package/dist/api-routes/groups/harvest-runs.js +24 -3
  32. package/dist/api-routes/groups/records.d.ts.map +1 -1
  33. package/dist/api-routes/groups/records.js +30 -21
  34. package/dist/api-routes/groups/reports.d.ts.map +1 -1
  35. package/dist/api-routes/groups/reports.js +3 -2
  36. package/dist/api-routes/helpers.d.ts +1 -1
  37. package/dist/api-routes/helpers.d.ts.map +1 -1
  38. package/dist/api-routes/helpers.js +10 -6
  39. package/dist/api-routes/openapi.d.ts.map +1 -1
  40. package/dist/api-routes/openapi.js +15 -1
  41. package/dist/api-routes/request-extraction.js +2 -2
  42. package/dist/api-routes/schemas/common.d.ts.map +1 -1
  43. package/dist/api-routes/schemas/common.js +7 -2
  44. package/dist/api-routes/schemas/responses.d.ts +38 -12
  45. package/dist/api-routes/schemas/responses.d.ts.map +1 -1
  46. package/dist/api-routes/schemas/responses.js +11 -1
  47. package/dist/bootstrap.d.ts.map +1 -1
  48. package/dist/bootstrap.js +13 -3
  49. package/dist/config/agendaQueue.config.d.ts +5 -0
  50. package/dist/config/agendaQueue.config.d.ts.map +1 -1
  51. package/dist/config/agendaQueue.config.js +29 -2
  52. package/dist/config/appConfigSecrets.config.d.ts +14 -0
  53. package/dist/config/appConfigSecrets.config.d.ts.map +1 -0
  54. package/dist/config/appConfigSecrets.config.js +8 -0
  55. package/dist/config/brandingConfigurationDefaults.config.d.ts +16 -3
  56. package/dist/config/brandingConfigurationDefaults.config.d.ts.map +1 -1
  57. package/dist/config/brandingConfigurationDefaults.config.js +1 -1
  58. package/dist/config/dompurify.config.d.ts.map +1 -1
  59. package/dist/config/dompurify.config.js +3 -2
  60. package/dist/config/harvestRuns.config.d.ts +7 -0
  61. package/dist/config/harvestRuns.config.d.ts.map +1 -1
  62. package/dist/config/harvestRuns.config.js +2 -1
  63. package/dist/config/http.config.d.ts +3 -2
  64. package/dist/config/http.config.d.ts.map +1 -1
  65. package/dist/config/http.config.js +108 -12
  66. package/dist/config/i18n.config.d.ts +3 -0
  67. package/dist/config/i18n.config.d.ts.map +1 -1
  68. package/dist/config/i18n.config.js +1 -1
  69. package/dist/config/index.d.ts +4 -0
  70. package/dist/config/index.d.ts.map +1 -1
  71. package/dist/config/index.js +4 -1
  72. package/dist/config/log.config.d.ts +33 -5
  73. package/dist/config/log.config.d.ts.map +1 -1
  74. package/dist/config/log.config.js +58 -54
  75. package/dist/config/record.config.d.ts +17 -0
  76. package/dist/config/record.config.d.ts.map +1 -1
  77. package/dist/config/record.config.js +7 -1
  78. package/dist/config/routes.config.d.ts.map +1 -1
  79. package/dist/config/routes.config.js +11 -2
  80. package/dist/config/session.config.d.ts +2 -2
  81. package/dist/config/session.config.d.ts.map +1 -1
  82. package/dist/config/solr.config.d.ts +8 -0
  83. package/dist/config/solr.config.d.ts.map +1 -1
  84. package/dist/config/solr.config.js +15 -2
  85. package/dist/config/storage.config.d.ts.map +1 -1
  86. package/dist/config/storage.config.js +9 -1
  87. package/dist/config/vocab.config.d.ts +1 -0
  88. package/dist/config/vocab.config.d.ts.map +1 -1
  89. package/dist/config/vocab.config.js +3 -3
  90. package/dist/config/webpack.config.d.ts.map +1 -1
  91. package/dist/config/webpack.config.js +23 -5
  92. package/dist/configmodels/ConfigModels.d.ts.map +1 -1
  93. package/dist/configmodels/ConfigModels.js +3 -2
  94. package/dist/configmodels/FigsharePublishing.d.ts +1 -1
  95. package/dist/controllers/ActionController.d.ts.map +1 -1
  96. package/dist/controllers/ActionController.js +8 -2
  97. package/dist/controllers/BrandingAppController.d.ts.map +1 -1
  98. package/dist/controllers/BrandingAppController.js +21 -2
  99. package/dist/controllers/DynamicAssetController.d.ts +9 -10
  100. package/dist/controllers/DynamicAssetController.d.ts.map +1 -1
  101. package/dist/controllers/DynamicAssetController.js +67 -53
  102. package/dist/controllers/EmailController.d.ts.map +1 -1
  103. package/dist/controllers/EmailController.js +32 -14
  104. package/dist/controllers/ExportController.d.ts +9 -0
  105. package/dist/controllers/ExportController.d.ts.map +1 -1
  106. package/dist/controllers/ExportController.js +154 -3
  107. package/dist/controllers/FormVocabularyController.d.ts.map +1 -1
  108. package/dist/controllers/FormVocabularyController.js +62 -33
  109. package/dist/controllers/RecordAuditController.d.ts.map +1 -1
  110. package/dist/controllers/RecordAuditController.js +4 -2
  111. package/dist/controllers/RecordController.d.ts +4 -1
  112. package/dist/controllers/RecordController.d.ts.map +1 -1
  113. package/dist/controllers/RecordController.js +248 -114
  114. package/dist/controllers/ReportController.d.ts +1 -0
  115. package/dist/controllers/ReportController.d.ts.map +1 -1
  116. package/dist/controllers/ReportController.js +40 -12
  117. package/dist/controllers/TranslationController.d.ts.map +1 -1
  118. package/dist/controllers/TranslationController.js +56 -16
  119. package/dist/controllers/UserController.d.ts +3 -1
  120. package/dist/controllers/UserController.d.ts.map +1 -1
  121. package/dist/controllers/UserController.js +178 -76
  122. package/dist/controllers/VocabularyController.d.ts +0 -1
  123. package/dist/controllers/VocabularyController.d.ts.map +1 -1
  124. package/dist/controllers/VocabularyController.js +18 -16
  125. package/dist/controllers/webservice/AdminController.d.ts.map +1 -1
  126. package/dist/controllers/webservice/AdminController.js +2 -5
  127. package/dist/controllers/webservice/HarvestRunController.d.ts +1 -0
  128. package/dist/controllers/webservice/HarvestRunController.d.ts.map +1 -1
  129. package/dist/controllers/webservice/HarvestRunController.js +46 -2
  130. package/dist/controllers/webservice/IntegrationAuditController.d.ts +0 -1
  131. package/dist/controllers/webservice/IntegrationAuditController.d.ts.map +1 -1
  132. package/dist/controllers/webservice/IntegrationAuditController.js +13 -6
  133. package/dist/controllers/webservice/RecordController.d.ts +1 -1
  134. package/dist/controllers/webservice/RecordController.d.ts.map +1 -1
  135. package/dist/controllers/webservice/RecordController.js +13 -4
  136. package/dist/controllers/webservice/ReportController.d.ts.map +1 -1
  137. package/dist/controllers/webservice/ReportController.js +15 -10
  138. package/dist/controllers/webservice/UserManagementController.d.ts.map +1 -1
  139. package/dist/controllers/webservice/UserManagementController.js +17 -8
  140. package/dist/controllers/webservice/VocabularyController.d.ts.map +1 -1
  141. package/dist/controllers/webservice/VocabularyController.js +19 -13
  142. package/dist/form-config/generated-view-only.d.ts.map +1 -1
  143. package/dist/form-config/generated-view-only.js +12 -1
  144. package/dist/index.d.ts +2 -1
  145. package/dist/index.d.ts.map +1 -1
  146. package/dist/index.js +1 -1
  147. package/dist/loader/index.d.ts +1 -0
  148. package/dist/loader/index.d.ts.map +1 -1
  149. package/dist/loader/index.js +56 -11
  150. package/dist/middleware/redboxSession.d.ts.map +1 -1
  151. package/dist/middleware/redboxSession.js +15 -3
  152. package/dist/middleware/requestChronicle.d.ts +14 -0
  153. package/dist/middleware/requestChronicle.d.ts.map +1 -0
  154. package/dist/middleware/requestChronicle.js +73 -0
  155. package/dist/model/BuildResponse.d.ts +7 -5
  156. package/dist/model/BuildResponse.d.ts.map +1 -1
  157. package/dist/model/RBValidationError.d.ts +18 -5
  158. package/dist/model/RBValidationError.d.ts.map +1 -1
  159. package/dist/model/RBValidationError.js +56 -17
  160. package/dist/model/storage/ExportJobModel.d.ts +33 -0
  161. package/dist/model/storage/ExportJobModel.d.ts.map +1 -0
  162. package/dist/model/storage/ExportJobModel.js +3 -0
  163. package/dist/model/storage/HarvestRunModel.d.ts +20 -0
  164. package/dist/model/storage/HarvestRunModel.d.ts.map +1 -1
  165. package/dist/model/storage/HarvestRunModel.js +2 -1
  166. package/dist/model/storage/index.d.ts +2 -1
  167. package/dist/model/storage/index.d.ts.map +1 -1
  168. package/dist/model/storage/index.js +1 -1
  169. package/dist/policies/checkAuth.d.ts.map +1 -1
  170. package/dist/policies/checkAuth.js +3 -2
  171. package/dist/policies/contentSecurityPolicy.d.ts.map +1 -1
  172. package/dist/policies/contentSecurityPolicy.js +7 -2
  173. package/dist/policies/noCache.d.ts.map +1 -1
  174. package/dist/policies/noCache.js +4 -3
  175. package/dist/record-contract/record-contract-compiler.d.ts.map +1 -1
  176. package/dist/record-contract/record-contract-compiler.js +3 -19
  177. package/dist/record-contract/record-contract-context.d.ts +2 -0
  178. package/dist/record-contract/record-contract-context.d.ts.map +1 -1
  179. package/dist/record-contract/record-contract-context.js +1 -1
  180. package/dist/responses/notFound.d.ts.map +1 -1
  181. package/dist/responses/notFound.js +6 -1
  182. package/dist/responses/serverError.d.ts.map +1 -1
  183. package/dist/responses/serverError.js +13 -3
  184. package/dist/sails.d.ts +27 -17
  185. package/dist/sails.d.ts.map +1 -1
  186. package/dist/services/AgendaQueueService.d.ts +11 -2
  187. package/dist/services/AgendaQueueService.d.ts.map +1 -1
  188. package/dist/services/AgendaQueueService.js +163 -51
  189. package/dist/services/AppConfigSecrets.d.ts +66 -0
  190. package/dist/services/AppConfigSecrets.d.ts.map +1 -0
  191. package/dist/services/AppConfigSecrets.js +396 -0
  192. package/dist/services/AppConfigService.d.ts +16 -1
  193. package/dist/services/AppConfigService.d.ts.map +1 -1
  194. package/dist/services/AppConfigService.js +283 -33
  195. package/dist/services/BrandingThemeCssService.d.ts.map +1 -1
  196. package/dist/services/BrandingThemeCssService.js +32 -3
  197. package/dist/services/BrandingThemeTokens.d.ts.map +1 -1
  198. package/dist/services/BrandingThemeTokens.js +10 -1
  199. package/dist/services/ConfigService.d.ts +1 -0
  200. package/dist/services/ConfigService.d.ts.map +1 -1
  201. package/dist/services/ConfigService.js +24 -9
  202. package/dist/services/DomSanitizerService.d.ts.map +1 -1
  203. package/dist/services/DomSanitizerService.js +19 -6
  204. package/dist/services/EmailService.d.ts +10 -2
  205. package/dist/services/EmailService.d.ts.map +1 -1
  206. package/dist/services/EmailService.js +53 -53
  207. package/dist/services/ExportService.d.ts +62 -0
  208. package/dist/services/ExportService.d.ts.map +1 -0
  209. package/dist/services/ExportService.js +609 -0
  210. package/dist/services/FormVocabularyService.d.ts.map +1 -1
  211. package/dist/services/FormVocabularyService.js +14 -4
  212. package/dist/services/FormsService.d.ts +3 -0
  213. package/dist/services/FormsService.d.ts.map +1 -1
  214. package/dist/services/FormsService.js +10 -3
  215. package/dist/services/HarvestRunService.d.ts +23 -1
  216. package/dist/services/HarvestRunService.d.ts.map +1 -1
  217. package/dist/services/HarvestRunService.js +155 -22
  218. package/dist/services/I18nEntriesService.d.ts +5 -0
  219. package/dist/services/I18nEntriesService.d.ts.map +1 -1
  220. package/dist/services/I18nEntriesService.js +55 -3
  221. package/dist/services/NamedQueryService.d.ts +1 -0
  222. package/dist/services/NamedQueryService.d.ts.map +1 -1
  223. package/dist/services/NamedQueryService.js +67 -31
  224. package/dist/services/RDMPService.d.ts.map +1 -1
  225. package/dist/services/RDMPService.js +69 -83
  226. package/dist/services/RaidService.d.ts.map +1 -1
  227. package/dist/services/RaidService.js +45 -11
  228. package/dist/services/RecordSchemaService.d.ts +3 -1
  229. package/dist/services/RecordSchemaService.d.ts.map +1 -1
  230. package/dist/services/RecordSchemaService.js +2 -1
  231. package/dist/services/RecordValidationService.d.ts +3 -0
  232. package/dist/services/RecordValidationService.d.ts.map +1 -1
  233. package/dist/services/RecordValidationService.js +25 -5
  234. package/dist/services/RecordsService.d.ts +10 -1
  235. package/dist/services/RecordsService.d.ts.map +1 -1
  236. package/dist/services/RecordsService.js +194 -93
  237. package/dist/services/ReportsService.d.ts +1 -0
  238. package/dist/services/ReportsService.d.ts.map +1 -1
  239. package/dist/services/ReportsService.js +10 -9
  240. package/dist/services/RvaImportService.d.ts.map +1 -1
  241. package/dist/services/RvaImportService.js +6 -5
  242. package/dist/services/SolrSearchService.d.ts +7 -2
  243. package/dist/services/SolrSearchService.d.ts.map +1 -1
  244. package/dist/services/SolrSearchService.js +205 -81
  245. package/dist/services/StorageManagerService.d.ts +5 -0
  246. package/dist/services/StorageManagerService.d.ts.map +1 -1
  247. package/dist/services/StorageManagerService.js +4 -1
  248. package/dist/services/TriggerService.d.ts.map +1 -1
  249. package/dist/services/TriggerService.js +64 -56
  250. package/dist/services/UsersService.d.ts +13 -1
  251. package/dist/services/UsersService.d.ts.map +1 -1
  252. package/dist/services/UsersService.js +191 -257
  253. package/dist/services/VocabularyService.d.ts +11 -1
  254. package/dist/services/VocabularyService.d.ts.map +1 -1
  255. package/dist/services/VocabularyService.js +120 -24
  256. package/dist/services/doi-v2/http.d.ts +3 -2
  257. package/dist/services/doi-v2/http.d.ts.map +1 -1
  258. package/dist/services/doi-v2/http.js +38 -4
  259. package/dist/services/doi-v2/runtime.d.ts +4 -3
  260. package/dist/services/doi-v2/runtime.d.ts.map +1 -1
  261. package/dist/services/doi-v2/runtime.js +52 -17
  262. package/dist/services/figshare-v2/assets.d.ts +1 -1
  263. package/dist/services/figshare-v2/assets.d.ts.map +1 -1
  264. package/dist/services/figshare-v2/assets.js +1 -1
  265. package/dist/services/figshare-v2/http.d.ts +3 -2
  266. package/dist/services/figshare-v2/http.d.ts.map +1 -1
  267. package/dist/services/figshare-v2/http.js +38 -4
  268. package/dist/services/figshare-v2/observability.d.ts.map +1 -1
  269. package/dist/services/figshare-v2/observability.js +3 -3
  270. package/dist/services/figshare-v2/runtime.d.ts +4 -3
  271. package/dist/services/figshare-v2/runtime.d.ts.map +1 -1
  272. package/dist/services/figshare-v2/runtime.js +48 -13
  273. package/dist/services/index.d.ts +3 -0
  274. package/dist/services/index.d.ts.map +1 -1
  275. package/dist/services/index.js +8 -3
  276. package/dist/services/integration-v2/runtime.d.ts +1 -1
  277. package/dist/services/integration-v2/runtime.d.ts.map +1 -1
  278. package/dist/services/integration-v2/runtime.js +7 -7
  279. package/dist/services/oni-v2/audit.d.ts +3 -2
  280. package/dist/services/oni-v2/audit.d.ts.map +1 -1
  281. package/dist/services/oni-v2/audit.js +38 -4
  282. package/dist/services/oni-v2/bindings.d.ts +1 -1
  283. package/dist/services/oni-v2/bindings.d.ts.map +1 -1
  284. package/dist/services/oni-v2/bindings.js +37 -4
  285. package/dist/services/oni-v2/repository.d.ts +3 -2
  286. package/dist/services/oni-v2/repository.d.ts.map +1 -1
  287. package/dist/services/oni-v2/repository.js +42 -7
  288. package/dist/services/oni-v2/runtime.d.ts +5 -4
  289. package/dist/services/oni-v2/runtime.d.ts.map +1 -1
  290. package/dist/services/oni-v2/runtime.js +57 -19
  291. package/dist/services/oni-v2/templating.d.ts +4 -2
  292. package/dist/services/oni-v2/templating.d.ts.map +1 -1
  293. package/dist/services/oni-v2/templating.js +42 -7
  294. package/dist/services/raid-v2/audit.d.ts +1 -1
  295. package/dist/services/raid-v2/audit.d.ts.map +1 -1
  296. package/dist/services/raid-v2/audit.js +39 -5
  297. package/dist/services/raid-v2/errors.d.ts +9 -9
  298. package/dist/services/raid-v2/errors.js +44 -11
  299. package/dist/services/raid-v2/http.d.ts +1 -1
  300. package/dist/services/raid-v2/http.d.ts.map +1 -1
  301. package/dist/services/raid-v2/http.js +42 -8
  302. package/dist/services/raid-v2/logger.d.ts +1 -1
  303. package/dist/services/raid-v2/logger.d.ts.map +1 -1
  304. package/dist/services/raid-v2/logger.js +42 -8
  305. package/dist/services/raid-v2/mapping.d.ts +1 -1
  306. package/dist/services/raid-v2/mapping.d.ts.map +1 -1
  307. package/dist/services/raid-v2/mapping.js +41 -7
  308. package/dist/services/raid-v2/runtime.d.ts +1 -1
  309. package/dist/services/raid-v2/runtime.d.ts.map +1 -1
  310. package/dist/services/raid-v2/runtime.js +76 -34
  311. package/dist/services/raid-v2/tags.d.ts +8 -8
  312. package/dist/services/raid-v2/tags.d.ts.map +1 -1
  313. package/dist/services/raid-v2/tags.js +42 -9
  314. package/dist/services/record-hooks/coordinator.d.ts +11 -0
  315. package/dist/services/record-hooks/coordinator.d.ts.map +1 -1
  316. package/dist/services/record-hooks/coordinator.js +70 -6
  317. package/dist/storage/GridFSDriver.d.ts +16 -9
  318. package/dist/storage/GridFSDriver.d.ts.map +1 -1
  319. package/dist/storage/GridFSDriver.js +87 -33
  320. package/dist/storage/TusStorageManagerDataStore.d.ts +11 -1
  321. package/dist/storage/TusStorageManagerDataStore.d.ts.map +1 -1
  322. package/dist/storage/TusStorageManagerDataStore.js +190 -56
  323. package/dist/utilities/HarvestHistoryRetention.d.ts +17 -0
  324. package/dist/utilities/HarvestHistoryRetention.d.ts.map +1 -0
  325. package/dist/utilities/HarvestHistoryRetention.js +141 -0
  326. package/dist/utilities/HarvestRunIndexes.d.ts +12 -0
  327. package/dist/utilities/HarvestRunIndexes.d.ts.map +1 -0
  328. package/dist/utilities/HarvestRunIndexes.js +84 -0
  329. package/dist/utilities/PinoLoggerUtils.d.ts +9 -0
  330. package/dist/utilities/PinoLoggerUtils.d.ts.map +1 -0
  331. package/dist/utilities/PinoLoggerUtils.js +17 -0
  332. package/dist/utilities/RequestChronicle.d.ts +221 -0
  333. package/dist/utilities/RequestChronicle.d.ts.map +1 -0
  334. package/dist/utilities/RequestChronicle.js +770 -0
  335. package/dist/utilities/RequestChronicleContext.d.ts +6 -0
  336. package/dist/utilities/RequestChronicleContext.d.ts.map +1 -0
  337. package/dist/utilities/RequestChronicleContext.js +19 -0
  338. package/dist/utilities/RequestChronicleSettings.d.ts +29 -0
  339. package/dist/utilities/RequestChronicleSettings.d.ts.map +1 -0
  340. package/dist/utilities/RequestChronicleSettings.js +31 -0
  341. package/dist/utilities/TransactionUtils.d.ts +2 -1
  342. package/dist/utilities/TransactionUtils.d.ts.map +1 -1
  343. package/dist/utilities/TransactionUtils.js +1 -1
  344. package/dist/utilities/TranslationHtml.d.ts.map +1 -1
  345. package/dist/utilities/TranslationHtml.js +13 -5
  346. package/dist/utilities/VocabularyAdminAccess.d.ts +10 -0
  347. package/dist/utilities/VocabularyAdminAccess.d.ts.map +1 -0
  348. package/dist/utilities/VocabularyAdminAccess.js +42 -0
  349. package/dist/visitor/construct.visitor.d.ts.map +1 -1
  350. package/dist/visitor/construct.visitor.js +7 -2
  351. package/dist/visitor/context-variables.visitor.d.ts +1 -2
  352. package/dist/visitor/context-variables.visitor.d.ts.map +1 -1
  353. package/dist/visitor/context-variables.visitor.js +1 -1
  354. package/dist/visitor/migrate-config-v4-v5.visitor.d.ts.map +1 -1
  355. package/dist/visitor/migrate-config-v4-v5.visitor.js +5 -1
  356. package/dist/visitor/related-object-data-inline.visitor.d.ts +1 -1
  357. package/dist/visitor/related-object-data-inline.visitor.d.ts.map +1 -1
  358. package/dist/visitor/related-object-data-inline.visitor.js +57 -23
  359. package/dist/visitor/validator.visitor.d.ts.map +1 -1
  360. package/dist/visitor/validator.visitor.js +4 -2
  361. package/dist/visitor/visitor-helpers.js +3 -3
  362. package/dist/visitor/vocab-inline.visitor.d.ts +1 -2
  363. package/dist/visitor/vocab-inline.visitor.d.ts.map +1 -1
  364. package/dist/visitor/vocab-inline.visitor.js +1 -1
  365. package/dist/waterline-models/ExportJob.d.ts +38 -0
  366. package/dist/waterline-models/ExportJob.d.ts.map +1 -0
  367. package/dist/waterline-models/ExportJob.js +148 -0
  368. package/dist/waterline-models/HarvestRecordEvent.d.ts.map +1 -1
  369. package/dist/waterline-models/HarvestRecordEvent.js +3 -9
  370. package/dist/waterline-models/HarvestRun.d.ts +5 -1
  371. package/dist/waterline-models/HarvestRun.d.ts.map +1 -1
  372. package/dist/waterline-models/HarvestRun.js +13 -7
  373. package/dist/waterline-models/HarvestRunChunk.d.ts.map +1 -1
  374. package/dist/waterline-models/HarvestRunChunk.js +3 -7
  375. package/dist/waterline-models/User.d.ts +2 -2
  376. package/dist/waterline-models/User.d.ts.map +1 -1
  377. package/dist/waterline-models/User.js +3 -3
  378. package/dist/waterline-models/index.d.ts +2 -0
  379. package/dist/waterline-models/index.d.ts.map +1 -1
  380. package/dist/waterline-models/index.js +4 -1
  381. package/logfmt-transport.cjs +59 -0
  382. package/package.json +76 -45
  383. package/dist/Logger.d.ts +0 -16
  384. package/dist/Logger.d.ts.map +0 -1
  385. package/dist/Logger.js +0 -3
@@ -0,0 +1,609 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Services = exports.EXPORT_METADATA_RETENTION_MS = exports.EXPORT_STALE_MS = exports.EXPORT_HEARTBEAT_MS = exports.ExportServiceError = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const rxjs_1 = require("rxjs");
6
+ const luxon_1 = require("luxon");
7
+ const CoreService_1 = require("../CoreService");
8
+ const agendaQueue_config_1 = require("../config/agendaQueue.config");
9
+ class ExportServiceError extends Error {
10
+ status;
11
+ code;
12
+ constructor(status, code, message) {
13
+ super(message);
14
+ this.status = status;
15
+ this.code = code;
16
+ this.name = 'ExportServiceError';
17
+ }
18
+ }
19
+ exports.ExportServiceError = ExportServiceError;
20
+ exports.EXPORT_HEARTBEAT_MS = 15000;
21
+ exports.EXPORT_STALE_MS = 5 * 60 * 1000;
22
+ exports.EXPORT_METADATA_RETENTION_MS = 24 * 60 * 60 * 1000;
23
+ const PREFIX = 'exports/';
24
+ const JOB_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
25
+ function roleBrandId(role) {
26
+ const branding = role.branding;
27
+ if (typeof branding === 'string' || typeof branding === 'number')
28
+ return String(branding);
29
+ return branding && typeof branding === 'object' && 'id' in branding ? String(branding.id) : '';
30
+ }
31
+ function authorizationContext(context) {
32
+ const roles = context.user.roles
33
+ .filter(role => roleBrandId(role) === String(context.brand.id))
34
+ .map(role => [String(role.id), role.name])
35
+ .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
36
+ return (0, node_crypto_1.createHash)('sha256')
37
+ .update(JSON.stringify({ id: context.user.id, username: context.user.username, roles }))
38
+ .digest('hex');
39
+ }
40
+ function iso(value) {
41
+ return value === null ? null : new Date(value).toISOString();
42
+ }
43
+ function normalizeDate(value) {
44
+ if (value === undefined || value === null || value === '')
45
+ return null;
46
+ if (typeof value !== 'string' || !/(?:Z|[+-]\d{2}:\d{2})$/.test(value)) {
47
+ throw new ExportServiceError(400, 'export-invalid-date', 'Export dates must be ISO timestamps with a timezone.');
48
+ }
49
+ const date = luxon_1.DateTime.fromISO(value, { setZone: true });
50
+ const normalized = date.isValid ? date.toUTC().toISO() : null;
51
+ if (normalized === null)
52
+ throw new ExportServiceError(400, 'export-invalid-date', 'Export dates must be valid timestamps.');
53
+ return normalized;
54
+ }
55
+ var Services;
56
+ (function (Services) {
57
+ /** Background CSV lifecycle. All binary I/O stays behind the configured StorageManager disk. */
58
+ class Export extends CoreService_1.Services.Core.Service {
59
+ _exportedMethods = [
60
+ 'init',
61
+ 'createJob',
62
+ 'listJobs',
63
+ 'getJob',
64
+ 'deleteJob',
65
+ 'openDownload',
66
+ 'generateCsvJob',
67
+ 'maintenanceJob',
68
+ ];
69
+ indexesReady;
70
+ async init() {
71
+ // The storage manager creates disks after ready; config validation does not resolve a disk yet.
72
+ try {
73
+ this.settings();
74
+ }
75
+ catch (error) {
76
+ if (!(error instanceof ExportServiceError))
77
+ throw error;
78
+ // Export availability must not prevent deployments with custom disk maps from lifting.
79
+ this.updateChronicle({ exportOperation: 'init-config' }, [error]);
80
+ }
81
+ await this.ensureIndexes();
82
+ }
83
+ collection() {
84
+ return ExportJob.getDatastore().manager.collection(ExportJob.tableName);
85
+ }
86
+ ensureIndexes() {
87
+ this.indexesReady ??= (async () => {
88
+ const collection = this.collection();
89
+ await collection.createIndex({ jobId: 1 }, { unique: true });
90
+ await collection.createIndex({ brandId: 1, portal: 1, requestedByUserId: 1, createdAt: -1 });
91
+ await collection.createIndex({ status: 1, heartbeatAt: 1 });
92
+ await collection.createIndex({ status: 1, expiresAt: 1 });
93
+ await collection.createIndex({ status: 1, createdAt: 1, enqueuedAt: 1 });
94
+ await collection.createIndex({ status: 1, enqueuedAt: 1 });
95
+ await collection.createIndex({ diskName: 1, objectKey: 1 });
96
+ })().catch(error => {
97
+ this.indexesReady = undefined;
98
+ throw error;
99
+ });
100
+ return this.indexesReady;
101
+ }
102
+ settings() {
103
+ const config = sails.config.record.export.background;
104
+ const diskName = config?.diskName ?? 'exports';
105
+ const retentionHours = config?.retentionHours ?? 24;
106
+ const maxRunMinutes = config?.maxRunMinutes ?? 60;
107
+ const maxQueueMinutes = config?.maxQueueMinutes ?? 24 * 60;
108
+ const queueMs = maxQueueMinutes * 60000;
109
+ const retentionMs = retentionHours * 3600000;
110
+ const runMs = maxRunMinutes * 60000;
111
+ if (typeof retentionHours !== 'number' ||
112
+ typeof maxRunMinutes !== 'number' ||
113
+ typeof maxQueueMinutes !== 'number' ||
114
+ !Number.isSafeInteger(queueMs) ||
115
+ queueMs <= 0 ||
116
+ typeof diskName !== 'string' ||
117
+ !diskName ||
118
+ !Number.isSafeInteger(retentionMs) ||
119
+ retentionMs <= 0 ||
120
+ !Number.isSafeInteger(runMs) ||
121
+ runMs <= 0 ||
122
+ runMs > 2147483647) {
123
+ throw new ExportServiceError(503, 'export-invalid-config', 'Background export configuration is invalid.');
124
+ }
125
+ this.validateDisk(diskName);
126
+ return { diskName, retentionMs, runMs, queueMs };
127
+ }
128
+ validateDisk(diskName) {
129
+ try {
130
+ const config = StorageManagerService.getDiskConfig(diskName);
131
+ if (config.config.visibility !== 'private')
132
+ throw new Error('Export disk must be private.');
133
+ }
134
+ catch {
135
+ throw new ExportServiceError(503, 'export-storage-unavailable', 'The configured private export disk is unavailable.');
136
+ }
137
+ }
138
+ async disk(diskName) {
139
+ this.validateDisk(diskName);
140
+ await StorageManagerService.bootstrap();
141
+ return StorageManagerService.disk(diskName);
142
+ }
143
+ async effectiveContext(context) {
144
+ if (!context.brand?.id || !context.brand.name || !context.portal || !context.user?.id) {
145
+ throw new ExportServiceError(403, 'export-access-denied', 'Export access is unavailable.');
146
+ }
147
+ const user = await (0, rxjs_1.firstValueFrom)(UsersService.getEffectiveUser(context.user.id));
148
+ if (!user || user.loginDisabled || user.effectiveLoginDisabled || !user.id || !user.username) {
149
+ throw new ExportServiceError(403, 'export-access-denied', 'Export access is unavailable.');
150
+ }
151
+ const rules = PathRulesService.getRulesFromPath(`/${context.brand.name}/${context.portal}/export/record/download/csv`, context.brand);
152
+ const roles = user.roles.filter(role => roleBrandId(role) === String(context.brand.id));
153
+ const allowed = rules
154
+ ? PathRulesService.canRead(rules, roles.map(role => ({ id: role.id, name: role.name })), context.brand.name)
155
+ : roles.some(role => role.name === 'Admin' || role.name === 'Librarians');
156
+ if (!allowed)
157
+ throw new ExportServiceError(403, 'export-access-denied', 'You no longer have permission to export records.');
158
+ return { ...context, user };
159
+ }
160
+ scope(context) {
161
+ return { brandId: String(context.brand.id), portal: context.portal, requestedByUserId: String(context.user.id) };
162
+ }
163
+ dto(job) {
164
+ if (job.status === 'deleted')
165
+ throw new ExportServiceError(404, 'export-not-found', 'The export was not found.');
166
+ const expired = job.expiresAt !== null && job.expiresAt <= Date.now();
167
+ const status = expired ? 'expired' : job.status;
168
+ return {
169
+ id: job.jobId,
170
+ recordType: job.recordType,
171
+ format: job.format,
172
+ modifiedBefore: job.modifiedBefore,
173
+ modifiedAfter: job.modifiedAfter,
174
+ status,
175
+ createdAt: new Date(job.createdAt).toISOString(),
176
+ startedAt: iso(job.startedAt),
177
+ completedAt: iso(job.completedAt),
178
+ expiresAt: iso(job.expiresAt),
179
+ filename: job.filename,
180
+ byteLength: job.byteLength,
181
+ downloadUrl: status === 'ready' ? `export/jobs/${encodeURIComponent(job.jobId)}/download` : null,
182
+ errorCode: job.errorCode,
183
+ errorMessage: job.errorMessage,
184
+ };
185
+ }
186
+ async createJob(context, input, filename) {
187
+ const settings = this.settings();
188
+ const effective = await this.effectiveContext(context);
189
+ if (!input ||
190
+ input.format !== 'csv' ||
191
+ typeof input.recType !== 'string' ||
192
+ !input.recType ||
193
+ input.recType.length > 200) {
194
+ throw new ExportServiceError(400, 'export-invalid-request', 'Select a valid record type and CSV format.');
195
+ }
196
+ const modifiedBefore = normalizeDate(input.before);
197
+ const modifiedAfter = normalizeDate(input.after);
198
+ if (modifiedBefore && modifiedAfter && modifiedBefore < modifiedAfter) {
199
+ throw new ExportServiceError(400, 'export-invalid-range', 'The start date must not be after the end date.');
200
+ }
201
+ if (!(await (0, rxjs_1.firstValueFrom)(RecordTypesService.get(effective.brand, input.recType)))) {
202
+ throw new ExportServiceError(400, 'export-invalid-record-type', 'The selected record type does not exist.');
203
+ }
204
+ await this.ensureIndexes();
205
+ const row = {
206
+ jobId: (0, node_crypto_1.randomUUID)(),
207
+ brandId: String(effective.brand.id),
208
+ portal: effective.portal,
209
+ requestedByUserId: String(effective.user.id),
210
+ recordType: input.recType,
211
+ format: 'csv',
212
+ modifiedBefore,
213
+ modifiedAfter,
214
+ status: 'queued',
215
+ createdAt: Date.now(),
216
+ enqueuedAt: null,
217
+ startedAt: null,
218
+ completedAt: null,
219
+ expiresAt: null,
220
+ attemptId: null,
221
+ heartbeatAt: null,
222
+ deadlineAt: null,
223
+ cleanupAfter: null,
224
+ diskName: settings.diskName,
225
+ objectKey: null,
226
+ byteLength: null,
227
+ filename,
228
+ authorizationContext: null,
229
+ errorCode: null,
230
+ errorMessage: null,
231
+ cleanedAt: null,
232
+ };
233
+ await this.collection().insertOne(row);
234
+ try {
235
+ await AgendaQueueService.now(agendaQueue_config_1.EXPORT_GENERATE_JOB_NAME, { jobId: row.jobId });
236
+ row.enqueuedAt = Date.now();
237
+ await this.collection().updateOne({ jobId: row.jobId }, { $set: { enqueuedAt: row.enqueuedAt } });
238
+ }
239
+ catch (error) {
240
+ this.updateChronicle({ exportJobId: row.jobId, exportOperation: 'enqueue' }, [error]);
241
+ await this.fail(row.jobId, { status: 'queued' }, 'export-enqueue-failed', 'The export could not be queued. Prepare it again.');
242
+ throw new ExportServiceError(503, 'export-enqueue-failed', 'The export could not be queued. Prepare it again.');
243
+ }
244
+ return this.dto(row);
245
+ }
246
+ async listJobs(context) {
247
+ const effective = await this.effectiveContext(context);
248
+ const rows = await this.collection()
249
+ .find({ ...this.scope(effective), status: { $ne: 'deleted' } })
250
+ .sort({ createdAt: -1, jobId: -1 })
251
+ .limit(20)
252
+ .toArray();
253
+ return rows.map(row => this.dto(row));
254
+ }
255
+ async ownedJob(context, id, includeDeleted = false) {
256
+ const effective = await this.effectiveContext(context);
257
+ const row = typeof id === 'string' && JOB_ID.test(id)
258
+ ? await this.collection().findOne({
259
+ ...this.scope(effective),
260
+ jobId: id,
261
+ ...(includeDeleted ? {} : { status: { $ne: 'deleted' } }),
262
+ })
263
+ : null;
264
+ if (!row)
265
+ throw new ExportServiceError(404, 'export-not-found', 'The export was not found.');
266
+ return { context: effective, row };
267
+ }
268
+ async getJob(context, id) {
269
+ return this.dto((await this.ownedJob(context, id)).row);
270
+ }
271
+ async deleteJob(context, id) {
272
+ const { context: effective, row } = await this.ownedJob(context, id, true);
273
+ if (row.status === 'queued' || row.status === 'running') {
274
+ throw new ExportServiceError(409, 'export-in-progress', 'Wait for export preparation to finish before deleting it.');
275
+ }
276
+ let deleted = row;
277
+ if (row.status !== 'deleted') {
278
+ const now = Date.now();
279
+ // Revoke access before touching storage. Keep any existing grace period for a failed
280
+ // worker whose remote upload might still be settling; its late cleanup can also retry.
281
+ const changed = await this.collection().findOneAndUpdate({ ...this.scope(effective), jobId: id, status: { $in: ['ready', 'failed', 'expired'] } }, {
282
+ $set: {
283
+ status: 'deleted',
284
+ expiresAt: now,
285
+ cleanupAfter: Math.max(now, row.cleanupAfter ?? now),
286
+ },
287
+ }, { returnDocument: 'after', includeResultMetadata: false });
288
+ const current = changed ?? (await this.collection().findOne({ ...this.scope(effective), jobId: id }));
289
+ if (!current || current.status !== 'deleted')
290
+ throw new ExportServiceError(404, 'export-not-found', 'The export was not found.');
291
+ deleted = current;
292
+ }
293
+ if (deleted.cleanedAt === null && deleted.cleanupAfter !== null && deleted.cleanupAfter <= Date.now()) {
294
+ await this.cleanupArtifact(deleted);
295
+ }
296
+ }
297
+ async openDownload(context, id) {
298
+ const { context: effective, row } = await this.ownedJob(context, id);
299
+ if (row.status === 'expired' || (row.expiresAt !== null && row.expiresAt <= Date.now())) {
300
+ throw new ExportServiceError(410, 'export-expired', 'This export has expired. Prepare another export.');
301
+ }
302
+ if (row.status !== 'ready' || !row.objectKey || row.byteLength === null) {
303
+ throw new ExportServiceError(409, 'export-not-ready', 'The export is not ready to download.');
304
+ }
305
+ if (row.authorizationContext !== authorizationContext(effective)) {
306
+ throw new ExportServiceError(403, 'export-authorization-changed', 'Your account permissions have changed. Prepare another export.');
307
+ }
308
+ try {
309
+ const disk = await this.disk(row.diskName);
310
+ const stream = await disk.getStream(row.objectKey);
311
+ let readError;
312
+ const keepReadError = (error) => {
313
+ readError = error;
314
+ };
315
+ stream.on('error', keepReadError);
316
+ try {
317
+ // Recheck after opening storage: deletion or expiry may have won during that await.
318
+ const current = await this.collection().findOne({ ...this.scope(effective), jobId: id });
319
+ if (!current || current.status === 'deleted')
320
+ throw new ExportServiceError(404, 'export-not-found', 'The export was not found.');
321
+ if (current.status === 'expired' || (current.expiresAt !== null && current.expiresAt <= Date.now()))
322
+ throw new ExportServiceError(410, 'export-expired', 'This export has expired. Prepare another export.');
323
+ if (readError)
324
+ throw readError;
325
+ return { stream, filename: row.filename, byteLength: row.byteLength };
326
+ }
327
+ catch (error) {
328
+ stream.destroy();
329
+ throw error;
330
+ }
331
+ finally {
332
+ stream.off('error', keepReadError);
333
+ }
334
+ }
335
+ catch (error) {
336
+ if (error instanceof ExportServiceError)
337
+ throw error;
338
+ this.updateChronicle({ exportJobId: row.jobId, exportOperation: 'download' }, [error]);
339
+ throw new ExportServiceError(503, 'export-file-unavailable', 'The prepared export is temporarily unavailable.');
340
+ }
341
+ }
342
+ async fail(jobId, filter, code, message) {
343
+ const now = Date.now();
344
+ await this.collection().updateOne({ jobId, ...filter }, {
345
+ $set: {
346
+ status: 'failed',
347
+ completedAt: now,
348
+ expiresAt: now + this.settings().retentionMs,
349
+ cleanupAfter: now + exports.EXPORT_STALE_MS,
350
+ errorCode: code,
351
+ errorMessage: message,
352
+ },
353
+ });
354
+ }
355
+ async generateCsvJob(job) {
356
+ const jobId = job.attrs?.data?.jobId;
357
+ if (typeof jobId !== 'string' || !JOB_ID.test(jobId))
358
+ return;
359
+ const settings = this.settings();
360
+ const now = Date.now();
361
+ const attemptId = (0, node_crypto_1.randomUUID)();
362
+ const row = await this.collection().findOneAndUpdate({ jobId, status: 'queued' }, {
363
+ $set: {
364
+ status: 'running',
365
+ attemptId,
366
+ startedAt: now,
367
+ heartbeatAt: now,
368
+ deadlineAt: now + settings.runMs,
369
+ objectKey: `${PREFIX}${jobId}/${attemptId}.csv`,
370
+ },
371
+ }, { returnDocument: 'after', includeResultMetadata: false });
372
+ if (!row)
373
+ return;
374
+ let source;
375
+ let stopped;
376
+ let rejectStop = () => { };
377
+ const stopping = new Promise((_resolve, reject) => {
378
+ rejectStop = reject;
379
+ });
380
+ const stop = (error) => {
381
+ if (stopped)
382
+ return;
383
+ stopped = error;
384
+ source?.destroy(error);
385
+ rejectStop(error);
386
+ };
387
+ const assertActive = () => {
388
+ if (stopped)
389
+ throw stopped;
390
+ };
391
+ let heartbeatBusy = false;
392
+ const heartbeat = setInterval(() => {
393
+ if (heartbeatBusy || stopped)
394
+ return;
395
+ heartbeatBusy = true;
396
+ void (async () => {
397
+ if (job.touch)
398
+ await job.touch();
399
+ const renewed = await this.collection().updateOne({ jobId, status: 'running', attemptId, heartbeatAt: { $gt: Date.now() - exports.EXPORT_STALE_MS } }, { $set: { heartbeatAt: Date.now() } });
400
+ if (!renewed.matchedCount) {
401
+ // Publication may win a race with an already-running heartbeat.
402
+ const completed = await this.collection().findOne({ jobId, attemptId, status: 'ready' });
403
+ if (!completed)
404
+ throw new Error('Export claim is no longer active.');
405
+ }
406
+ })()
407
+ .catch(() => stop(new ExportServiceError(503, 'export-worker-interrupted', 'Export preparation was interrupted. Prepare it again.')))
408
+ .finally(() => {
409
+ heartbeatBusy = false;
410
+ });
411
+ }, exports.EXPORT_HEARTBEAT_MS);
412
+ heartbeat.unref();
413
+ const deadline = setTimeout(() => stop(new ExportServiceError(503, 'export-timed-out', 'Export preparation exceeded its time limit. Prepare it again.')), settings.runMs);
414
+ deadline.unref();
415
+ let settled = false;
416
+ const work = (async () => {
417
+ const brand = BrandingService.getBrandById(row.brandId);
418
+ const user = await (0, rxjs_1.firstValueFrom)(UsersService.getEffectiveUser(row.requestedByUserId));
419
+ if (!brand || !user)
420
+ throw new ExportServiceError(403, 'export-access-denied', 'The requester no longer has export access.');
421
+ const effective = await this.effectiveContext({ brand, portal: row.portal, user });
422
+ const disk = await this.disk(row.diskName);
423
+ assertActive();
424
+ const roles = effective.user.roles.map(role => ({ ...role, branding: roleBrandId(role) }));
425
+ source = RecordsService.exportAllPlans(effective.user.username, roles, brand, 'csv', row.modifiedBefore, row.modifiedAfter, row.recordType);
426
+ // Keep errors handled even if a disk waits before attaching its stream consumer.
427
+ source.on('error', () => { });
428
+ await disk.putStream(row.objectKey, source, { visibility: 'private', contentType: 'text/csv' });
429
+ assertActive();
430
+ const metadata = await disk.getMetaData(row.objectKey);
431
+ assertActive();
432
+ if (!Number.isSafeInteger(metadata.contentLength) || metadata.contentLength < 0)
433
+ throw new Error('Export storage returned an invalid length.');
434
+ const completedAt = Date.now();
435
+ const published = await this.collection().updateOne({
436
+ jobId,
437
+ status: 'running',
438
+ attemptId,
439
+ heartbeatAt: { $gt: completedAt - exports.EXPORT_STALE_MS },
440
+ deadlineAt: { $gt: completedAt },
441
+ }, {
442
+ $set: {
443
+ status: 'ready',
444
+ completedAt,
445
+ expiresAt: completedAt + settings.retentionMs,
446
+ byteLength: metadata.contentLength,
447
+ authorizationContext: authorizationContext(effective),
448
+ },
449
+ });
450
+ if (!published.matchedCount)
451
+ throw new ExportServiceError(503, 'export-worker-interrupted', 'Export preparation was interrupted. Prepare it again.');
452
+ })().finally(() => {
453
+ settled = true;
454
+ });
455
+ // A deadline can win while a remote disk operation is still settling. Its late result must
456
+ // never publish; when it settles, remove its own attempt artifact through the same disk.
457
+ void work
458
+ .catch(async () => {
459
+ if (stopped)
460
+ await this.cleanupArtifact(row);
461
+ })
462
+ .catch(error => {
463
+ this.updateChronicle({ exportJobId: jobId, exportOperation: 'late-cleanup' }, [error]);
464
+ });
465
+ try {
466
+ await Promise.race([work, stopping]);
467
+ }
468
+ catch (error) {
469
+ const failure = error instanceof ExportServiceError
470
+ ? error
471
+ : new ExportServiceError(503, 'export-generation-failed', 'The CSV could not be prepared. Prepare it again.');
472
+ source?.destroy();
473
+ this.updateChronicle({ exportJobId: jobId, exportOperation: 'generate' }, [error]);
474
+ await this.fail(jobId, { status: 'running', attemptId }, failure.code, failure.message);
475
+ if (settled)
476
+ await this.cleanupArtifact(row);
477
+ }
478
+ finally {
479
+ clearInterval(heartbeat);
480
+ clearTimeout(deadline);
481
+ }
482
+ }
483
+ async cleanupArtifact(row) {
484
+ const current = await this.collection().findOne({ jobId: row.jobId, attemptId: row.attemptId });
485
+ // A storage acknowledgement or timer may race a successful publication. Never delete
486
+ // the published object, nor remove an object while its active worker still owns it.
487
+ if (current?.status === 'ready' || current?.status === 'running')
488
+ return;
489
+ if (!row.objectKey) {
490
+ await this.collection().updateOne({ jobId: row.jobId, status: { $in: ['failed', 'expired', 'deleted'] } }, { $set: { cleanedAt: Date.now() } });
491
+ return;
492
+ }
493
+ try {
494
+ const disk = await this.disk(row.diskName);
495
+ // Ordinary existence only promises readable files. GridFS also exposes incomplete
496
+ // uploads to cleanup, without changing availability checks for other disk consumers.
497
+ const exists = await disk.exists(row.objectKey);
498
+ const incomplete = !exists && (await disk.listIncompleteUploads?.(row.objectKey));
499
+ if (exists || (incomplete && incomplete.some(upload => upload.key === row.objectKey))) {
500
+ await disk.delete(row.objectKey);
501
+ }
502
+ await this.collection().updateOne({ jobId: row.jobId, attemptId: row.attemptId, status: { $in: ['failed', 'expired', 'deleted'] } }, { $set: { cleanedAt: Date.now() } });
503
+ }
504
+ catch (error) {
505
+ this.updateChronicle({ exportJobId: row.jobId, exportOperation: 'cleanup' }, [error]);
506
+ }
507
+ }
508
+ async maintenanceJob(job) {
509
+ const { retentionMs, queueMs } = this.settings();
510
+ const collection = this.collection();
511
+ const now = Date.now();
512
+ await collection.updateMany({ status: 'queued', enqueuedAt: null, createdAt: { $lte: now - exports.EXPORT_STALE_MS } }, {
513
+ $set: {
514
+ status: 'failed',
515
+ completedAt: now,
516
+ expiresAt: now + retentionMs,
517
+ cleanupAfter: now,
518
+ errorCode: 'export-enqueue-failed',
519
+ errorMessage: 'Export submission was interrupted. Prepare it again.',
520
+ },
521
+ });
522
+ // An acknowledged delivery may be lost by the queue backend. Bound its wait
523
+ // separately from the short unacknowledged-submission and running-worker timeouts.
524
+ await collection.updateMany({ status: 'queued', enqueuedAt: { $ne: null, $lte: now - queueMs } }, {
525
+ $set: {
526
+ status: 'failed',
527
+ completedAt: now,
528
+ expiresAt: now + retentionMs,
529
+ cleanupAfter: now,
530
+ errorCode: 'export-queue-timed-out',
531
+ errorMessage: 'Export preparation did not start within its queue time limit. Prepare it again.',
532
+ },
533
+ });
534
+ await collection.updateMany({ status: 'running', $or: [{ heartbeatAt: { $lte: now - exports.EXPORT_STALE_MS } }, { deadlineAt: { $lte: now } }] }, {
535
+ $set: {
536
+ status: 'failed',
537
+ completedAt: now,
538
+ expiresAt: now + retentionMs,
539
+ cleanupAfter: now + exports.EXPORT_STALE_MS,
540
+ errorCode: 'export-worker-interrupted',
541
+ errorMessage: 'Export preparation was interrupted. Prepare it again.',
542
+ },
543
+ });
544
+ await collection.updateMany({ status: 'ready', expiresAt: { $lte: now } }, { $set: { status: 'expired', cleanupAfter: now } });
545
+ const cursor = collection
546
+ .find({ status: { $in: ['failed', 'expired', 'deleted'] }, cleanedAt: null, cleanupAfter: { $lte: now } })
547
+ .batchSize(100);
548
+ for await (const row of cursor) {
549
+ if (job?.touch)
550
+ await job.touch();
551
+ await this.cleanupArtifact(row);
552
+ }
553
+ await collection.deleteMany({
554
+ status: { $in: ['failed', 'expired', 'deleted'] },
555
+ cleanedAt: { $ne: null },
556
+ expiresAt: { $lte: now - exports.EXPORT_METADATA_RETENTION_MS },
557
+ });
558
+ await this.reconcileOrphans(job);
559
+ }
560
+ async reconcileObject(diskName, disk, object, job) {
561
+ if (job?.touch)
562
+ await job.touch();
563
+ if (!object ||
564
+ typeof object !== 'object' ||
565
+ !('key' in object) ||
566
+ typeof object.key !== 'string' ||
567
+ !object.key.startsWith(PREFIX))
568
+ return;
569
+ // Cleanup listings may include uploads that cannot be read yet.
570
+ // Prefer a valid listing timestamp; only request metadata when it is absent.
571
+ const listedTime = 'lastModified' in object &&
572
+ object.lastModified instanceof Date &&
573
+ Number.isFinite(object.lastModified.getTime())
574
+ ? object.lastModified
575
+ : undefined;
576
+ const lastModified = listedTime ?? (await disk.getMetaData(object.key)).lastModified;
577
+ if (!Number.isFinite(lastModified.getTime()) || lastModified.getTime() > Date.now() - exports.EXPORT_STALE_MS)
578
+ return;
579
+ const referenced = await this.collection().findOne({ diskName, objectKey: object.key });
580
+ if (!referenced)
581
+ await disk.delete(object.key);
582
+ }
583
+ async reconcileOrphans(job) {
584
+ const diskNames = await this.collection().distinct('diskName');
585
+ diskNames.push(this.settings().diskName);
586
+ for (const diskName of new Set(diskNames)) {
587
+ try {
588
+ const disk = await this.disk(diskName);
589
+ let paginationToken;
590
+ do {
591
+ const page = await disk.listAll(PREFIX, { recursive: true, paginationToken });
592
+ for (const object of page.objects) {
593
+ await this.reconcileObject(diskName, disk, object, job);
594
+ }
595
+ paginationToken = page.paginationToken;
596
+ } while (paginationToken);
597
+ for (const upload of (await disk.listIncompleteUploads?.(PREFIX)) ?? []) {
598
+ await this.reconcileObject(diskName, disk, upload, job);
599
+ }
600
+ }
601
+ catch (error) {
602
+ this.updateChronicle({ exportOperation: 'orphan-cleanup', exportDisk: diskName }, [error]);
603
+ }
604
+ }
605
+ }
606
+ }
607
+ Services.Export = Export;
608
+ })(Services || (exports.Services = Services = {}));
609
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXhwb3J0U2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9FeHBvcnRTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFxRDtBQUdyRCwrQkFBc0M7QUFDdEMsaUNBQWlDO0FBRWpDLGdEQUFzRDtBQU10RCxxRUFBd0U7QUFReEUsTUFBYSxrQkFBbUIsU0FBUSxLQUFLO0lBRXpCO0lBQ0E7SUFGbEIsWUFDa0IsTUFBYyxFQUNkLElBQVksRUFDNUIsT0FBZTtRQUVmLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUpDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxTQUFJLEdBQUosSUFBSSxDQUFRO1FBSTVCLElBQUksQ0FBQyxJQUFJLEdBQUcsb0JBQW9CLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBVEQsZ0RBU0M7QUFPWSxRQUFBLG1CQUFtQixHQUFHLEtBQUssQ0FBQztBQUM1QixRQUFBLGVBQWUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNoQyxRQUFBLDRCQUE0QixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNoRSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFDMUIsTUFBTSxNQUFNLEdBQUcsZ0VBQWdFLENBQUM7QUFFaEYsU0FBUyxXQUFXLENBQUMsSUFBZTtJQUNsQyxNQUFNLFFBQVEsR0FBWSxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3hDLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRixPQUFPLFFBQVEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksSUFBSSxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFD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