@anzusystems/common-admin 2.0.0-rc.5 → 2.0.0-rc.7

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 (690) hide show
  1. package/README.md +4 -0
  2. package/dist/AnzuSystemsCommonAdmin.d.ts +42 -32
  3. package/dist/AnzuSystemsCommonAdmin.js.map +1 -1
  4. package/dist/common-admin.css +1 -1
  5. package/dist/common-admin.js +282 -282
  6. package/dist/domains/anzuUser/api/anzuUserApi.d.ts +9 -12
  7. package/dist/domains/anzuUser/api/anzuUserApi.js.map +1 -1
  8. package/dist/domains/anzuUser/components/AAnzuUserDatatable.js.map +1 -1
  9. package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue.d.ts +38 -44
  10. package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/domains/anzuUser/components/AAnzuUserFilter.js.map +1 -1
  12. package/dist/domains/anzuUser/components/AAnzuUserFilter.vue.d.ts +12 -13
  13. package/dist/domains/anzuUser/components/AAnzuUserFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/domains/anzuUser/components/AAnzuUserForm.js.map +1 -1
  15. package/dist/domains/anzuUser/components/AAnzuUserForm.vue.d.ts +18 -20
  16. package/dist/domains/anzuUser/components/AAnzuUserForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.js.map +1 -1
  18. package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/domains/anzuUser/components/AUserBulkActionDialog.js.map +1 -1
  20. package/dist/domains/anzuUser/components/AUserBulkActionDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.js.map +1 -1
  22. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue.d.ts +2 -3
  23. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.js.map +1 -1
  25. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue.d.ts +9 -15
  26. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/domains/anzuUser/components/AUserEnabledSwitch.js.map +1 -1
  28. package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue.d.ts +8 -7
  29. package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/domains/anzuUser/components/AUserManageButton.js.map +1 -1
  31. package/dist/domains/anzuUser/components/AUserManageButton.vue.d.ts +0 -1
  32. package/dist/domains/anzuUser/components/AUserManageButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/domains/anzuUser/components/AUserMetadataForm.js.map +1 -1
  34. package/dist/domains/anzuUser/components/AUserMetadataForm.vue.d.ts +8 -9
  35. package/dist/domains/anzuUser/components/AUserMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.js.map +1 -1
  37. package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.js.map +1 -1
  39. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue.d.ts +1 -2
  40. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/domains/anzuUser/components/AUserSystemOverview.js.map +1 -1
  42. package/dist/domains/anzuUser/components/AUserSystemOverview.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/domains/anzuUser/components/AUserSystemPanel.js.map +1 -1
  44. package/dist/domains/anzuUser/components/AUserSystemPanel.vue.d.ts +2 -2
  45. package/dist/domains/anzuUser/components/AUserSystemPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/domains/anzuUser/components/AUserSystemStatusChip.js.map +1 -1
  47. package/dist/domains/anzuUser/components/AUserSystemStatusChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/domains/anzuUser/components/AUserTabsShell.js.map +1 -1
  49. package/dist/domains/anzuUser/components/AUserTabsShell.vue.d.ts +17 -22
  50. package/dist/domains/anzuUser/components/AUserTabsShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/domains/anzuUser/composables/anzuUserActions.d.ts +5 -9
  52. package/dist/domains/anzuUser/composables/anzuUserActions.js.map +1 -1
  53. package/dist/domains/anzuUser/composables/anzuUserValidations.d.ts +4 -6
  54. package/dist/domains/anzuUser/composables/anzuUserValidations.js.map +1 -1
  55. package/dist/domains/anzuUser/composables/cachedAnzuUsers.d.ts +3 -3
  56. package/dist/domains/anzuUser/composables/cachedAnzuUsers.js.map +1 -1
  57. package/dist/domains/anzuUser/composables/userCrossSystemSearch.d.ts +2 -4
  58. package/dist/domains/anzuUser/composables/userCrossSystemSearch.js.map +1 -1
  59. package/dist/domains/anzuUser/composables/userCrossSystemWrites.d.ts +5 -11
  60. package/dist/domains/anzuUser/composables/userCrossSystemWrites.js.map +1 -1
  61. package/dist/domains/anzuUser/composables/userSystemDescriptor.d.ts +33 -57
  62. package/dist/domains/anzuUser/composables/userSystemDescriptor.js.map +1 -1
  63. package/dist/domains/anzuUser/composables/userSystemProbe.d.ts +7 -27
  64. package/dist/domains/anzuUser/composables/userSystemProbe.js.map +1 -1
  65. package/dist/domains/anzuUser/filter/anzuUserFilter.d.ts +6 -16
  66. package/dist/domains/anzuUser/filter/anzuUserFilter.js.map +1 -1
  67. package/dist/domains/anzuUser/store/anzuUserStore.d.ts +1 -5
  68. package/dist/domains/anzuUser/store/anzuUserStore.js.map +1 -1
  69. package/dist/domains/anzuUser/store/userCrossSystemStore.d.ts +3 -14
  70. package/dist/domains/anzuUser/store/userCrossSystemStore.js.map +1 -1
  71. package/dist/domains/anzuUser/utils/userMetadataDiff.d.ts +7 -19
  72. package/dist/domains/anzuUser/utils/userMetadataDiff.js.map +1 -1
  73. package/dist/domains/anzuUser/utils/userSystemState.d.ts +12 -30
  74. package/dist/domains/anzuUser/utils/userSystemState.js.map +1 -1
  75. package/dist/domains/anzuUser/utils/userTabs.d.ts +1 -3
  76. package/dist/domains/anzuUser/utils/userTabs.js.map +1 -1
  77. package/dist/domains/api/composables/defineApiClient.d.ts +4 -8
  78. package/dist/domains/api/composables/defineApiClient.js.map +1 -1
  79. package/dist/domains/api/composables/request.d.ts +18 -48
  80. package/dist/domains/api/composables/request.js.map +1 -1
  81. package/dist/domains/api/composables/useApiFetchByIds.d.ts +7 -21
  82. package/dist/domains/api/composables/useApiFetchByIds.js.map +1 -1
  83. package/dist/domains/api/composables/useApiFetchItems.d.ts +18 -57
  84. package/dist/domains/api/composables/useApiFetchItems.js.map +1 -1
  85. package/dist/domains/api/composables/useApiFetchList.d.ts +7 -23
  86. package/dist/domains/api/composables/useApiFetchList.js.map +1 -1
  87. package/dist/domains/api/composables/useApiFetchListBatch.d.ts +5 -22
  88. package/dist/domains/api/composables/useApiFetchListBatch.js.map +1 -1
  89. package/dist/domains/api/composables/useApiQueryBuilder.js.map +1 -1
  90. package/dist/domains/api/composables/useApiRequest.d.ts +16 -39
  91. package/dist/domains/api/composables/useApiRequest.js.map +1 -1
  92. package/dist/domains/api/utils/apiErrors.d.ts +28 -55
  93. package/dist/domains/api/utils/apiErrors.js.map +1 -1
  94. package/dist/domains/api/utils/listBody.d.ts +22 -43
  95. package/dist/domains/api/utils/listBody.js.map +1 -1
  96. package/dist/domains/auth/components/Acl.js.map +1 -1
  97. package/dist/domains/auth/components/Acl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  98. package/dist/domains/auth/composables/aclAllowed.d.ts +2 -3
  99. package/dist/domains/auth/composables/aclAllowed.js.map +1 -1
  100. package/dist/domains/auth/composables/defineAuth.js.map +1 -1
  101. package/dist/domains/auth/composables/refreshSession.d.ts +10 -13
  102. package/dist/domains/auth/composables/refreshSession.js.map +1 -1
  103. package/dist/domains/cached/components/ACachedChip.js.map +1 -1
  104. package/dist/domains/cached/components/ACachedChip.vue.d.ts +13 -11
  105. package/dist/domains/cached/components/ACachedChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  106. package/dist/domains/cached/components/ACachedUserChip.js +1 -1
  107. package/dist/domains/cached/components/ACachedUserChip.js.map +1 -1
  108. package/dist/domains/cached/components/ACachedUserChip.vue.d.ts +3 -3
  109. package/dist/domains/cached/components/ACachedUserChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/domains/cached/composables/createUserAndTimeTrackingFields.d.ts +9 -9
  111. package/dist/domains/cached/composables/createUserAndTimeTrackingFields.js.map +1 -1
  112. package/dist/domains/cached/composables/defineCached.d.ts +13 -11
  113. package/dist/domains/cached/composables/defineCached.js.map +1 -1
  114. package/dist/domains/cached/composables/useCachedItem.d.ts +7 -8
  115. package/dist/domains/cached/composables/useCachedItem.js.map +1 -1
  116. package/dist/domains/collab/components/ACollabLockedByUser.js.map +1 -1
  117. package/dist/domains/collab/components/ACollabLockedByUser.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/domains/collab/composables/collabAnyDataChange.js.map +1 -1
  119. package/dist/domains/collab/composables/collabField.d.ts +5 -3
  120. package/dist/domains/collab/composables/collabField.js.map +1 -1
  121. package/dist/domains/collab/composables/collabInit.js +58 -54
  122. package/dist/domains/collab/composables/collabInit.js.map +1 -1
  123. package/dist/domains/collab/composables/collabRecovery.d.ts +49 -0
  124. package/dist/domains/collab/composables/collabRecovery.js +99 -0
  125. package/dist/domains/collab/composables/collabRecovery.js.map +1 -0
  126. package/dist/domains/collab/composables/collabRoom.js +106 -106
  127. package/dist/domains/collab/composables/collabRoom.js.map +1 -1
  128. package/dist/domains/collab/composables/collabState.d.ts +11 -4
  129. package/dist/domains/collab/composables/collabState.js +34 -25
  130. package/dist/domains/collab/composables/collabState.js.map +1 -1
  131. package/dist/domains/collab/composables/commonAdminCollabOptions.d.ts +4 -2
  132. package/dist/domains/collab/types/Collab.d.ts +31 -5
  133. package/dist/domains/collab/types/Collab.js +23 -11
  134. package/dist/domains/collab/types/Collab.js.map +1 -1
  135. package/dist/domains/customDataForm/components/ACustomDataForm.js.map +1 -1
  136. package/dist/domains/customDataForm/components/ACustomDataForm.vue.d.ts +7 -5
  137. package/dist/domains/customDataForm/components/ACustomDataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/domains/customDataForm/components/ACustomDataFormElement.js.map +1 -1
  139. package/dist/domains/customDataForm/components/ACustomDataFormElement.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.js.map +1 -1
  141. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue.d.ts +5 -3
  142. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/domains/customDataForm/composables/useCustomDataForm.js.map +1 -1
  144. package/dist/domains/customDataForm/types/CustomDataForm.d.ts +4 -1
  145. package/dist/domains/dam/api/damAssetApi.d.ts +7 -7
  146. package/dist/domains/dam/api/damAssetApi.js.map +1 -1
  147. package/dist/domains/dam/api/damAssetLicenceApi.d.ts +1 -1
  148. package/dist/domains/dam/api/damAssetLicenceApi.js.map +1 -1
  149. package/dist/domains/dam/api/damConstants.js.map +1 -1
  150. package/dist/domains/dam/api/damEndPoints.js.map +1 -1
  151. package/dist/domains/dam/api/damImageApi.js.map +1 -1
  152. package/dist/domains/dam/api/uploadApi.js.map +1 -1
  153. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.js.map +1 -1
  154. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue.d.ts +7 -5
  155. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  156. package/dist/domains/dam/assetDetail/components/AssetDetailDialog.js.map +1 -1
  157. package/dist/domains/dam/assetDetail/components/AssetDetailDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  158. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.js.map +1 -1
  159. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue.d.ts +1 -1
  160. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  161. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsWrapper.vue.d.ts +5 -3
  162. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.js.map +1 -1
  163. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.js.map +1 -1
  165. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  166. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.js.map +1 -1
  167. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.js.map +1 -1
  169. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue.d.ts +1 -1
  170. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  171. package/dist/domains/dam/assetDetail/components/AssetImage.js.map +1 -1
  172. package/dist/domains/dam/assetDetail/components/AssetImage.vue.d.ts +1 -1
  173. package/dist/domains/dam/assetDetail/components/AssetImage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  174. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.js.map +1 -1
  175. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue.d.ts +2 -2
  176. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue_vue_type_script_setup_true_lang.js.map +1 -1
  177. package/dist/domains/dam/assetDetail/components/AssetInfobox.js.map +1 -1
  178. package/dist/domains/dam/assetDetail/components/AssetInfobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/domains/dam/assetDetail/components/AssetMetadata.js.map +1 -1
  180. package/dist/domains/dam/assetDetail/components/AssetMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.d.ts +5 -6
  182. package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.js.map +1 -1
  183. package/dist/domains/dam/assetDetail/composables/assetDetailView.d.ts +10 -10
  184. package/dist/domains/dam/assetDetail/composables/assetDetailView.js.map +1 -1
  185. package/dist/domains/dam/assetDetail/store/assetDetailStore.js.map +1 -1
  186. package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.d.ts +4 -3
  187. package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.js.map +1 -1
  188. package/dist/domains/dam/assetSelect/api/damPodcastApi.js.map +1 -1
  189. package/dist/domains/dam/assetSelect/components/AAssetListInner.js.map +1 -1
  190. package/dist/domains/dam/assetSelect/components/AAssetListInner.vue.d.ts +789 -787
  191. package/dist/domains/dam/assetSelect/components/AAssetListInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  192. package/dist/domains/dam/assetSelect/components/AAssetSelect.js.map +1 -1
  193. package/dist/domains/dam/assetSelect/components/AAssetSelect.vue.d.ts +395 -393
  194. package/dist/domains/dam/assetSelect/components/AAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  195. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.js.map +1 -1
  196. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue.d.ts +14 -12
  197. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.js.map +1 -1
  199. package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  200. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.js.map +1 -1
  201. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue.d.ts +9 -7
  202. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.js.map +1 -1
  204. package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  205. package/dist/domains/dam/assetSelect/composables/assetSelectListActions.js.map +1 -1
  206. package/dist/domains/dam/assetSelect/store/assetSelectStore.js.map +1 -1
  207. package/dist/domains/dam/author/api/authorApi.js.map +1 -1
  208. package/dist/domains/dam/author/components/AuthorCreateButton.js.map +1 -1
  209. package/dist/domains/dam/author/components/AuthorCreateButton.vue.d.ts +1 -1
  210. package/dist/domains/dam/author/components/AuthorCreateButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.js.map +1 -1
  212. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue.d.ts +9 -6
  213. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.js.map +1 -1
  215. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.vue_vue_type_script_setup_true_lang.js.map +1 -1
  216. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js +1 -1
  217. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js.map +1 -1
  218. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue.d.ts +2 -2
  219. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.js.map +1 -1
  221. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue.d.ts +1 -1
  222. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/domains/dam/author/composables/cachedAuthors.d.ts +5 -4
  224. package/dist/domains/dam/author/composables/cachedAuthors.js.map +1 -1
  225. package/dist/domains/dam/author/composables/cachedUsers.d.ts +5 -4
  226. package/dist/domains/dam/author/composables/cachedUsers.js.map +1 -1
  227. package/dist/domains/dam/author/composables/damAuthorConfig.d.ts +2 -2
  228. package/dist/domains/dam/author/composables/damAuthorConfig.js.map +1 -1
  229. package/dist/domains/dam/components/DamAdminAssetLink.js.map +1 -1
  230. package/dist/domains/dam/components/DamAdminAssetLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/domains/dam/composables/commonAdminCoreDamOptions.d.ts +10 -8
  232. package/dist/domains/dam/composables/commonAdminCoreDamOptions.js.map +1 -1
  233. package/dist/domains/dam/composables/damConfigName.d.ts +8 -9
  234. package/dist/domains/dam/composables/damConfigName.js.map +1 -1
  235. package/dist/domains/dam/composables/damNotifications.d.ts +9 -9
  236. package/dist/domains/dam/composables/damNotifications.js.map +1 -1
  237. package/dist/domains/dam/composables/damNotificationsConnection.d.ts +4 -4
  238. package/dist/domains/dam/composables/damNotificationsConnection.js.map +1 -1
  239. package/dist/domains/dam/composables/damNotificationsEventBus.d.ts +2 -2
  240. package/dist/domains/dam/composables/damNotificationsEventBus.js.map +1 -1
  241. package/dist/domains/dam/composables/extSystemIdForCached.d.ts +5 -4
  242. package/dist/domains/dam/composables/extSystemIdForCached.js.map +1 -1
  243. package/dist/domains/dam/config/api/damAssetCustomFormApi.js.map +1 -1
  244. package/dist/domains/dam/config/api/damConfigApi.js.map +1 -1
  245. package/dist/domains/dam/config/composables/damConfigState.d.ts +5 -5
  246. package/dist/domains/dam/config/composables/damConfigState.js.map +1 -1
  247. package/dist/domains/dam/config/store/damConfigStore.d.ts +5 -4
  248. package/dist/domains/dam/config/store/damConfigStore.js.map +1 -1
  249. package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.d.ts +3 -1
  250. package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.js.map +1 -1
  251. package/dist/domains/dam/cropper/components/ACropper.js.map +1 -1
  252. package/dist/domains/dam/cropper/components/ACropper.vue.d.ts +8 -16
  253. package/dist/domains/dam/cropper/components/ACropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  254. package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.js.map +1 -1
  255. package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  256. package/dist/domains/dam/cropper/store/imageRoiStore.d.ts +9 -12
  257. package/dist/domains/dam/cropper/store/imageRoiStore.js.map +1 -1
  258. package/dist/domains/dam/cropper/utils/cropperGeometry.d.ts +24 -38
  259. package/dist/domains/dam/cropper/utils/cropperGeometry.js.map +1 -1
  260. package/dist/domains/dam/cropper/utils/cropperJsService.d.ts +3 -7
  261. package/dist/domains/dam/cropper/utils/cropperJsService.js +10 -3
  262. package/dist/domains/dam/cropper/utils/cropperJsService.js.map +1 -1
  263. package/dist/domains/dam/cropper/utils/cropperTypes.d.ts +3 -6
  264. package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.d.ts +5 -5
  265. package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.js.map +1 -1
  266. package/dist/domains/dam/imageWidget/components/AImageMediaWidget.js.map +1 -1
  267. package/dist/domains/dam/imageWidget/components/AImageMediaWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
  268. package/dist/domains/dam/imageWidget/components/AImagePublicInput.js.map +1 -1
  269. package/dist/domains/dam/imageWidget/components/AImagePublicInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  270. package/dist/domains/dam/imageWidget/components/AImageWidget.js.map +1 -1
  271. package/dist/domains/dam/imageWidget/components/AImageWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
  272. package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.js.map +1 -1
  273. package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.vue_vue_type_script_setup_true_lang.js.map +1 -1
  274. package/dist/domains/dam/imageWidget/components/AImageWidgetSimple.vue.d.ts +43 -41
  275. package/dist/domains/dam/imageWidget/components/AMediaWidgetSimple.vue.d.ts +31 -29
  276. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.js.map +1 -1
  277. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue.d.ts +29 -27
  278. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  279. package/dist/domains/dam/imageWidget/components/ImageMassOperations.js.map +1 -1
  280. package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue.d.ts +1 -1
  281. package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
  282. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.js.map +1 -1
  283. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue.d.ts +68 -66
  284. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  285. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.js.map +1 -1
  286. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue.d.ts +402 -400
  287. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  288. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.js.map +1 -1
  289. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue.d.ts +384 -382
  290. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  291. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.js.map +1 -1
  292. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  293. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.js.map +1 -1
  294. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  295. package/dist/domains/dam/imageWidget/components/MediaWidgetSimpleDialog.vue.d.ts +7 -5
  296. package/dist/domains/dam/imageWidget/composables/commonAdminImageOptions.js.map +1 -1
  297. package/dist/domains/dam/imageWidget/composables/imageApiCms.js.map +1 -1
  298. package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.d.ts +11 -13
  299. package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.js.map +1 -1
  300. package/dist/domains/dam/imageWidget/composables/useImageMassOperations.js.map +1 -1
  301. package/dist/domains/dam/imageWidget/store/imageMediaWidgetStore.js.map +1 -1
  302. package/dist/domains/dam/imageWidget/store/imageStore.js.map +1 -1
  303. package/dist/domains/dam/imageWidget/utils/damImage.d.ts +5 -6
  304. package/dist/domains/dam/imageWidget/utils/damImage.js.map +1 -1
  305. package/dist/domains/dam/imageWidget/utils/fieldLockTurns.d.ts +1 -2
  306. package/dist/domains/dam/imageWidget/utils/fieldLockTurns.js.map +1 -1
  307. package/dist/domains/dam/imageWidget/utils/imageSaves.d.ts +10 -14
  308. package/dist/domains/dam/imageWidget/utils/imageSaves.js.map +1 -1
  309. package/dist/domains/dam/imageWidget/utils/metadataToImageMap.js.map +1 -1
  310. package/dist/domains/dam/imageWidget/utils/waitLimit.d.ts +4 -6
  311. package/dist/domains/dam/imageWidget/utils/waitLimit.js.map +1 -1
  312. package/dist/domains/dam/keyword/api/keywordApi.js.map +1 -1
  313. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.js.map +1 -1
  314. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue.d.ts +1 -1
  315. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  316. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.js.map +1 -1
  317. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue.d.ts +8 -5
  318. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  319. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js +1 -1
  320. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js.map +1 -1
  321. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue.d.ts +2 -2
  322. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
  323. package/dist/domains/dam/keyword/composables/cachedKeywords.d.ts +5 -4
  324. package/dist/domains/dam/keyword/composables/cachedKeywords.js.map +1 -1
  325. package/dist/domains/dam/keyword/composables/damKeywordConfig.d.ts +2 -2
  326. package/dist/domains/dam/keyword/composables/damKeywordConfig.js.map +1 -1
  327. package/dist/domains/dam/types/Asset.d.ts +1 -1
  328. package/dist/domains/dam/types/Asset.js.map +1 -1
  329. package/dist/domains/dam/types/UploadQueue.d.ts +5 -4
  330. package/dist/domains/dam/types/UploadQueue.js.map +1 -1
  331. package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.js.map +1 -1
  332. package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
  333. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.js.map +1 -1
  334. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue.d.ts +2 -2
  335. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  336. package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.js.map +1 -1
  337. package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  338. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.js.map +1 -1
  339. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  340. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.js.map +1 -1
  341. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue.d.ts +6 -4
  342. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  343. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.js.map +1 -1
  344. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue.d.ts +1 -1
  345. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  346. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.js.map +1 -1
  347. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  348. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.js.map +1 -1
  349. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue.d.ts +6 -6
  350. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  351. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.js.map +1 -1
  352. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue.d.ts +13 -13
  353. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  354. package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.d.ts +13 -13
  355. package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.js.map +1 -1
  356. package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.d.ts +2 -2
  357. package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.js.map +1 -1
  358. package/dist/domains/dam/uploadQueue/composables/uploadMeter.d.ts +12 -12
  359. package/dist/domains/dam/uploadQueue/composables/uploadMeter.js.map +1 -1
  360. package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.d.ts +5 -5
  361. package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.js.map +1 -1
  362. package/dist/domains/dam/uploadQueue/composables/uploadService.d.ts +2 -3
  363. package/dist/domains/dam/uploadQueue/composables/uploadService.js.map +1 -1
  364. package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.d.ts +5 -4
  365. package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.js.map +1 -1
  366. package/dist/domains/dam/uploadQueue/core/uploadQueueCore.d.ts +3 -2
  367. package/dist/domains/dam/uploadQueue/core/uploadQueueCore.js.map +1 -1
  368. package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.d.ts +8 -5
  369. package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.js.map +1 -1
  370. package/dist/domains/dam/uploadQueue/core/uploadQueueFill.d.ts +3 -3
  371. package/dist/domains/dam/uploadQueue/core/uploadQueueFill.js.map +1 -1
  372. package/dist/domains/dam/uploadQueue/presets/queuePresets.d.ts +8 -5
  373. package/dist/domains/dam/uploadQueue/presets/queuePresets.js.map +1 -1
  374. package/dist/domains/dam/uploadQueue/presets/uploadPresets.d.ts +15 -13
  375. package/dist/domains/dam/uploadQueue/presets/uploadPresets.js.map +1 -1
  376. package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.d.ts +7 -7
  377. package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.js.map +1 -1
  378. package/dist/domains/dam/uploadQueue/settlement/uploadPoller.d.ts +4 -4
  379. package/dist/domains/dam/uploadQueue/settlement/uploadPoller.js.map +1 -1
  380. package/dist/domains/dam/uploadQueue/settlement/uploadSettle.d.ts +28 -30
  381. package/dist/domains/dam/uploadQueue/settlement/uploadSettle.js.map +1 -1
  382. package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.d.ts +2 -2
  383. package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.js.map +1 -1
  384. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.d.ts +2 -2
  385. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.js.map +1 -1
  386. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.d.ts +63 -73
  387. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.js.map +1 -1
  388. package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.d.ts +8 -9
  389. package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.js.map +1 -1
  390. package/dist/domains/dam/user/api/userApi.d.ts +2 -2
  391. package/dist/domains/dam/user/api/userApi.js.map +1 -1
  392. package/dist/domains/dam/user/components/DamDistributionServiceSelect.js.map +1 -1
  393. package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue.d.ts +1 -1
  394. package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  395. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.js.map +1 -1
  396. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue.d.ts +1 -1
  397. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  398. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.js.map +1 -1
  399. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue.d.ts +1 -1
  400. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  401. package/dist/domains/dam/user/composables/damUserSelectActions.d.ts +1 -1
  402. package/dist/domains/dam/user/composables/damUserSelectActions.js.map +1 -1
  403. package/dist/domains/dam/user/types/DamDistributionServiceType.d.ts +2 -2
  404. package/dist/domains/dam/user/types/DamDistributionServiceType.js.map +1 -1
  405. package/dist/domains/dam/user/types/DamExternalProviderAssetType.d.ts +1 -1
  406. package/dist/domains/dam/user/types/DamExternalProviderAssetType.js.map +1 -1
  407. package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.js.map +1 -1
  408. package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  409. package/dist/domains/filters/bookmarks/store/bookmarksStore.d.ts +3 -3
  410. package/dist/domains/filters/bookmarks/store/bookmarksStore.js.map +1 -1
  411. package/dist/domains/filters/components/AFilterDatetimePicker.js.map +1 -1
  412. package/dist/domains/filters/components/AFilterDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  413. package/dist/domains/filters/components/AFilterInteger.js.map +1 -1
  414. package/dist/domains/filters/components/AFilterInteger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  415. package/dist/domains/filters/components/AFilterString.js.map +1 -1
  416. package/dist/domains/filters/components/AFilterString.vue_vue_type_script_setup_true_lang.js.map +1 -1
  417. package/dist/domains/filters/components/AFilterTimeInterval.js +1 -1
  418. package/dist/domains/filters/components/AFilterTimeInterval.js.map +1 -1
  419. package/dist/domains/filters/components/AFilterTimeInterval.vue.d.ts +5 -3
  420. package/dist/domains/filters/components/AFilterTimeInterval.vue_vue_type_script_setup_true_lang.js.map +1 -1
  421. package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.js.map +1 -1
  422. package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  423. package/dist/domains/filters/components/AFilterWrapper.js.map +1 -1
  424. package/dist/domains/filters/components/AFilterWrapper.vue.d.ts +17 -15
  425. package/dist/domains/filters/components/AFilterWrapper.vue_vue_type_script_setup_true_lang.js +63 -62
  426. package/dist/domains/filters/components/AFilterWrapper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  427. package/dist/domains/filters/components/AFilterWrapperSidebar.vue.d.ts +5 -3
  428. package/dist/domains/filters/components/FiltersSelected.js.map +1 -1
  429. package/dist/domains/filters/components/FiltersSelected.vue_vue_type_script_setup_true_lang.js.map +1 -1
  430. package/dist/domains/filters/composables/filterFactory.d.ts +16 -26
  431. package/dist/domains/filters/composables/filterFactory.js +38 -31
  432. package/dist/domains/filters/composables/filterFactory.js.map +1 -1
  433. package/dist/domains/filters/datatable/components/ADatatableOrdering.js.map +1 -1
  434. package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js +3 -1
  435. package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js.map +1 -1
  436. package/dist/domains/filters/datatable/components/ADatatablePagination.js.map +1 -1
  437. package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js +2 -4
  438. package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  439. package/dist/domains/filters/utils/filterInjectionKeys.js.map +1 -1
  440. package/dist/domains/form/components/AFormDatetimePicker.js.map +1 -1
  441. package/dist/domains/form/components/AFormDatetimePicker.vue.d.ts +7 -5
  442. package/dist/domains/form/components/AFormDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  443. package/dist/domains/form/components/AFormFlagDatetimePicker.js.map +1 -1
  444. package/dist/domains/form/components/AFormFlagDatetimePicker.vue.d.ts +7 -5
  445. package/dist/domains/form/components/AFormFlagDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  446. package/dist/domains/form/components/AFormSwitch.vue.d.ts +7 -5
  447. package/dist/domains/form/components/AFormTextField.js.map +1 -1
  448. package/dist/domains/form/components/AFormTextField.vue.d.ts +9 -7
  449. package/dist/domains/form/components/AFormTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  450. package/dist/domains/form/components/AFormTextarea.vue.d.ts +13 -11
  451. package/dist/domains/form/components/AFormValueObjectOptionsSelect.vue.d.ts +7 -5
  452. package/dist/domains/form/components/ASystemEntityScope.vue.d.ts +5 -3
  453. package/dist/domains/job/api/jobApi.js.map +1 -1
  454. package/dist/domains/job/components/AJobDetailCommon.vue.d.ts +5 -3
  455. package/dist/domains/listEditor/components/AListEditor.js.map +1 -1
  456. package/dist/domains/listEditor/components/AListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  457. package/dist/domains/listEditor/components/ANestedSortableListEditor.js.map +1 -1
  458. package/dist/domains/listEditor/components/ANestedSortableListEditor.vue.d.ts +2 -3
  459. package/dist/domains/listEditor/components/ANestedSortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  460. package/dist/domains/listEditor/components/ASortableListEditor.js.map +1 -1
  461. package/dist/domains/listEditor/components/ASortableListEditor.vue.d.ts +2 -3
  462. package/dist/domains/listEditor/components/ASortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  463. package/dist/domains/listEditor/composables/useListEditorController.d.ts +4 -5
  464. package/dist/domains/listEditor/composables/useListEditorController.js.map +1 -1
  465. package/dist/domains/listEditor/composables/useNestedListEditor.d.ts +3 -4
  466. package/dist/domains/listEditor/composables/useNestedListEditor.js.map +1 -1
  467. package/dist/domains/listEditor/composables/useNestedListEditorController.d.ts +5 -4
  468. package/dist/domains/listEditor/composables/useNestedListEditorController.js.map +1 -1
  469. package/dist/domains/listEditor/composables/useReorderMode.js.map +1 -1
  470. package/dist/domains/listEditor/types/listEditorTypes.d.ts +2 -2
  471. package/dist/domains/listEditor/utils/listEditorLoader.d.ts +5 -5
  472. package/dist/domains/listEditor/utils/listEditorLoader.js.map +1 -1
  473. package/dist/domains/listEditor/utils/resolveCompactText.js.map +1 -1
  474. package/dist/domains/log/api/logApi.d.ts +2 -3
  475. package/dist/domains/log/api/logApi.js.map +1 -1
  476. package/dist/domains/log/components/ALogDatatable.js.map +1 -1
  477. package/dist/domains/log/components/ALogDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  478. package/dist/domains/log/components/ALogDetailView.js.map +1 -1
  479. package/dist/domains/log/components/ALogDetailView.vue.d.ts +1 -1
  480. package/dist/domains/log/components/ALogDetailView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  481. package/dist/domains/log/components/ALogFilter.js.map +1 -1
  482. package/dist/domains/log/components/ALogFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  483. package/dist/domains/log/components/ALogListView.js.map +1 -1
  484. package/dist/domains/log/components/ALogListView.vue.d.ts +1 -1
  485. package/dist/domains/log/components/ALogListView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  486. package/dist/domains/log/composables/logActions.d.ts +4 -5
  487. package/dist/domains/log/composables/logActions.js.map +1 -1
  488. package/dist/domains/log/composables/logType.d.ts +6 -7
  489. package/dist/domains/log/composables/logType.js.map +1 -1
  490. package/dist/domains/log/filter/logFilter.d.ts +8 -11
  491. package/dist/domains/log/filter/logFilter.js.map +1 -1
  492. package/dist/domains/permission/components/APermissionEditor.js.map +1 -1
  493. package/dist/domains/permission/components/APermissionEditor.vue.d.ts +4 -4
  494. package/dist/domains/permission/components/APermissionEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  495. package/dist/domains/permission/composables/permissionActions.d.ts +3 -6
  496. package/dist/domains/permission/composables/permissionActions.js.map +1 -1
  497. package/dist/domains/permission/config/api/permissionConfigApi.d.ts +2 -2
  498. package/dist/domains/permission/config/api/permissionConfigApi.js.map +1 -1
  499. package/dist/domains/permission/config/composables/permissionConfigActions.d.ts +3 -7
  500. package/dist/domains/permission/config/composables/permissionConfigActions.js.map +1 -1
  501. package/dist/domains/permission/config/store/permissionConfigStore.d.ts +2 -4
  502. package/dist/domains/permission/config/store/permissionConfigStore.js.map +1 -1
  503. package/dist/domains/permission/group/api/permissionGroupApi.d.ts +8 -10
  504. package/dist/domains/permission/group/api/permissionGroupApi.js.map +1 -1
  505. package/dist/domains/permission/group/components/APermissionGroupDatatable.js.map +1 -1
  506. package/dist/domains/permission/group/components/APermissionGroupDatatable.vue.d.ts +12 -10
  507. package/dist/domains/permission/group/components/APermissionGroupDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  508. package/dist/domains/permission/group/components/APermissionGroupDetail.js.map +1 -1
  509. package/dist/domains/permission/group/components/APermissionGroupDetail.vue.d.ts +21 -22
  510. package/dist/domains/permission/group/components/APermissionGroupDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  511. package/dist/domains/permission/group/components/APermissionGroupManage.js.map +1 -1
  512. package/dist/domains/permission/group/components/APermissionGroupManage.vue.d.ts +21 -22
  513. package/dist/domains/permission/group/components/APermissionGroupManage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  514. package/dist/domains/permission/group/composables/cachedPermissionGroups.js.map +1 -1
  515. package/dist/domains/permission/group/composables/permissionGroupActions.d.ts +6 -8
  516. package/dist/domains/permission/group/composables/permissionGroupActions.js.map +1 -1
  517. package/dist/domains/permission/group/composables/permissionGroupValidations.d.ts +2 -3
  518. package/dist/domains/permission/group/composables/permissionGroupValidations.js.map +1 -1
  519. package/dist/domains/permission/group/filter/permissionGroupFilter.d.ts +2 -3
  520. package/dist/domains/permission/group/filter/permissionGroupFilter.js.map +1 -1
  521. package/dist/domains/permission/group/store/permissionGroupStore.d.ts +3 -6
  522. package/dist/domains/permission/group/store/permissionGroupStore.js.map +1 -1
  523. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.js.map +1 -1
  524. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  525. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.js.map +1 -1
  526. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  527. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.js.map +1 -1
  528. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  529. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue.d.ts +5 -3
  530. package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.d.ts +11 -13
  531. package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.js.map +1 -1
  532. package/dist/domains/subjectSelect/components/AFilterWrapperSubjectSelect.vue.d.ts +13 -11
  533. package/dist/domains/subjectSelect/components/ASubjectSelect.js.map +1 -1
  534. package/dist/domains/subjectSelect/components/ASubjectSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  535. package/dist/domains/subjectSelect/composables/useSubjectSelect.js +53 -51
  536. package/dist/domains/subjectSelect/composables/useSubjectSelect.js.map +1 -1
  537. package/dist/domains/system/appShell/components/AActionbar.vue.d.ts +7 -5
  538. package/dist/domains/system/appShell/components/ALayoutSwitch.js.map +1 -1
  539. package/dist/domains/system/appShell/components/ALayoutSwitch.vue.d.ts +7 -5
  540. package/dist/domains/system/appShell/components/ALayoutSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  541. package/dist/domains/system/appShell/composables/teleportSlot.d.ts +0 -1
  542. package/dist/domains/system/appShell/composables/teleportSlot.js.map +1 -1
  543. package/dist/domains/system/components/AAlerts.js.map +1 -1
  544. package/dist/domains/system/components/AAlerts.vue_vue_type_script_setup_true_lang.js.map +1 -1
  545. package/dist/domains/system/composables/alerts.js.map +1 -1
  546. package/dist/domains/system/composables/breadcrumbs.d.ts +3 -3
  547. package/dist/domains/system/composables/breadcrumbs.js.map +1 -1
  548. package/dist/domains/system/composables/languageSettings.js.map +1 -1
  549. package/dist/domains/system/composables/loginStatus.js.map +1 -1
  550. package/dist/domains/system/composables/navigationError.d.ts +6 -8
  551. package/dist/domains/system/composables/navigationError.js.map +1 -1
  552. package/dist/domains/system/composables/pageNavigation.d.ts +9 -10
  553. package/dist/domains/system/composables/pageNavigation.js.map +1 -1
  554. package/dist/domains/system/composables/recordActions.d.ts +14 -22
  555. package/dist/domains/system/composables/recordActions.js.map +1 -1
  556. package/dist/domains/system/composables/recordPage.d.ts +23 -38
  557. package/dist/domains/system/composables/recordPage.js.map +1 -1
  558. package/dist/domains/system/composables/routeHistory.d.ts +4 -5
  559. package/dist/domains/system/composables/routeHistory.js.map +1 -1
  560. package/dist/domains/system/composables/sentry.js.map +1 -1
  561. package/dist/domains/system/composables/useDebugFeatures.d.ts +3 -6
  562. package/dist/domains/system/composables/useDebugFeatures.js.map +1 -1
  563. package/dist/domains/system/store/datatablePageStore.d.ts +8 -1
  564. package/dist/domains/system/store/datatablePageStore.js +10 -3
  565. package/dist/domains/system/store/datatablePageStore.js.map +1 -1
  566. package/dist/domains/system/systemBar/components/ASystemBar.js.map +1 -1
  567. package/dist/domains/system/systemBar/components/ASystemBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  568. package/dist/domains/system/systemBar/utils/appReload.d.ts +5 -5
  569. package/dist/domains/system/systemBar/utils/appReload.js.map +1 -1
  570. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.js.map +1 -1
  571. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue.d.ts +2 -3
  572. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue_vue_type_script_setup_true_lang.js.map +1 -1
  573. package/dist/domains/ui/buttons/action/components/AActionDeleteButton.js.map +1 -1
  574. package/dist/domains/ui/buttons/action/components/AActionDeleteButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  575. package/dist/domains/ui/buttons/components/ABtnSplit.vue.d.ts +9 -7
  576. package/dist/domains/ui/components/AAvatarColorPicker.js.map +1 -1
  577. package/dist/domains/ui/components/AAvatarColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  578. package/dist/domains/ui/components/ACard.js.map +1 -1
  579. package/dist/domains/ui/components/ACard.vue.d.ts +7 -3
  580. package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js +6 -2
  581. package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  582. package/dist/domains/ui/components/ACardLoader.js.map +1 -1
  583. package/dist/domains/ui/components/ACardLoader.vue.d.ts +1 -0
  584. package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js +13 -7
  585. package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  586. package/dist/domains/ui/components/AChipNoLink.vue.d.ts +5 -3
  587. package/dist/domains/ui/components/ACopyText.vue.d.ts +9 -7
  588. package/dist/domains/ui/components/ACreateDialog.js.map +1 -1
  589. package/dist/domains/ui/components/ACreateDialog.vue.d.ts +11 -9
  590. package/dist/domains/ui/components/ACreateDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  591. package/dist/domains/ui/components/ADialogToolbar.vue.d.ts +5 -3
  592. package/dist/domains/ui/components/ARow.vue.d.ts +5 -3
  593. package/dist/domains/ui/components/ATimeTrackingFields.js.map +1 -1
  594. package/dist/domains/ui/components/ATimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
  595. package/dist/domains/ui/components/AUserAndTimeTrackingFields.js.map +1 -1
  596. package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue.d.ts +3 -5
  597. package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
  598. package/dist/domains/ui/datetime/components/ADatetimePicker.js +1 -1
  599. package/dist/domains/ui/datetime/components/ADatetimePicker.js.map +1 -1
  600. package/dist/domains/ui/datetime/components/ADatetimePicker.vue.d.ts +5 -3
  601. package/dist/domains/ui/datetime/components/ADatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  602. package/dist/domains/ui/file/components/AFileDropzone.js.map +1 -1
  603. package/dist/domains/ui/file/components/AFileDropzone.vue.d.ts +1 -1
  604. package/dist/domains/ui/file/components/AFileDropzone.vue_vue_type_script_setup_true_lang.js.map +1 -1
  605. package/dist/domains/ui/file/components/AFileInput.js.map +1 -1
  606. package/dist/domains/ui/file/components/AFileInput.vue.d.ts +9 -7
  607. package/dist/domains/ui/file/components/AFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  608. package/dist/domains/ui/file/components/AFileInputDialog.js.map +1 -1
  609. package/dist/domains/ui/file/components/AFileInputDialog.vue.d.ts +9 -7
  610. package/dist/domains/ui/file/components/AFileInputDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  611. package/dist/domains/ui/file/composables/dropzone.js.map +1 -1
  612. package/dist/domains/ui/file/composables/formatAndSizeCheck.js.map +1 -1
  613. package/dist/domains/ui/view/components/AGenericView.vue.d.ts +7 -5
  614. package/dist/domains/ui/view/components/ALoginView.js +1 -1
  615. package/dist/domains/ui/view/components/ALoginView.js.map +1 -1
  616. package/dist/domains/ui/view/components/ALoginView.vue.d.ts +5 -3
  617. package/dist/domains/ui/view/components/ALoginView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  618. package/dist/domains/ui/view/components/ALogoutView.js.map +1 -1
  619. package/dist/domains/ui/view/components/ALogoutView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  620. package/dist/domains/ui/view/components/ANotFoundView.js.map +1 -1
  621. package/dist/domains/ui/view/components/ANotFoundView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  622. package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.d.ts +6 -7
  623. package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.js.map +1 -1
  624. package/dist/lib.d.ts +2 -2
  625. package/dist/plugins/commonVuetifyConfig.d.ts +3 -3
  626. package/dist/plugins/commonVuetifyConfig.js.map +1 -1
  627. package/dist/plugins/i18n.d.ts +4 -5
  628. package/dist/plugins/i18n.js.map +1 -1
  629. package/dist/plugins/pluginOptions.d.ts +4 -2
  630. package/dist/plugins/pluginOptions.js.map +1 -1
  631. package/dist/plugins/webfontloader.js.map +1 -1
  632. package/dist/shared/error/AnzuApiCancelledError.d.ts +5 -8
  633. package/dist/shared/error/AnzuApiCancelledError.js.map +1 -1
  634. package/dist/shared/error/AnzuError.d.ts +3 -5
  635. package/dist/shared/error/AnzuError.js.map +1 -1
  636. package/dist/shared/error/AuthUnavailableError.d.ts +3 -3
  637. package/dist/shared/error/AuthUnavailableError.js.map +1 -1
  638. package/dist/shared/error/isInCauseChain.d.ts +2 -2
  639. package/dist/shared/error/isInCauseChain.js.map +1 -1
  640. package/dist/shared/types/UserAndTimeTracking.d.ts +5 -5
  641. package/dist/shared/types/Validation.d.ts +4 -5
  642. package/dist/shared/types/common.d.ts +1 -3
  643. package/dist/shared/types/globalComponents.d.ts +5 -6
  644. package/dist/shared/utils/common.js.map +1 -1
  645. package/dist/shared/utils/datetime.d.ts +0 -1
  646. package/dist/shared/utils/datetime.js.map +1 -1
  647. package/dist/shared/utils/datetimePickerValue.d.ts +4 -7
  648. package/dist/shared/utils/datetimePickerValue.js.map +1 -1
  649. package/dist/shared/utils/development.d.ts +3 -3
  650. package/dist/shared/utils/development.js.map +1 -1
  651. package/dist/shared/utils/envConfig.d.ts +4 -4
  652. package/dist/shared/utils/envConfig.js.map +1 -1
  653. package/dist/shared/utils/json.d.ts +1 -1
  654. package/dist/shared/utils/json.js.map +1 -1
  655. package/dist/shared/utils/userAndTimeTracking.d.ts +5 -7
  656. package/dist/shared/utils/userAndTimeTracking.js.map +1 -1
  657. package/dist/shared/validators/vuelidate/common/useValidateHexColor.d.ts +3 -5
  658. package/dist/shared/validators/vuelidate/common/useValidateHexColor.js.map +1 -1
  659. package/dist/testing/appShell.d.ts +11 -11
  660. package/dist/testing/appShell.js.map +1 -1
  661. package/dist/testing/closeButtons.d.ts +9 -11
  662. package/dist/testing/closeButtons.js.map +1 -1
  663. package/dist/testing/declaredDependencies.d.ts +7 -7
  664. package/dist/testing/declaredDependencies.js.map +1 -1
  665. package/dist/testing/generatedRoutes.d.ts +6 -11
  666. package/dist/testing/generatedRoutes.js.map +1 -1
  667. package/dist/testing/routeHistory.d.ts +5 -12
  668. package/dist/testing/routeHistory.js.map +1 -1
  669. package/dist/testing/sortableLists.d.ts +16 -21
  670. package/dist/testing/sortableLists.js.map +1 -1
  671. package/dist/testing/typedRouter.d.ts +0 -1
  672. package/dist/testing/typedRouter.js.map +1 -1
  673. package/package.json +39 -29
  674. package/src/e2e/conventions.d.mts +4 -0
  675. package/src/e2e/conventions.mjs +15 -0
  676. package/src/e2e/index.d.mts +8 -0
  677. package/src/e2e/index.mjs +1 -0
  678. package/src/e2e/routeWalk.d.mts +43 -0
  679. package/src/e2e/routeWalk.mjs +606 -0
  680. package/src/e2e/types.d.mts +161 -0
  681. package/src/eslint/adminConfig.mjs +19 -27
  682. package/src/eslint/globalComponentNames.mjs +3 -4
  683. package/src/eslint/oxlint.mjs +7 -20
  684. package/src/eslint/plugin.d.mts +2 -4
  685. package/src/eslint/plugin.mjs +18 -34
  686. package/src/eslint/validRouteName.mjs +6 -7
  687. package/src/vite/devWatch.mjs +30 -43
  688. package/src/vite/index.d.mts +5 -5
  689. package/src/vite/sentry.mjs +7 -12
  690. package/src/vite/sourcemaps.mjs +4 -8
@@ -1 +1 @@
1
- {"version":3,"file":"useApiFetchItems.js","names":["useApiFetchItems","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","fetchParams","url","dispatched","res","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","sendsBody","isNull","body","method","resolvedParams","urlParams","requestUrl","replaceUrlParameters","config","ownedByHelper","options","abortSignal","instance","client","signal","asSent","requestedUrl","isValidHTTPStatus","AnzuApiResponseCodeError","hasBody","shape","readArrayBody","readListBody","err","context","report","mapApiError"],"sources":["../../../../src/domains/api/composables/useApiFetchItems.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport type { Ref } from 'vue'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readArrayBody, readListBody } from '@/domains/api/utils/listBody'\n\n/** Which of the two shapes a list arrives in. */\nexport type ItemsShape = 'envelope' | 'array'\n\nexport type UseApiFetchItemsParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n /**\n * The url, query and all: whatever built the query has already run by the time it gets here.\n *\n * `urlParams` are substituted into the PATH only -- `/article/:id/routes?locale=:locale` fills in\n * `:id` and sends `:locale` as it stands. This is the helper written for hand-made queries, so it\n * is the one place someone would reach for a placeholder in the query; put the value in the query\n * when building it, or pass it through `options.params` and let axios serialise it.\n */\n urlTemplate?: string\n urlParams?: UrlParams\n /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n /**\n * Default `GET`, which is what 17 of the fleet's list reads and every existing caller here use.\n *\n * The others are here because a list is not only ever the answer to a read: a filter too big for a\n * url goes out as a POST, and a mutation can answer with the list it just changed -- a swap, a\n * shift, an upsert-all. What this helper is about is the answer, not the verb.\n */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH'\n /**\n * Default `'envelope'`, because that is the fleet's norm and the exception is what gets declared.\n *\n * Leaving it out cannot go wrong quietly: the reader refuses the shape that was not declared, so a\n * forgotten `'array'` fails on the first run rather than handing back something that is not a list.\n */\n shape?: ItemsShape\n}\n\nexport type FetchItemsParams<B = never> = {\n urlTemplate?: string\n urlParams?: UrlParams\n /** `null` omits the body, as everywhere in this family. */\n body?: B\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n}\n\n/**\n * A list from an endpoint the caller has already written the query for, with no pagination.\n *\n * It exists because the fleet kept doing this through `useApiRequest<ApiResponseList<T[]>>`: build a\n * query by hand -- an order, a limit, a fixed filter -- bake it into the url, and read `.data` off\n * the envelope that comes back. That is a list fetch with the list part missing: nothing checks that\n * `data` is an array, so a malformed answer still hands back `undefined` typed as `T[]`, which is\n * the bug this whole family was built to end.\n *\n * `useApiFetchList` cannot serve them: it asks for a pagination ref, a `filterData` and a\n * `filterConfig`, and these calls have none -- their filters are decided at the call site and are\n * not the user's to change. So this is that helper with the pagination taken out: same core, same\n * error mapping, same list-body check, and it answers with the items rather than the envelope.\n *\n * Read is the usual case, not the only one: a filter too big for a url goes out as a POST, and a\n * mutation can answer with the list it just changed. The helper is about what comes back.\n *\n * Which shape it comes back in is declared, not guessed. `shape` picks the reader and the reader\n * refuses the other shape, the way `optionalBody` makes a caller declare a body instead of leaving\n * the helper to accept whatever turns up. A wrong declaration therefore fails loudly on the first\n * run, which is what makes having a default safe at all.\n *\n * It writes no metadata. An endpoint whose paging the user drives is `useApiFetchList`; a list read\n * page by page to the end is `useApiFetchListBatch`.\n */\nexport const useApiFetchItems = <T, B = never>(params: UseApiFetchItemsParams): UseApiFetchItemsReturnType<T, B> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n method = 'GET',\n shape = 'envelope',\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (fetchParams: FetchItemsParams<B> = {}): Promise<T[]> => {\n const { urlTemplate: urlTemplateOverride, urlParams: urlParamsOverride, body, signal } = fetchParams\n\n // Assigned inside `run`, at the moment there is a url to ask for; undefined until then, which is\n // what a failure before dispatch honestly reports.\n let url: string | undefined\n let dispatched: AxiosRequestConfig | undefined\n\n try {\n const res = await abortable.run((abortSignal) => {\n // Derived inside `run`, the way the rest of the family does it: `run` opens the generation\n // and, with `cancelPrevious`, stops the call before this one.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n // `null` omits the body, as it always has -- a caller that means to send JSON `null` wraps it.\n const sendsBody = !isNull(body) && !isUndefined(body)\n\n // Because `method` defaults to GET: a caller who wrote a body and forgot `method: 'POST'`\n // would otherwise send a GET without its filter, and nothing downstream would notice.\n if (method === 'GET' && sendsBody) {\n throw new AnzuFatalError(\n undefined,\n 'A GET request does not carry a body -- set method, or pass the value through options.params'\n )\n }\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const requestUrl = isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)\n\n // `options` first, then what this helper owns: a caller cannot reach in and set the method,\n // the url, the body or the signal through it.\n const config: AxiosRequestConfig = {\n ...ownedByHelper(options),\n method,\n url: requestUrl,\n signal: abortSignal,\n }\n if (sendsBody) config.data = JSON.stringify(body)\n\n const instance = client()\n\n // Recorded last, when nothing between here and the call can throw any more. It used to sit\n // safely above the dispatch because nothing here could fail; `JSON.stringify` can -- a\n // circular body would otherwise be reported as a request to a url nobody ever called.\n url = requestUrl\n\n return instance.request(config)\n }, signal)\n\n dispatched = res.config\n // The url the report will name, so a message and the context beside it cannot disagree about\n // which request failed when an interceptor rewrote it on the way out.\n const asSent = () => requestedUrl(client, url, options, undefined, dispatched)\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // Nothing matched -- an empty answer, not a broken one.\n if (res.status === HTTP_STATUS_NO_CONTENT) return []\n\n if (!hasBody(res)) {\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + asSent())\n }\n\n return shape === 'array'\n ? readArrayBody<T>(res.data, res.status, asSent())\n : readListBody<T>(res.data, res.status, asSent()).items\n } catch (err: unknown) {\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n throw report(mapApiError(err, context), context)\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchItemsReturnType<T, B = never> = {\n execute: (params?: FetchItemsParams<B>) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance has a request in flight, false once the last one settles.\n *\n * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in\n * a `finally`, and that `finally` belongs to whichever call ended -- including one that\n * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting\n * for is still running. This one never dips between a superseded call and the one that replaced it.\n *\n * Two things to know before replacing a hand-rolled flag with it.\n *\n * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a\n * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it\n * for this one turns the spinner off too early. Keep your own where it means more than \"this helper\n * is working\".\n *\n * It belongs to the instance, so it is only reachable if you hold the instance. A factory that\n * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the\n * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the\n * instance to where the caller lives first.\n */\n loading: Ref<boolean>\n}\n"],"mappings":";;;;;;;;;;AAuFA,IAAaA,KAAkC,MAAqE;CAClH,IAAM,EACJ,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,IACjB,YAAS,OACT,WAAQ,eACNC,GACEC,IAAYC,EAAgB,EAAE,kBAAe,CAAC;CAiFpD,OAAO;EAAE,gBA/Ec,IAAmC,CAAC,MAAoB;GAC7E,IAAM,EAAE,aAAaC,GAAqB,WAAWC,GAAmB,SAAM,cAAWC,GAIrFC,GACAC;GAEJ,IAAI;IACF,IAAMC,IAAM,MAAMP,EAAU,KAAK,MAAgB;KAG/C,IAAMQ,IAAWC,EAAUP,CAAmB,IAAIA,IAAsBQ;KACxE,IAAIC,EAAYH,CAAQ,GAAG,MAAM,IAAII,EAAe,KAAA,GAAW,2BAA2B;KAG1F,IAAMC,IAAY,CAACC,EAAOC,CAAI,KAAK,CAACJ,EAAYI,CAAI;KAIpD,IAAIC,MAAW,SAASH,GACtB,MAAM,IAAID,EACR,KAAA,GACA,6FACF;KAGF,IAAMK,IAAiBR,EAAUN,CAAiB,IAAIA,IAAoBe,GACpEC,IAAaR,EAAYM,CAAc,IAAIT,IAAWY,EAAqBZ,GAAUS,CAAc,GAInGI,IAA6B;MACjC,GAAGC,EAAcC,CAAO;MACxB;MACA,KAAKJ;MACL,QAAQK;KACV;KACA,AAAIX,MAAW,EAAO,OAAO,KAAK,UAAUE,CAAI;KAEhD,IAAMU,IAAWC,EAAO;KAOxB,OAFA,IAAMP,GAECM,EAAS,QAAQJ,CAAM;IAChC,GAAGM,CAAM;IAET,IAAapB,EAAI;IAGjB,IAAMqB,UAAeC,EAAaH,GAAQrB,GAAKkB,GAAS,KAAA,GAAWjB,CAAU;IAC7E,IAAI,CAACwB,EAAkBvB,EAAI,MAAM,GAAG,MAAM,IAAIwB,EAAyBxB,EAAI,MAAM;IAGjF,IAAIA,EAAI,WAAA,KAAmC,OAAO,CAAC;IAEnD,IAAI,CAACyB,EAAQzB,CAAG,GACd,MAAM,IAAIwB,EAAyBxB,EAAI,QAAQ,KAAA,GAAW,oCAAoCqB,EAAO,CAAC;IAGxG,OAAOK,MAAU,UACbC,EAAiB3B,EAAI,MAAMA,EAAI,QAAQqB,EAAO,CAAC,IAC/CO,EAAgB5B,EAAI,MAAMA,EAAI,QAAQqB,EAAO,CAAC,CAAC,CAAC;GACtD,SAASQ,GAAc;IACrB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKR,EAAaH,GAAQrB,GAAKkB,GAASa,GAAK9B,CAAU;IACzD;IAEA,MAAMgC,EAAOC,EAAYH,GAAKC,CAAO,GAAGA,CAAO;GACjD;EACF;EAEkB,OAAOrC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE"}
1
+ {"version":3,"file":"useApiFetchItems.js","names":["useApiFetchItems","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","fetchParams","url","dispatched","res","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","sendsBody","isNull","body","method","resolvedParams","urlParams","requestUrl","replaceUrlParameters","config","ownedByHelper","options","abortSignal","instance","client","signal","asSent","requestedUrl","isValidHTTPStatus","AnzuApiResponseCodeError","hasBody","shape","readArrayBody","readListBody","err","context","report","mapApiError"],"sources":["../../../../src/domains/api/composables/useApiFetchItems.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport type { Ref } from 'vue'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readArrayBody, readListBody } from '@/domains/api/utils/listBody'\n\n/** Which of the two shapes a list arrives in. */\nexport type ItemsShape = 'envelope' | 'array'\n\nexport type UseApiFetchItemsParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n /**\n * The full url including the query, already built by the caller.\n * `urlParams` are substituted into the path only. A placeholder in the query\n * is sent as is. Put the value in the query or pass it via `options.params`.\n */\n urlTemplate?: string\n urlParams?: UrlParams\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n /**\n * Defaults to `GET`.\n * Other verbs exist because a filter too big for a url goes out\n * as a POST, and a mutation can answer with the changed list.\n */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH'\n /**\n * Defaults to `'envelope'`, the fleet norm.\n * The reader refuses an undeclared shape, so a forgotten `'array'` fails on the first run.\n */\n shape?: ItemsShape\n}\n\nexport type FetchItemsParams<B = never> = {\n urlTemplate?: string\n urlParams?: UrlParams\n /** `null` omits the body, as everywhere in this family. */\n body?: B\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n}\n\n/**\n * Fetches a list from an endpoint whose query the caller already built, without pagination.\n * Replaces `useApiRequest<ApiResponseList<T[]>>` reads, which never checked that `data`\n * is an array. `useApiFetchList` needs pagination and filter config these calls lack.\n * `shape` is declared, and the reader refuses the other shape, so a wrong declaration fails loudly.\n * Writes no metadata. Use `useApiFetchList` for user-driven paging and `useApiFetchListBatch` to read all pages.\n */\nexport const useApiFetchItems = <T, B = never>(params: UseApiFetchItemsParams): UseApiFetchItemsReturnType<T, B> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n method = 'GET',\n shape = 'envelope',\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (fetchParams: FetchItemsParams<B> = {}): Promise<T[]> => {\n const { urlTemplate: urlTemplateOverride, urlParams: urlParamsOverride, body, signal } = fetchParams\n\n // Assigned inside `run` once a url exists. It stays undefined\n // before that, so a failure before dispatch reports no url.\n let url: string | undefined\n let dispatched: AxiosRequestConfig | undefined\n\n try {\n const res = await abortable.run((abortSignal) => {\n // Derived inside `run` because `run` opens the generation and, with `cancelPrevious`, stops the previous call.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n // `null` omits the body. To send JSON `null`, the caller wraps it.\n const sendsBody = !isNull(body) && !isUndefined(body)\n\n // `method` defaults to GET, so a body without `method: 'POST'` would silently send a GET without its filter.\n if (method === 'GET' && sendsBody) {\n throw new AnzuFatalError(\n undefined,\n 'A GET request does not carry a body -- set method, or pass the value through options.params'\n )\n }\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const requestUrl = isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)\n\n // `options` first, then the helper-owned keys, so a caller cannot override method, url, body or signal.\n const config: AxiosRequestConfig = {\n ...ownedByHelper(options),\n method,\n url: requestUrl,\n signal: abortSignal,\n }\n if (sendsBody) config.data = JSON.stringify(body)\n\n const instance = client()\n\n // Recorded last, after anything that can throw. `JSON.stringify` fails on a circular\n // body, which would otherwise be reported as a request to a url never called.\n url = requestUrl\n\n return instance.request(config)\n }, signal)\n\n dispatched = res.config\n // The url the report names, so the message and context agree when an interceptor rewrote the request.\n const asSent = () => requestedUrl(client, url, options, undefined, dispatched)\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // Nothing matched -- an empty answer, not a broken one.\n if (res.status === HTTP_STATUS_NO_CONTENT) return []\n\n if (!hasBody(res)) {\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + asSent())\n }\n\n return shape === 'array'\n ? readArrayBody<T>(res.data, res.status, asSent())\n : readListBody<T>(res.data, res.status, asSent()).items\n } catch (err: unknown) {\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n throw report(mapApiError(err, context), context)\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchItemsReturnType<T, B = never> = {\n execute: (params?: FetchItemsParams<B>) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance has a request in flight. Unlike a caller-cleared\n * `finally` flag, it does not dip when `cancelPrevious` supersedes a call.\n * It covers only this helper's work. Keep your own flag if it also spans follow-up fetches or mapping.\n * It belongs to the instance. A factory that builds one per call cannot\n * expose `loading`, `abort` or `cancelPrevious`, so hoist the instance first.\n */\n loading: Ref<boolean>\n}\n"],"mappings":";;;;;;;;;;AA6DA,IAAaA,KAAkC,MAAqE;CAClH,IAAM,EACJ,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,IACjB,YAAS,OACT,WAAQ,eACNC,GACEC,IAAYC,EAAgB,EAAE,kBAAe,CAAC;CA4EpD,OAAO;EAAE,gBA1Ec,IAAmC,CAAC,MAAoB;GAC7E,IAAM,EAAE,aAAaC,GAAqB,WAAWC,GAAmB,SAAM,cAAWC,GAIrFC,GACAC;GAEJ,IAAI;IACF,IAAMC,IAAM,MAAMP,EAAU,KAAK,MAAgB;KAE/C,IAAMQ,IAAWC,EAAUP,CAAmB,IAAIA,IAAsBQ;KACxE,IAAIC,EAAYH,CAAQ,GAAG,MAAM,IAAII,EAAe,KAAA,GAAW,2BAA2B;KAG1F,IAAMC,IAAY,CAACC,EAAOC,CAAI,KAAK,CAACJ,EAAYI,CAAI;KAGpD,IAAIC,MAAW,SAASH,GACtB,MAAM,IAAID,EACR,KAAA,GACA,6FACF;KAGF,IAAMK,IAAiBR,EAAUN,CAAiB,IAAIA,IAAoBe,GACpEC,IAAaR,EAAYM,CAAc,IAAIT,IAAWY,EAAqBZ,GAAUS,CAAc,GAGnGI,IAA6B;MACjC,GAAGC,EAAcC,CAAO;MACxB;MACA,KAAKJ;MACL,QAAQK;KACV;KACA,AAAIX,MAAW,EAAO,OAAO,KAAK,UAAUE,CAAI;KAEhD,IAAMU,IAAWC,EAAO;KAMxB,OAFA,IAAMP,GAECM,EAAS,QAAQJ,CAAM;IAChC,GAAGM,CAAM;IAET,IAAapB,EAAI;IAEjB,IAAMqB,UAAeC,EAAaH,GAAQrB,GAAKkB,GAAS,KAAA,GAAWjB,CAAU;IAC7E,IAAI,CAACwB,EAAkBvB,EAAI,MAAM,GAAG,MAAM,IAAIwB,EAAyBxB,EAAI,MAAM;IAGjF,IAAIA,EAAI,WAAA,KAAmC,OAAO,CAAC;IAEnD,IAAI,CAACyB,EAAQzB,CAAG,GACd,MAAM,IAAIwB,EAAyBxB,EAAI,QAAQ,KAAA,GAAW,oCAAoCqB,EAAO,CAAC;IAGxG,OAAOK,MAAU,UACbC,EAAiB3B,EAAI,MAAMA,EAAI,QAAQqB,EAAO,CAAC,IAC/CO,EAAgB5B,EAAI,MAAMA,EAAI,QAAQqB,EAAO,CAAC,CAAC,CAAC;GACtD,SAASQ,GAAc;IACrB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKR,EAAaH,GAAQrB,GAAKkB,GAASa,GAAK9B,CAAU;IACzD;IAEA,MAAMgC,EAAOC,EAAYH,GAAKC,CAAO,GAAGA,CAAO;GACjD;EACF;EAEkB,OAAOrC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE"}
@@ -13,7 +13,6 @@ export type UseApiFetchListParams = {
13
13
  validationEntity?: string;
14
14
  urlTemplate?: string;
15
15
  urlParams?: UrlParams;
16
- /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */
17
16
  options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>;
18
17
  cancelPrevious?: boolean;
19
18
  };
@@ -24,10 +23,8 @@ export type FetchListParams = {
24
23
  /** Stops this one call, leaving the instance's other calls alone. */
25
24
  signal?: AbortSignal;
26
25
  /**
27
- * `false`: a failure of this one call is thrown as ever, and not handed to the api error logger.
28
- *
29
- * As in `useApiRequest`: for a caller that reads a list again on a timer and has reported its first failure
30
- * already. It is the caller's to say which call that is, call by call; an instance has no such switch.
26
+ * `false`: a failure of this call is still thrown but not sent to the api error logger.
27
+ * For a caller that polls a list and has already reported its first failure. It is set per call, not per instance.
31
28
  */
32
29
  report?: boolean;
33
30
  };
@@ -37,24 +34,11 @@ export type UseApiFetchListReturnType<T> = {
37
34
  execute: (pagination: Ref<Pagination>, filterData: FilterData<any>, filterConfig: FilterConfig<any>, params?: FetchListParams) => Promise<T[]>;
38
35
  abort: () => void;
39
36
  /**
40
- * True while this instance has a request in flight, false once the last one settles.
41
- *
42
- * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in
43
- * a `finally`, and that `finally` belongs to whichever call ended -- including one that
44
- * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting
45
- * for is still running. This one never dips between a superseded call and the one that replaced it.
46
- *
47
- * Two things to know before replacing a hand-rolled flag with it.
48
- *
49
- * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a
50
- * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it
51
- * for this one turns the spinner off too early. Keep your own where it means more than "this helper
52
- * is working".
53
- *
54
- * It belongs to the instance, so it is only reachable if you hold the instance. A factory that
55
- * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the
56
- * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the
57
- * instance to where the caller lives first.
37
+ * True while this instance has a request in flight. Unlike a caller-cleared
38
+ * `finally` flag, it does not dip when `cancelPrevious` supersedes a call.
39
+ * It covers only this helper's work. Keep your own flag if it also spans follow-up fetches or mapping.
40
+ * It belongs to the instance. A factory that builds one per call cannot
41
+ * expose `loading`, `abort` or `cancelPrevious`, so hoist the instance first.
58
42
  */
59
43
  loading: Ref<boolean>;
60
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useApiFetchList.js","names":["generateListQuery","useApiQueryBuilder","querySetLimit","pagination","querySetOffset","querySetOrder","SortOrder","querySetFilters","filterData","filterConfig","queryBuild","useApiFetchList","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","reported","fetchParams","url","dispatched","generation","ownSignal","writePagination","signal","next","res","currentGeneration","abortSignal","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","resolvedParams","urlParams","searchApi","forceElastic","requestUrl","replaceUrlParameters","instance","client","ownedByHelper","options","asSent","requestedUrl","isValidHTTPStatus","AnzuApiResponseCodeError","isNull","hasBody","list","readListBody","err","context","error","mapApiError","report"],"sources":["../../../../src/domains/api/composables/useApiFetchList.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig } from 'axios'\nimport { useApiQueryBuilder } from '@/domains/api/composables/useApiQueryBuilder'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { FilterConfig, FilterData } from '@/domains/filters/composables/filterFactory'\nimport type { Ref } from 'vue'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport type { Pagination } from '@/domains/api/composables/pagination'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readListBody } from '@/domains/api/utils/listBody'\n\nexport type UseApiFetchListParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n}\n\nexport type FetchListParams = {\n urlTemplate?: string\n urlParams?: UrlParams\n forceElastic?: boolean\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n /**\n * `false`: a failure of this one call is thrown as ever, and not handed to the api error logger.\n *\n * As in `useApiRequest`: for a caller that reads a list again on a timer and has reported its first failure\n * already. It is the caller's to say which call that is, call by call; an instance has no such switch.\n */\n report?: boolean\n}\n\nexport const generateListQuery = (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>\n): string => {\n const { querySetLimit, querySetOffset, querySetOrder, queryBuild, querySetFilters } = useApiQueryBuilder()\n querySetLimit(pagination.value.rowsPerPage)\n querySetOffset(pagination.value.page, pagination.value.rowsPerPage)\n if (pagination.value.sortBy) {\n querySetOrder(pagination.value.sortBy.key, pagination.value.sortBy.order === SortOrder.Desc)\n }\n querySetFilters(filterData, filterConfig)\n return queryBuild()\n}\n\nexport const useApiFetchList = <T>(params: UseApiFetchListParams): UseApiFetchListReturnType<T> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n fetchParams: FetchListParams = {}\n ): Promise<T[]> => {\n const {\n urlTemplate: urlTemplateOverride,\n urlParams: urlParamsOverride,\n forceElastic = false,\n signal,\n report: reported = true,\n } = fetchParams\n\n // Assigned inside `run`, once, at the moment there is a url to ask for. It stays undefined until\n // then, and that is what a failure before dispatch reports: the field says which url was\n // requested, and a call that never reached the wire requested none. Neither the client root nor\n // the path it was going to build is an answer to that question.\n let url: string | undefined\n // The config axios used, kept for the failures this helper raises after reading the response:\n // they carry no config of their own, and rebuilding one describes the request as the client\n // would send it now rather than as it was sent.\n let dispatched: AxiosRequestConfig | undefined\n\n // Handed over by `run`, not read before it: `run` is what opens a new generation, so a value\n // taken beforehand belongs to the previous call and would never match.\n let generation = 0\n let ownSignal: AbortSignal | undefined\n const writePagination = (next: Partial<Pagination>) => {\n // Two ways to stop being the call whose answer counts, and both have to be checked: a newer\n // call opened a generation, or this one was cancelled through a signal of its own. Aborting\n // does not stop a response already on its way, so either can still arrive and write.\n //\n // The generation belongs to the instance, not to this `pagination` ref, so one instance serves\n // one list. Two concurrent calls on a shared instance writing to different refs would leave\n // the older ref unwritten -- correct for the same list shown twice, wrong for two lists.\n if (abortable.generation() !== generation) return\n if (ownSignal?.aborted === true) return\n // The caller's own signal, read directly rather than through the relay `run` set up for it.\n // `run` drops that relay as soon as the response is in hand, and the write happens after --\n // so an abort landing in between leaves `ownSignal` untouched, and the call the caller just\n // stopped would go on to write the pagination. This is the only state the family writes\n // outside `run`, so it is the only place the gap exists.\n if (signal?.aborted === true) return\n pagination.value = { ...pagination.value, ...next }\n }\n\n try {\n const res = await abortable.run((abortSignal, currentGeneration) => {\n generation = currentGeneration\n ownSignal = abortSignal\n\n // The whole url is derived here, inside `run`, and that is the point of putting it here:\n // `run` is what opens a new generation and, with `cancelPrevious`, stops the call before\n // this one. Anything done ahead of it belongs to no generation yet, so a missing template or\n // a malformed filter config -- both of which throw while the url is being built -- would\n // leave the previous call current, and its answer, arriving afterwards, would write\n // pagination for a query the caller has already replaced. It also keeps all of it inside the\n // try, so the caller gets the same error class as for every other failure rather than a bare\n // `Error` nothing in the fleet is written to catch.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const searchApi = filterConfig.general.elastic || forceElastic ? '/search' : ''\n const baseUrl =\n (isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)) + searchApi\n const requestUrl = baseUrl + generateListQuery(pagination, filterData, filterConfig)\n const instance = client()\n\n // Recorded last, when nothing between here and the call can throw any more: a client factory\n // that fails is a request that never happened, and the report says so by naming no url.\n url = requestUrl\n\n return instance.get(requestUrl, { ...ownedByHelper(options), signal: abortSignal })\n }, signal)\n\n dispatched = res.config\n // The url the report will name, so a message and the context beside it cannot disagree about\n // which request failed when an interceptor rewrote it on the way out.\n const asSent = () => requestedUrl(client, url, options, undefined, dispatched)\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // 204 is an empty list, and the metadata has to say so -- left alone it keeps answering for\n // the previous query.\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n // A 204 says the list is empty; it says nothing about which kind of list it is. So the mode\n // the pagination is already in decides which field gets cleared: a counted list keeps\n // `null`, and an infinite one keeps a boolean and gets `false` -- which is what it means,\n // \"there is nothing after this\". Writing `null` for both put an infinite list into counted\n // mode, where `ASubjectSelect` reads a next page as available and its autoload fires again\n // on the same 204, and `ADatatablePagination` offers Next and Last on an empty page.\n const stillCounted = isNull(pagination.value.hasNextPage)\n writePagination({ totalCount: 0, hasNextPage: stillCounted ? null : false, currentViewCount: 0 })\n return []\n }\n\n if (!hasBody(res)) {\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + asSent())\n }\n\n const list = readListBody<T>(res.data, res.status, asSent())\n // Only when the response said something about paging at all: a body that named no mode has\n // said nothing to write, and a count of what just arrived would be the one field left\n // describing a query nobody asked about.\n if (list.mode !== 'unknown') writePagination({ ...list.pagination, currentViewCount: list.items.length })\n\n return list.items\n } catch (err: unknown) {\n // Built once and handed to both, the way the batch does it: half the work on the failure path,\n // and one place that could go wrong instead of two.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n const error = mapApiError(err, context)\n\n throw reported ? report(error, context) : error\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchListReturnType<T> = {\n execute: (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n params?: FetchListParams\n ) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance has a request in flight, false once the last one settles.\n *\n * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in\n * a `finally`, and that `finally` belongs to whichever call ended -- including one that\n * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting\n * for is still running. This one never dips between a superseded call and the one that replaced it.\n *\n * Two things to know before replacing a hand-rolled flag with it.\n *\n * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a\n * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it\n * for this one turns the spinner off too early. Keep your own where it means more than \"this helper\n * is working\".\n *\n * It belongs to the instance, so it is only reachable if you hold the instance. A factory that\n * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the\n * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the\n * instance to where the caller lives first.\n */\n loading: Ref<boolean>\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,IAAaA,KACX,GACA,GACA,MACW;CACX,IAAM,EAAE,kBAAe,mBAAgB,kBAAe,eAAY,uBAAoBC,EAAmB;CAOzG,OANAC,EAAcC,EAAW,MAAM,WAAW,GAC1CC,EAAeD,EAAW,MAAM,MAAMA,EAAW,MAAM,WAAW,GAC9DA,EAAW,MAAM,UACnBE,EAAcF,EAAW,MAAM,OAAO,KAAKA,EAAW,MAAM,OAAO,UAAUG,EAAU,IAAI,GAE7FC,EAAgBC,GAAYC,CAAY,GACjCC,EAAW;AACpB,GAEaC,KAAsB,MAAgE;CACjG,IAAM,EACJ,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,OACfC,GACEC,IAAYC,EAAgB,EAAE,kBAAe,CAAC;CA+HpD,OAAO;EAAE,gBA5HP,GACA,GACA,GACA,IAA+B,CAAC,MACf;GACjB,IAAM,EACJ,aAAaC,GACb,WAAWC,GACX,kBAAe,IACf,WACA,QAAQC,IAAW,OACjBC,GAMAC,GAIAC,GAIAC,IAAa,GACbC,GACEC,KAAmB,MAA8B;IAQrD,AAAIV,EAAU,WAAW,MAAMQ,KAC3BC,GAAW,YAAY,MAMvBE,GAAQ,YAAY,OACxB,EAAW,QAAQ;KAAE,GAAGrB,EAAW;KAAO,GAAGsB;IAAK;GACpD;GAEA,IAAI;IACF,IAAMC,IAAM,MAAMb,EAAU,KAAK,GAAa,MAAsB;KAElE,AADA,IAAac,GACb,IAAYC;KAUZ,IAAMC,IAAWC,EAAUf,CAAmB,IAAIA,IAAsBgB;KACxE,IAAIC,EAAYH,CAAQ,GAAG,MAAM,IAAII,EAAe,KAAA,GAAW,2BAA2B;KAE1F,IAAMC,IAAiBJ,EAAUd,CAAiB,IAAIA,IAAoBmB,GACpEC,IAAY3B,EAAa,QAAQ,WAAW4B,IAAe,YAAY,IAGvEC,KADHN,EAAYE,CAAc,IAAIL,IAAWU,EAAqBV,GAAUK,CAAc,KAAKE,IACjEpC,EAAkBG,GAAYK,GAAYC,CAAY,GAC7E+B,IAAWC,EAAO;KAMxB,OAFA,IAAMH,GAECE,EAAS,IAAIF,GAAY;MAAE,GAAGI,EAAcC,CAAO;MAAG,QAAQf;KAAY,CAAC;IACpF,GAAGJ,CAAM;IAET,IAAaE,EAAI;IAGjB,IAAMkB,UAAeC,EAAaJ,GAAQtB,GAAKwB,GAAS,KAAA,GAAWvB,CAAU;IAC7E,IAAI,CAAC0B,EAAkBpB,EAAI,MAAM,GAAG,MAAM,IAAIqB,EAAyBrB,EAAI,MAAM;IAIjF,IAAIA,EAAI,WAAA,KASN,OADAH,EAAgB;KAAE,YAAY;KAAG,aADZyB,EAAO7C,EAAW,MAAM,WACC,IAAe,OAAO;KAAO,kBAAkB;IAAE,CAAC,GACzF,CAAC;IAGV,IAAI,CAAC8C,EAAQvB,CAAG,GACd,MAAM,IAAIqB,EAAyBrB,EAAI,QAAQ,KAAA,GAAW,oCAAoCkB,EAAO,CAAC;IAGxG,IAAMM,IAAOC,EAAgBzB,EAAI,MAAMA,EAAI,QAAQkB,EAAO,CAAC;IAM3D,OAFIM,EAAK,SAAS,aAAW3B,EAAgB;KAAE,GAAG2B,EAAK;KAAY,kBAAkBA,EAAK,MAAM;IAAO,CAAC,GAEjGA,EAAK;GACd,SAASE,GAAc;IAGrB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKR,EAAaJ,GAAQtB,GAAKwB,GAASS,GAAKhC,CAAU;IACzD,GAEMkC,IAAQC,EAAYH,GAAKC,CAAO;IAEtC,MAAMpC,IAAWuC,EAAOF,GAAOD,CAAO,IAAIC;GAC5C;EACF;EAEkB,OAAOzC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE"}
1
+ {"version":3,"file":"useApiFetchList.js","names":["generateListQuery","useApiQueryBuilder","querySetLimit","pagination","querySetOffset","querySetOrder","SortOrder","querySetFilters","filterData","filterConfig","queryBuild","useApiFetchList","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","reported","fetchParams","url","dispatched","generation","ownSignal","writePagination","signal","next","res","currentGeneration","abortSignal","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","resolvedParams","urlParams","searchApi","forceElastic","requestUrl","replaceUrlParameters","instance","client","ownedByHelper","options","asSent","requestedUrl","isValidHTTPStatus","AnzuApiResponseCodeError","isNull","hasBody","list","readListBody","err","context","error","mapApiError","report"],"sources":["../../../../src/domains/api/composables/useApiFetchList.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig } from 'axios'\nimport { useApiQueryBuilder } from '@/domains/api/composables/useApiQueryBuilder'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { FilterConfig, FilterData } from '@/domains/filters/composables/filterFactory'\nimport type { Ref } from 'vue'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport type { Pagination } from '@/domains/api/composables/pagination'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readListBody } from '@/domains/api/utils/listBody'\n\nexport type UseApiFetchListParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n}\n\nexport type FetchListParams = {\n urlTemplate?: string\n urlParams?: UrlParams\n forceElastic?: boolean\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n /**\n * `false`: a failure of this call is still thrown but not sent to the api error logger.\n * For a caller that polls a list and has already reported its first failure. It is set per call, not per instance.\n */\n report?: boolean\n}\n\nexport const generateListQuery = (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>\n): string => {\n const { querySetLimit, querySetOffset, querySetOrder, queryBuild, querySetFilters } = useApiQueryBuilder()\n querySetLimit(pagination.value.rowsPerPage)\n querySetOffset(pagination.value.page, pagination.value.rowsPerPage)\n if (pagination.value.sortBy) {\n querySetOrder(pagination.value.sortBy.key, pagination.value.sortBy.order === SortOrder.Desc)\n }\n querySetFilters(filterData, filterConfig)\n return queryBuild()\n}\n\nexport const useApiFetchList = <T>(params: UseApiFetchListParams): UseApiFetchListReturnType<T> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n fetchParams: FetchListParams = {}\n ): Promise<T[]> => {\n const {\n urlTemplate: urlTemplateOverride,\n urlParams: urlParamsOverride,\n forceElastic = false,\n signal,\n report: reported = true,\n } = fetchParams\n\n // Assigned inside `run` once a url exists. It stays undefined before\n // that, because a call that never reached the wire requested no url.\n let url: string | undefined\n // The config axios used, kept for failures raised after reading the response. Those carry\n // no config, and a rebuild would describe the request as the client would send it now.\n let dispatched: AxiosRequestConfig | undefined\n\n // Set by `run`, not read before it. `run` opens the new\n // generation, so an earlier value belongs to the previous call.\n let generation = 0\n let ownSignal: AbortSignal | undefined\n const writePagination = (next: Partial<Pagination>) => {\n // Check both a newer generation and this call's own abort. Aborting does not stop a response already arriving.\n // The generation belongs to the instance, so one instance must serve one list.\n // Concurrent calls writing to different refs would leave the older ref unwritten.\n if (abortable.generation() !== generation) return\n if (ownSignal?.aborted === true) return\n // Read the caller's signal directly, not the relay. `run` drops the relay once the response arrives\n // and this write happens after, so an abort in between would otherwise still write pagination.\n if (signal?.aborted === true) return\n pagination.value = { ...pagination.value, ...next }\n }\n\n try {\n const res = await abortable.run((abortSignal, currentGeneration) => {\n generation = currentGeneration\n ownSignal = abortSignal\n\n // The url is derived inside `run`, which opens the generation and, with\n // `cancelPrevious`, stops the previous call. If building it threw before `run`,\n // the previous call would stay current and write pagination for a replaced query.\n // Inside the try so these failures raise the same error class as others.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const searchApi = filterConfig.general.elastic || forceElastic ? '/search' : ''\n const baseUrl =\n (isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)) + searchApi\n const requestUrl = baseUrl + generateListQuery(pagination, filterData, filterConfig)\n const instance = client()\n\n // Recorded last, when nothing before the call can throw. A failing\n // client factory means no request happened, so no url is reported.\n url = requestUrl\n\n return instance.get(requestUrl, { ...ownedByHelper(options), signal: abortSignal })\n }, signal)\n\n dispatched = res.config\n // The url the report names, so the message and context agree when an interceptor rewrote the request.\n const asSent = () => requestedUrl(client, url, options, undefined, dispatched)\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // 204 is an empty list. The metadata must be reset, or it keeps describing the previous query.\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n // The current pagination mode decides what to clear. A counted list\n // keeps `hasNextPage` as `null`, an infinite one gets `false`.\n // Writing `null` for both switched infinite lists to counted mode. `ASubjectSelect` then autoloaded\n // the same 204 again, and `ADatatablePagination` offered Next and Last on an empty page.\n const stillCounted = isNull(pagination.value.hasNextPage)\n writePagination({ totalCount: 0, hasNextPage: stillCounted ? null : false, currentViewCount: 0 })\n return []\n }\n\n if (!hasBody(res)) {\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + asSent())\n }\n\n const list = readListBody<T>(res.data, res.status, asSent())\n // Only write when the response named a paging mode. Otherwise a lone\n // `currentViewCount` would be stale metadata for an earlier query.\n if (list.mode !== 'unknown') writePagination({ ...list.pagination, currentViewCount: list.items.length })\n\n return list.items\n } catch (err: unknown) {\n // Built once and shared by both, as in the batch.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n const error = mapApiError(err, context)\n\n throw reported ? report(error, context) : error\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchListReturnType<T> = {\n execute: (\n pagination: Ref<Pagination>,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n params?: FetchListParams\n ) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance has a request in flight. Unlike a caller-cleared\n * `finally` flag, it does not dip when `cancelPrevious` supersedes a call.\n * It covers only this helper's work. Keep your own flag if it also spans follow-up fetches or mapping.\n * It belongs to the instance. A factory that builds one per call cannot\n * expose `loading`, `abort` or `cancelPrevious`, so hoist the instance first.\n */\n loading: Ref<boolean>\n}\n"],"mappings":";;;;;;;;;;;;AA2CA,IAAaA,KACX,GACA,GACA,MACW;CACX,IAAM,EAAE,kBAAe,mBAAgB,kBAAe,eAAY,uBAAoBC,EAAmB;CAOzG,OANAC,EAAcC,EAAW,MAAM,WAAW,GAC1CC,EAAeD,EAAW,MAAM,MAAMA,EAAW,MAAM,WAAW,GAC9DA,EAAW,MAAM,UACnBE,EAAcF,EAAW,MAAM,OAAO,KAAKA,EAAW,MAAM,OAAO,UAAUG,EAAU,IAAI,GAE7FC,EAAgBC,GAAYC,CAAY,GACjCC,EAAW;AACpB,GAEaC,KAAsB,MAAgE;CACjG,IAAM,EACJ,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,OACfC,GACEC,IAAYC,EAAgB,EAAE,kBAAe,CAAC;CA2GpD,OAAO;EAAE,gBAxGP,GACA,GACA,GACA,IAA+B,CAAC,MACf;GACjB,IAAM,EACJ,aAAaC,GACb,WAAWC,GACX,kBAAe,IACf,WACA,QAAQC,IAAW,OACjBC,GAIAC,GAGAC,GAIAC,IAAa,GACbC,GACEC,KAAmB,MAA8B;IAIrD,AAAIV,EAAU,WAAW,MAAMQ,KAC3BC,GAAW,YAAY,MAGvBE,GAAQ,YAAY,OACxB,EAAW,QAAQ;KAAE,GAAGrB,EAAW;KAAO,GAAGsB;IAAK;GACpD;GAEA,IAAI;IACF,IAAMC,IAAM,MAAMb,EAAU,KAAK,GAAa,MAAsB;KAElE,AADA,IAAac,GACb,IAAYC;KAMZ,IAAMC,IAAWC,EAAUf,CAAmB,IAAIA,IAAsBgB;KACxE,IAAIC,EAAYH,CAAQ,GAAG,MAAM,IAAII,EAAe,KAAA,GAAW,2BAA2B;KAE1F,IAAMC,IAAiBJ,EAAUd,CAAiB,IAAIA,IAAoBmB,GACpEC,IAAY3B,EAAa,QAAQ,WAAW4B,IAAe,YAAY,IAGvEC,KADHN,EAAYE,CAAc,IAAIL,IAAWU,EAAqBV,GAAUK,CAAc,KAAKE,IACjEpC,EAAkBG,GAAYK,GAAYC,CAAY,GAC7E+B,IAAWC,EAAO;KAMxB,OAFA,IAAMH,GAECE,EAAS,IAAIF,GAAY;MAAE,GAAGI,EAAcC,CAAO;MAAG,QAAQf;KAAY,CAAC;IACpF,GAAGJ,CAAM;IAET,IAAaE,EAAI;IAEjB,IAAMkB,UAAeC,EAAaJ,GAAQtB,GAAKwB,GAAS,KAAA,GAAWvB,CAAU;IAC7E,IAAI,CAAC0B,EAAkBpB,EAAI,MAAM,GAAG,MAAM,IAAIqB,EAAyBrB,EAAI,MAAM;IAGjF,IAAIA,EAAI,WAAA,KAON,OADAH,EAAgB;KAAE,YAAY;KAAG,aADZyB,EAAO7C,EAAW,MAAM,WACC,IAAe,OAAO;KAAO,kBAAkB;IAAE,CAAC,GACzF,CAAC;IAGV,IAAI,CAAC8C,EAAQvB,CAAG,GACd,MAAM,IAAIqB,EAAyBrB,EAAI,QAAQ,KAAA,GAAW,oCAAoCkB,EAAO,CAAC;IAGxG,IAAMM,IAAOC,EAAgBzB,EAAI,MAAMA,EAAI,QAAQkB,EAAO,CAAC;IAK3D,OAFIM,EAAK,SAAS,aAAW3B,EAAgB;KAAE,GAAG2B,EAAK;KAAY,kBAAkBA,EAAK,MAAM;IAAO,CAAC,GAEjGA,EAAK;GACd,SAASE,GAAc;IAErB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKR,EAAaJ,GAAQtB,GAAKwB,GAASS,GAAKhC,CAAU;IACzD,GAEMkC,IAAQC,EAAYH,GAAKC,CAAO;IAEtC,MAAMpC,IAAWuC,EAAOF,GAAOD,CAAO,IAAIC;GAC5C;EACF;EAEkB,OAAOzC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE"}
@@ -12,7 +12,6 @@ export type UseApiFetchListBatchParams = {
12
12
  validationEntity?: string;
13
13
  urlTemplate?: string;
14
14
  urlParams?: UrlParams;
15
- /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */
16
15
  options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>;
17
16
  cancelPrevious?: boolean;
18
17
  };
@@ -31,27 +30,11 @@ export type UseApiFetchListBatchReturnType<T> = {
31
30
  execute: (filterData: FilterData<any>, filterConfig: FilterConfig<any>, params?: FetchListBatchParams) => Promise<T[]>;
32
31
  abort: () => void;
33
32
  /**
34
- * True while this instance is working, false once it stops.
35
- *
36
- * Here that is the whole walk, not one request: a batch reads every page, and the flag stays up
37
- * across the gaps between them and across the reading of each answer.
38
- *
39
- * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in
40
- * a `finally`, and that `finally` belongs to whichever call ended -- including one that
41
- * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting
42
- * for is still running. This one never dips between a superseded call and the one that replaced it.
43
- *
44
- * Two things to know before replacing a hand-rolled flag with it.
45
- *
46
- * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a
47
- * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it
48
- * for this one turns the spinner off too early. Keep your own where it means more than "this helper
49
- * is working".
50
- *
51
- * It belongs to the instance, so it is only reachable if you hold the instance. A factory that
52
- * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the
53
- * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the
54
- * instance to where the caller lives first.
33
+ * True while this instance is working. For a batch it covers the whole walk, including gaps between pages.
34
+ * Unlike a hand-rolled ref cleared in `finally`, it does not drop when `cancelPrevious` supersedes a call.
35
+ * It covers only this helper. Keep your own flag if it also spans follow-up work such as a cached fetch or mapping.
36
+ * It is only reachable if you hold the instance. A factory that creates
37
+ * one per call cannot expose `loading`, `abort` or `cancelPrevious`.
55
38
  */
56
39
  loading: Ref<boolean>;
57
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useApiFetchListBatch.js","names":["PageFailure","pageUrl","failure","dispatched","useApiFetchListBatch","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","fetchParams","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","batchSize","resolvedParams","urlParams","searchApi","filterConfig","forceElastic","baseUrl","replaceUrlParameters","instance","client","usePagination","sortBy","sortDesc","SortOrder","get","generateListQuery","page","filterData","ownedByHelper","options","abortSignal","err","asSent","requestedUrl","res","readPage","isValidHTTPStatus","AnzuApiResponseCodeError","hasBody","body","readListBody","firstPage","pagination","first","results","capped","hasNextPage","nextPage","next","pageCount","ref","index","signal","failed","context","report","mapApiError"],"sources":["../../../../src/domains/api/composables/useApiFetchListBatch.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig, AxiosResponse } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { FilterConfig, FilterData } from '@/domains/filters/composables/filterFactory'\nimport { type Ref, ref } from 'vue'\nimport { isDefined, isUndefined } from '@/shared/utils/common'\nimport { type Pagination, usePagination } from '@/domains/api/composables/pagination'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { generateListQuery } from '@/domains/api/composables/useApiFetchList'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readListBody } from '@/domains/api/utils/listBody'\n\nexport type UseApiFetchListBatchParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n}\n\nexport type FetchListBatchParams = {\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n urlTemplate?: string\n urlParams?: UrlParams\n sortBy?: string\n sortDesc?: boolean\n batchSize?: number\n forceElastic?: boolean\n}\n\n/**\n * Carries the url of the page a failure happened on out to the catch that reports it.\n *\n * Nothing outside this file sees it: the catch unwraps it before mapping, so the caller gets the\n * same classes it would get from any other helper.\n */\nclass PageFailure extends Error {\n readonly pageUrl: string\n readonly failure: unknown\n /**\n * The config axios used for this page, when the page answered and it was this helper that\n * refused what came back. A page that failed in transport needs none: axios kept its own.\n */\n readonly dispatched?: AxiosRequestConfig\n\n constructor(pageUrl: string, failure: unknown, dispatched?: AxiosRequestConfig) {\n super('Batch page failed')\n this.name = 'PageFailure'\n this.pageUrl = pageUrl\n this.failure = failure\n this.dispatched = dispatched\n }\n}\n\nexport const useApiFetchListBatch = <T>(params: UseApiFetchListBatchParams): UseApiFetchListBatchReturnType<T> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n fetchParams: FetchListBatchParams = {}\n ): Promise<T[]> => {\n const {\n urlTemplate: urlTemplateOverride,\n urlParams: urlParamsOverride,\n sortBy = 'id',\n sortDesc = true,\n batchSize = 100,\n forceElastic = false,\n signal,\n } = fetchParams\n\n try {\n return await abortable.run(async (abortSignal) => {\n // Derived inside `run`, the way the list does it: `run` opens the generation and, with\n // `cancelPrevious`, stops the call before this one, so a call that throws on a missing\n // template or a malformed filter config would otherwise leave its predecessor running.\n // Inside the try as well, so that failure arrives as the same error class as every other.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n // A page size below one cannot end the walk: every page is then \"not shorter than the one\n // asked for\", so the loop has no exit and the helper becomes an unbounded stream of\n // requests. It is the caller's mistake, and it arrives as the same error class as the\n // caller's other mistakes rather than as a backend that never stops answering.\n if (batchSize < 1) throw new AnzuFatalError(undefined, 'batchSize must be at least 1, got ' + batchSize)\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const searchApi = filterConfig.general.elastic || forceElastic ? '/search' : ''\n const baseUrl =\n (isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)) + searchApi\n // One instance for the whole batch: a call is one call, and a factory that answers\n // differently per page would have its pages talking to two backends.\n const instance = client()\n\n const { pagination } = usePagination(sortBy, sortDesc ? SortOrder.Desc : SortOrder.Asc, {\n rowsPerPage: batchSize,\n })\n\n // The page's own url travels with its response: a batch that failed on page three has to\n // be able to say which page that was, and the base url cannot.\n const get = async (page: Ref<Pagination>) => {\n const pageUrl = baseUrl + generateListQuery(page, filterData, filterConfig)\n\n try {\n return { res: await instance.get(pageUrl, { ...ownedByHelper(options), signal: abortSignal }), pageUrl }\n } catch (err: unknown) {\n // Tagged here, where the page is still known. A shared variable cannot do this job: the\n // counted branch dispatches every page before any of them answers, so it would always\n // hold the last one and name the wrong page for the one that actually failed.\n throw new PageFailure(pageUrl, err)\n }\n }\n\n // The url the report will name for this page, so a message and the context beside it cannot\n // disagree about which request failed when an interceptor rewrote it on the way out.\n const asSent = (res: AxiosResponse, pageUrl: string) =>\n requestedUrl(client, pageUrl, options, undefined, res.config)\n\n // Every page is read the same way, the ones after the first included: a 2xx with no body at\n // all has broken its contract, wherever in the sequence it sits -- a server that fails on\n // page three is not \"finished\". The 204 branch is defensive rather than expected: these\n // backends answer an empty list as a 200 with a body, so a list never arrives as a 204, and\n // the branch is here for an endpoint that one day does.\n\n const readPage = (res: AxiosResponse, pageUrl: string) => {\n if (!isValidHTTPStatus(res.status)) {\n throw new PageFailure(pageUrl, new AnzuApiResponseCodeError(res.status), res.config)\n }\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n return {\n items: [] as T[],\n mode: 'unknown' as const,\n totalCount: 0,\n hasNextPage: false,\n countIsBound: false,\n empty: true,\n }\n }\n if (!hasBody(res)) {\n throw new PageFailure(\n pageUrl,\n new AnzuApiResponseCodeError(\n res.status,\n undefined,\n 'Expected a response body, url: ' + asSent(res, pageUrl)\n ),\n res.config\n )\n }\n\n let body\n try {\n body = readListBody<T>(res.data, res.status, asSent(res, pageUrl))\n } catch (err: unknown) {\n throw new PageFailure(pageUrl, err, res.config)\n }\n\n return {\n items: body.items,\n mode: body.mode,\n totalCount: body.pagination.totalCount ?? 0,\n hasNextPage: body.pagination.hasNextPage === true,\n countIsBound: body.countIsBound,\n empty: false,\n }\n }\n\n const firstPage = await get(pagination)\n const first = readPage(firstPage.res, firstPage.pageUrl)\n const results: T[] = [...first.items]\n if (first.empty) return results\n\n // A first page shorter than the one asked for means the offsets cannot be trusted: every page\n // after it is addressed by arithmetic on a page size, and the server has just shown that the\n // size it uses is not the size requested. Read as the server's real page size -- a capped\n // `limit`, which backends do -- and taken from page one, which has already answered.\n //\n // Before the branch, not inside it: both ways of walking a list address their pages this way,\n // and hardening one of them is how the counted branch was fixed while the infinite one went\n // on losing rows.\n //\n // It is a reading, not a fact. The other reading would be a server that applies `limit` and\n // then drops rows -- permissions, soft deletes -- while counting `totalCount` before that:\n // its window really is the requested size, so stepping by the shorter one overlaps and rows\n // repeat at each boundary. A sweep of the shared path found no such dropping, so the reading\n // taken here is the one these backends support; the trade is deliberate anyway, because\n // repeated rows are visible to whoever reads the list and missing ones are not.\n //\n // What the ambiguity does buy is the caution below: once the arithmetic is in doubt, the\n // pages are walked one at a time rather than fired off together, so a wrong guess costs\n // requests one by one rather than a burst of them, and stops at the first empty page.\n const capped = first.items.length > 0 && first.items.length < pagination.value.rowsPerPage\n if (capped) pagination.value.rowsPerPage = first.items.length\n\n // Infinite lists walk page by page, because only the answer says whether another exists.\n if (first.mode === 'infinite') {\n let hasNextPage = first.hasNextPage\n while (hasNextPage) {\n pagination.value.page++\n const nextPage = await get(pagination)\n const next = readPage(nextPage.res, nextPage.pageUrl)\n results.push(...next.items)\n if (next.empty) break\n hasNextPage = next.hasNextPage\n }\n\n return results\n }\n\n // A list that named neither mode has said nothing about further pages, so the first is all\n // there is.\n if (first.mode !== 'counted') return results\n\n // Two ways the count cannot be divided into a page count. The server may have said so itself\n // -- `bigTable`, which is on by default, makes `totalCount` a look-ahead of `offset + limit + 1`\n // rather than a total, corrected to the real number only on the page that comes back short.\n // Dividing that by the page size answers 2, whatever the list's real length: a batch over\n // 5000 rows would return 200 of them and resolve as though it were finished. Or the page size\n // itself had to be guessed, in which case the count divides by a number the server has\n // already contradicted.\n //\n // Either way the walk is sequential and ends where the data does -- a page shorter than the\n // one asked for is the server saying there is no more, and it is the same signal the\n // repository uses to correct the count in the first place.\n // Already holding as many rows as the count names, so there is nothing to walk to. This is\n // also what makes a short first page unambiguous: the repository corrects `totalCount` to the\n // real total exactly when a page comes back shorter than the limit it applied, so a list that\n // simply ends satisfies this, while a server that capped the limit reports its look-ahead\n // instead and does not.\n if (results.length >= first.totalCount) return results\n\n if (capped || first.countIsBound) {\n for (;;) {\n pagination.value.page++\n const nextPage = await get(pagination)\n const next = readPage(nextPage.res, nextPage.pageUrl)\n results.push(...next.items)\n if (next.items.length < pagination.value.rowsPerPage) break\n }\n\n return results\n }\n\n // Counted lists know how many pages there are, so the rest go out together.\n const pageCount = Math.ceil(first.totalCount / pagination.value.rowsPerPage)\n if (pageCount <= 1) return results\n\n // Each page is read as it arrives, not after all of them have. Reading them afterwards meant\n // a page that answered with a broken body was not noticed until every sibling had settled --\n // and a sibling that never answers made that never, so the call hung on a failure it was\n // already holding. Rejecting here reaches `run`, which stops the siblings.\n const rest = await Promise.all(\n Array.from({ length: pageCount - 1 }, (_unused, index) =>\n get(ref({ ...pagination.value, page: index + 2 })).then((page) => readPage(page.res, page.pageUrl))\n )\n )\n // A 204 among them contributes nothing and the others are kept -- there is no sequence to\n // stop here, they all went out at once.\n rest.forEach((page) => results.push(...page.items))\n\n return results\n }, signal)\n } catch (err: unknown) {\n const failed = err instanceof PageFailure ? err : null\n // Only a page can name a url here, and it names its own. The base url is not an answer: it was\n // never requested, and a failure that belongs to no page -- a missing template, a filter config\n // that will not render -- happened before any page existed. Nothing else can fail after a page\n // has gone out, because everything from the dispatch onwards is tagged as a `PageFailure`.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, failed?.pageUrl, options, failed?.failure ?? err, failed?.dispatched),\n }\n\n throw report(mapApiError(failed?.failure ?? err, context), context)\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchListBatchReturnType<T> = {\n execute: (filterData: FilterData<any>, filterConfig: FilterConfig<any>, params?: FetchListBatchParams) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance is working, false once it stops.\n *\n * Here that is the whole walk, not one request: a batch reads every page, and the flag stays up\n * across the gaps between them and across the reading of each answer.\n *\n * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in\n * a `finally`, and that `finally` belongs to whichever call ended -- including one that\n * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting\n * for is still running. This one never dips between a superseded call and the one that replaced it.\n *\n * Two things to know before replacing a hand-rolled flag with it.\n *\n * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a\n * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it\n * for this one turns the spinner off too early. Keep your own where it means more than \"this helper\n * is working\".\n *\n * It belongs to the instance, so it is only reachable if you hold the instance. A factory that\n * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the\n * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the\n * instance to where the caller lives first.\n */\n loading: Ref<boolean>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useApiFetchListBatch.js","names":["PageFailure","pageUrl","failure","dispatched","useApiFetchListBatch","params","abortable","createAbortable","urlTemplateOverride","urlParamsOverride","fetchParams","template","isDefined","urlTemplate","isUndefined","AnzuFatalError","batchSize","resolvedParams","urlParams","searchApi","filterConfig","forceElastic","baseUrl","replaceUrlParameters","instance","client","usePagination","sortBy","sortDesc","SortOrder","get","generateListQuery","page","filterData","ownedByHelper","options","abortSignal","err","asSent","requestedUrl","res","readPage","isValidHTTPStatus","AnzuApiResponseCodeError","hasBody","body","readListBody","firstPage","pagination","first","results","capped","hasNextPage","nextPage","next","pageCount","ref","index","signal","failed","context","report","mapApiError"],"sources":["../../../../src/domains/api/composables/useApiFetchListBatch.ts"],"sourcesContent":["import { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig, AxiosResponse } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { FilterConfig, FilterData } from '@/domains/filters/composables/filterFactory'\nimport { type Ref, ref } from 'vue'\nimport { isDefined, isUndefined } from '@/shared/utils/common'\nimport { type Pagination, usePagination } from '@/domains/api/composables/pagination'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { generateListQuery } from '@/domains/api/composables/useApiFetchList'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport { createAbortable, hasBody, ownedByHelper, requestedUrl } from '@/domains/api/composables/request'\nimport { readListBody } from '@/domains/api/utils/listBody'\n\nexport type UseApiFetchListBatchParams = {\n client: AxiosClientFn\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n cancelPrevious?: boolean\n}\n\nexport type FetchListBatchParams = {\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n urlTemplate?: string\n urlParams?: UrlParams\n sortBy?: string\n sortDesc?: boolean\n batchSize?: number\n forceElastic?: boolean\n}\n\n/**\n * Carries the url of the failing page to the catch that reports it.\n * The catch unwraps it before mapping, so callers see the same error classes as from other helpers.\n */\nclass PageFailure extends Error {\n readonly pageUrl: string\n readonly failure: unknown\n /**\n * The config axios used, set when the page answered but this helper refused\n * the response. Transport failures do not need it, axios keeps its own.\n */\n readonly dispatched?: AxiosRequestConfig\n\n constructor(pageUrl: string, failure: unknown, dispatched?: AxiosRequestConfig) {\n super('Batch page failed')\n this.name = 'PageFailure'\n this.pageUrl = pageUrl\n this.failure = failure\n this.dispatched = dispatched\n }\n}\n\nexport const useApiFetchListBatch = <T>(params: UseApiFetchListBatchParams): UseApiFetchListBatchReturnType<T> => {\n const {\n client,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable = createAbortable({ cancelPrevious })\n\n const execute = async (\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n fetchParams: FetchListBatchParams = {}\n ): Promise<T[]> => {\n const {\n urlTemplate: urlTemplateOverride,\n urlParams: urlParamsOverride,\n sortBy = 'id',\n sortDesc = true,\n batchSize = 100,\n forceElastic = false,\n signal,\n } = fetchParams\n\n try {\n return await abortable.run(async (abortSignal) => {\n // Derived inside `run` because `run` opens the generation and, with `cancelPrevious`,\n // stops the previous call. A throw before it would leave the predecessor running.\n // Inside the try so the failure raises the same error class as others.\n const template = isDefined(urlTemplateOverride) ? urlTemplateOverride : urlTemplate\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n\n // A page size below one never ends the walk and causes unbounded requests. Fail it as a caller error.\n if (batchSize < 1) throw new AnzuFatalError(undefined, 'batchSize must be at least 1, got ' + batchSize)\n\n const resolvedParams = isDefined(urlParamsOverride) ? urlParamsOverride : urlParams\n const searchApi = filterConfig.general.elastic || forceElastic ? '/search' : ''\n const baseUrl =\n (isUndefined(resolvedParams) ? template : replaceUrlParameters(template, resolvedParams)) + searchApi\n // One instance for the whole batch, so a factory that answers\n // differently per call cannot split pages across backends.\n const instance = client()\n\n const { pagination } = usePagination(sortBy, sortDesc ? SortOrder.Desc : SortOrder.Asc, {\n rowsPerPage: batchSize,\n })\n\n // Each page carries its own url so a failure can name the page. The base url cannot.\n const get = async (page: Ref<Pagination>) => {\n const pageUrl = baseUrl + generateListQuery(page, filterData, filterConfig)\n\n try {\n return { res: await instance.get(pageUrl, { ...ownedByHelper(options), signal: abortSignal }), pageUrl }\n } catch (err: unknown) {\n // Tagged here while the page is known. The counted branch dispatches all\n // pages before any answers, so a shared variable would name the wrong page.\n throw new PageFailure(pageUrl, err)\n }\n }\n\n // The url the report names for this page, so the message and\n // context agree when an interceptor rewrote the request.\n const asSent = (res: AxiosResponse, pageUrl: string) =>\n requestedUrl(client, pageUrl, options, undefined, res.config)\n\n // Every page is checked the same way. A 2xx with no body breaks the contract on any page.\n // The 204 branch is defensive. These backends return empty lists as 200 with a body.\n\n const readPage = (res: AxiosResponse, pageUrl: string) => {\n if (!isValidHTTPStatus(res.status)) {\n throw new PageFailure(pageUrl, new AnzuApiResponseCodeError(res.status), res.config)\n }\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n return {\n items: [] as T[],\n mode: 'unknown' as const,\n totalCount: 0,\n hasNextPage: false,\n countIsBound: false,\n empty: true,\n }\n }\n if (!hasBody(res)) {\n throw new PageFailure(\n pageUrl,\n new AnzuApiResponseCodeError(\n res.status,\n undefined,\n 'Expected a response body, url: ' + asSent(res, pageUrl)\n ),\n res.config\n )\n }\n\n let body\n try {\n body = readListBody<T>(res.data, res.status, asSent(res, pageUrl))\n } catch (err: unknown) {\n throw new PageFailure(pageUrl, err, res.config)\n }\n\n return {\n items: body.items,\n mode: body.mode,\n totalCount: body.pagination.totalCount ?? 0,\n hasNextPage: body.pagination.hasNextPage === true,\n countIsBound: body.countIsBound,\n empty: false,\n }\n }\n\n const firstPage = await get(pagination)\n const first = readPage(firstPage.res, firstPage.pageUrl)\n const results: T[] = [...first.items]\n if (first.empty) return results\n\n // A short first page is read as the server's real page size (a capped `limit`), so later\n // offsets use it. Done before the branch so both counted and infinite walks use it.\n // If the server instead dropped rows after applying `limit`, this would repeat rows at boundaries.\n // No such dropping was found, and repeated rows are visible while missing ones are not.\n // When capped, pages are walked one at a time, so a wrong guess\n // costs single requests and stops at the first empty page.\n const capped = first.items.length > 0 && first.items.length < pagination.value.rowsPerPage\n if (capped) pagination.value.rowsPerPage = first.items.length\n\n // Infinite lists walk page by page, because only the answer says whether another exists.\n if (first.mode === 'infinite') {\n let hasNextPage = first.hasNextPage\n while (hasNextPage) {\n pagination.value.page++\n const nextPage = await get(pagination)\n const next = readPage(nextPage.res, nextPage.pageUrl)\n results.push(...next.items)\n if (next.empty) break\n hasNextPage = next.hasNextPage\n }\n\n return results\n }\n\n // A list that named neither mode said nothing about further pages, so the first page is all there is.\n if (first.mode !== 'counted') return results\n\n // Two cases where `totalCount` cannot be divided into a page count. `bigTable` (on by default) makes\n // `totalCount` a look-ahead of `offset + limit + 1`, not a total. Dividing it gives 2 pages, so a\n // 5000-row batch would stop at 200. Or the page size was guessed and the server already contradicted it.\n // In both cases walk pages sequentially until a page is shorter than requested. That is the end-of-data signal.\n // Stop early when the rows already reach `totalCount`. The repository corrects\n // `totalCount` to the real total only when a page comes back shorter than its\n // limit. A capped server reports the look-ahead instead and does not match.\n if (results.length >= first.totalCount) return results\n\n if (capped || first.countIsBound) {\n for (;;) {\n pagination.value.page++\n const nextPage = await get(pagination)\n const next = readPage(nextPage.res, nextPage.pageUrl)\n results.push(...next.items)\n if (next.items.length < pagination.value.rowsPerPage) break\n }\n\n return results\n }\n\n // The count is known, so the remaining pages are requested in parallel.\n const pageCount = Math.ceil(first.totalCount / pagination.value.rowsPerPage)\n if (pageCount <= 1) return results\n\n // Read each page as it arrives, not after all settle. Otherwise a broken\n // body goes unnoticed while a sibling hangs, and the call never ends.\n // Rejecting here reaches `run`, which aborts the siblings.\n const rest = await Promise.all(\n Array.from({ length: pageCount - 1 }, (_unused, index) =>\n get(ref({ ...pagination.value, page: index + 2 })).then((page) => readPage(page.res, page.pageUrl))\n )\n )\n // A 204 page adds nothing. The other pages are kept, since all were sent at once.\n rest.forEach((page) => results.push(...page.items))\n\n return results\n }, signal)\n } catch (err: unknown) {\n const failed = err instanceof PageFailure ? err : null\n // Only a page reports a url, and it reports its own. The base url is never\n // requested. A failure before dispatch (missing template, unrenderable filter\n // config) belongs to no page. Every failure after dispatch is a `PageFailure`.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, failed?.pageUrl, options, failed?.failure ?? err, failed?.dispatched),\n }\n\n throw report(mapApiError(failed?.failure ?? err, context), context)\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\nexport type UseApiFetchListBatchReturnType<T> = {\n execute: (filterData: FilterData<any>, filterConfig: FilterConfig<any>, params?: FetchListBatchParams) => Promise<T[]>\n abort: () => void\n /**\n * True while this instance is working. For a batch it covers the whole walk, including gaps between pages.\n * Unlike a hand-rolled ref cleared in `finally`, it does not drop when `cancelPrevious` supersedes a call.\n * It covers only this helper. Keep your own flag if it also spans follow-up work such as a cached fetch or mapping.\n * It is only reachable if you hold the instance. A factory that creates\n * one per call cannot expose `loading`, `abort` or `cancelPrevious`.\n */\n loading: Ref<boolean>\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useApiQueryBuilder.js","names":["useApiQueryBuilder","q","ref","querySetLimit","value","querySetOffset","page","limit","querySetOrder","isNull","field","queryAdd","desc","SortOrder","formatValue","isBoolean","queryAddFilter","isString","filterVariant","fieldConfig","filterConfig","name","isUndefined","resolveTimeIntervalFilter","fromValue","filterData","fromName","untilValue","untilName","mandatory","exclude","now","dateTimeNow","nowDate","dateTimeToDate","TimeIntervalSpecialOptions","getMonthInterval","isNumber","dateToUtc","dateModifyMinutes","getValue","config","isArray","item","key","isSimpleFilters","filterName","filterFieldValue","filterFieldConfig","data","nameRelated"],"sources":["../../../../src/domains/api/composables/useApiQueryBuilder.ts"],"sourcesContent":["import { ref } from 'vue'\nimport { isArray, isBoolean, isNull, isNumber, isString, isUndefined } from '@/shared/utils/common'\nimport type {\n AllowedFilterValues,\n FilterConfig,\n FilterData,\n FilterField,\n FilterVariant,\n} from '@/domains/filters/composables/filterFactory'\nimport type { DatetimeUTCNullable } from '@/shared/types/common'\nimport {\n TimeIntervalSpecialOptions,\n type TimeIntervalToolsValue,\n} from '@/domains/filters/composables/filterTimeIntervalTools'\nimport { dateModifyMinutes, dateTimeNow, dateTimeToDate, dateToUtc, getMonthInterval } from '@/shared/utils/datetime'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\n\n/**\n * Docs: /doc/Admin-Cms-Doc/Filters.md\n */\nexport function useApiQueryBuilder() {\n const q = ref<string[]>([])\n\n const querySetLimit = (value: number): void => {\n queryAdd('limit', value)\n }\n\n const querySetOffset = (page: number, limit: number): void => {\n queryAdd('offset', Math.max(0, (page - 1) * limit))\n }\n\n const querySetOrder = (field: string | null, desc: boolean): void => {\n if (!isNull(field) && field.length > 0) queryAdd('order[' + field + ']', desc ? SortOrder.Desc : SortOrder.Asc)\n }\n\n const formatValue = (value: string | number | boolean): string | number => {\n if (isBoolean(value)) {\n return value ? '1' : '0'\n }\n return value\n }\n\n const queryAddFilter = (filterVariant: FilterVariant, field: string, value: string | number | boolean): void => {\n if (isString(value) && value.length === 0) return\n q.value.push('filter_' + filterVariant + '[' + field + ']=' + formatValue(value))\n }\n\n // `resolveTimeIntervalFilter` is returned, so any caller can pass any names: a missing one fails by name.\n const fieldConfig = (filterConfig: FilterConfig<any>, name: string) => {\n const field = filterConfig.fields[name]\n if (isUndefined(field)) throw new Error(`useApiQueryBuilder: filter field \"${name}\" is not configured`)\n return field\n }\n\n const resolveTimeIntervalFilter = (\n fromName: string,\n untilName: string,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n mandatory: boolean,\n exclude: boolean\n ): null | {\n from: DatetimeUTCNullable\n until: DatetimeUTCNullable\n } => {\n let fromValue = filterData[fromName] as TimeIntervalToolsValue\n let untilValue = filterData[untilName] as DatetimeUTCNullable\n if (isNull(fromValue) && mandatory && !exclude) {\n fromValue = fieldConfig(filterConfig, fromName).default as TimeIntervalToolsValue\n }\n if (isNull(untilValue) && mandatory && !exclude) {\n untilValue = fieldConfig(filterConfig, untilName).default as DatetimeUTCNullable\n }\n if (isString(fromValue) && isString(untilValue)) {\n return {\n from: fromValue,\n until: untilValue,\n }\n }\n const now = dateTimeNow()\n const nowDate = dateTimeToDate(now)\n switch (fromValue) {\n case TimeIntervalSpecialOptions.CurrentMonth: {\n return getMonthInterval(nowDate, 'utc', 0, false)\n }\n case TimeIntervalSpecialOptions.LastMonth: {\n return getMonthInterval(nowDate, 'utc', -1, false)\n }\n case TimeIntervalSpecialOptions.Last3Months: {\n return getMonthInterval(nowDate, 'utc', -2, true)\n }\n default: {\n if (isNumber(fromValue)) {\n return {\n from: dateToUtc(dateModifyMinutes(fromValue * -1, nowDate)),\n until: now,\n }\n }\n }\n }\n return null\n }\n\n const getValue = (value: AllowedFilterValues, config: FilterField): string | number | boolean | null => {\n if (isNull(value)) {\n if (config.mandatory && !config.exclude && !isUndefined(config.default)) {\n return isArray(config.default) ? config.default.join(',') : config.default\n }\n return null\n }\n if (isString(value)) {\n if (value.length === 0) {\n if (config.mandatory && !config.exclude && !isUndefined(config.default) && !isNull(config.default)) {\n return encodeURIComponent(isArray(config.default) ? config.default.join(',') : config.default)\n }\n return null\n }\n return encodeURIComponent(value)\n }\n if (isArray(value)) {\n if (value.length === 0) {\n if (config.mandatory && !config.exclude && isArray(config.default)) {\n return config.default.map((item) => (isString(item) ? encodeURIComponent(item) : item)).join(',')\n }\n return null\n }\n return value.map((item) => (isString(item) ? encodeURIComponent(item) : item)).join(',')\n }\n if (isNumber(value) || isBoolean(value)) {\n return value\n }\n\n return null\n }\n\n const queryAdd = (key: string, value: any): void => {\n q.value.push(key + '=' + value)\n }\n\n const queryBuild = (): string => {\n return '?' + q.value.join('&')\n }\n\n const querySetFilters = (filterData: FilterData<any>, filterConfig: FilterConfig<any>): void => {\n const isSimpleFilters = filterConfig.general.simpleFilters\n for (const filterName in filterData) {\n const filterFieldValue = filterData[filterName] as AllowedFilterValues\n const filterFieldConfig = filterConfig.fields[filterName]\n if (isUndefined(filterFieldConfig) || filterFieldConfig.exclude) {\n continue\n }\n const name = filterFieldConfig.apiName || filterName\n if (filterFieldConfig.type === 'timeInterval' && !isUndefined(filterFieldConfig.related)) {\n const data = resolveTimeIntervalFilter(\n filterName,\n filterFieldConfig.related,\n filterData,\n filterConfig,\n filterFieldConfig.mandatory,\n filterFieldConfig.exclude\n )\n if (isNull(data)) {\n continue\n }\n const filterFieldConfigRelated = fieldConfig(filterConfig, filterFieldConfig.related)\n const nameRelated = filterFieldConfigRelated.apiName || filterFieldConfig.related\n if (isSimpleFilters) {\n queryAdd(name, data.from)\n queryAdd(nameRelated, data.until)\n continue\n }\n if (data.from) queryAddFilter('gte', name, data.from)\n if (data.until) {\n queryAddFilter('lte', nameRelated, data.until)\n }\n continue\n }\n const value = getValue(filterFieldValue, filterFieldConfig)\n if (isNull(value)) {\n continue\n }\n if (isSimpleFilters) {\n queryAdd(name, value)\n continue\n }\n queryAddFilter(filterFieldConfig.variant, name, value)\n }\n }\n\n return {\n resolveTimeIntervalFilter,\n querySetLimit,\n querySetOffset,\n querySetOrder,\n queryAddFilter,\n querySetFilters,\n queryAdd,\n queryBuild,\n q,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useApiQueryBuilder.js","names":["useApiQueryBuilder","q","ref","querySetLimit","value","querySetOffset","page","limit","querySetOrder","isNull","field","queryAdd","desc","SortOrder","formatValue","isBoolean","queryAddFilter","isString","filterVariant","fieldConfig","filterConfig","name","isUndefined","resolveTimeIntervalFilter","fromValue","filterData","fromName","untilValue","untilName","mandatory","exclude","now","dateTimeNow","nowDate","dateTimeToDate","TimeIntervalSpecialOptions","getMonthInterval","isNumber","dateToUtc","dateModifyMinutes","getValue","config","isArray","item","key","isSimpleFilters","filterName","filterFieldValue","filterFieldConfig","data","nameRelated"],"sources":["../../../../src/domains/api/composables/useApiQueryBuilder.ts"],"sourcesContent":["import { ref } from 'vue'\nimport { isArray, isBoolean, isNull, isNumber, isString, isUndefined } from '@/shared/utils/common'\nimport type {\n AllowedFilterValues,\n FilterConfig,\n FilterData,\n FilterField,\n FilterVariant,\n} from '@/domains/filters/composables/filterFactory'\nimport type { DatetimeUTCNullable } from '@/shared/types/common'\nimport {\n TimeIntervalSpecialOptions,\n type TimeIntervalToolsValue,\n} from '@/domains/filters/composables/filterTimeIntervalTools'\nimport { dateModifyMinutes, dateTimeNow, dateTimeToDate, dateToUtc, getMonthInterval } from '@/shared/utils/datetime'\nimport { SortOrder } from '@/domains/api/types/SortOrder'\n\n/**\n * Docs: /doc/Admin-Cms-Doc/Filters.md\n */\nexport function useApiQueryBuilder() {\n const q = ref<string[]>([])\n\n const querySetLimit = (value: number): void => {\n queryAdd('limit', value)\n }\n\n const querySetOffset = (page: number, limit: number): void => {\n queryAdd('offset', Math.max(0, (page - 1) * limit))\n }\n\n const querySetOrder = (field: string | null, desc: boolean): void => {\n if (!isNull(field) && field.length > 0) queryAdd('order[' + field + ']', desc ? SortOrder.Desc : SortOrder.Asc)\n }\n\n const formatValue = (value: string | number | boolean): string | number => {\n if (isBoolean(value)) {\n return value ? '1' : '0'\n }\n return value\n }\n\n const queryAddFilter = (filterVariant: FilterVariant, field: string, value: string | number | boolean): void => {\n if (isString(value) && value.length === 0) return\n q.value.push('filter_' + filterVariant + '[' + field + ']=' + formatValue(value))\n }\n\n // `resolveTimeIntervalFilter` is public, so callers can pass any field names. A missing one fails with its name.\n const fieldConfig = (filterConfig: FilterConfig<any>, name: string) => {\n const field = filterConfig.fields[name]\n if (isUndefined(field)) throw new Error(`useApiQueryBuilder: filter field \"${name}\" is not configured`)\n return field\n }\n\n const resolveTimeIntervalFilter = (\n fromName: string,\n untilName: string,\n filterData: FilterData<any>,\n filterConfig: FilterConfig<any>,\n mandatory: boolean,\n exclude: boolean\n ): null | {\n from: DatetimeUTCNullable\n until: DatetimeUTCNullable\n } => {\n let fromValue = filterData[fromName] as TimeIntervalToolsValue\n let untilValue = filterData[untilName] as DatetimeUTCNullable\n if (isNull(fromValue) && mandatory && !exclude) {\n fromValue = fieldConfig(filterConfig, fromName).default as TimeIntervalToolsValue\n }\n if (isNull(untilValue) && mandatory && !exclude) {\n untilValue = fieldConfig(filterConfig, untilName).default as DatetimeUTCNullable\n }\n if (isString(fromValue) && isString(untilValue)) {\n return {\n from: fromValue,\n until: untilValue,\n }\n }\n const now = dateTimeNow()\n const nowDate = dateTimeToDate(now)\n switch (fromValue) {\n case TimeIntervalSpecialOptions.CurrentMonth: {\n return getMonthInterval(nowDate, 'utc', 0, false)\n }\n case TimeIntervalSpecialOptions.LastMonth: {\n return getMonthInterval(nowDate, 'utc', -1, false)\n }\n case TimeIntervalSpecialOptions.Last3Months: {\n return getMonthInterval(nowDate, 'utc', -2, true)\n }\n default: {\n if (isNumber(fromValue)) {\n return {\n from: dateToUtc(dateModifyMinutes(fromValue * -1, nowDate)),\n until: now,\n }\n }\n }\n }\n return null\n }\n\n const getValue = (value: AllowedFilterValues, config: FilterField): string | number | boolean | null => {\n if (isNull(value)) {\n if (config.mandatory && !config.exclude && !isUndefined(config.default)) {\n return isArray(config.default) ? config.default.join(',') : config.default\n }\n return null\n }\n if (isString(value)) {\n if (value.length === 0) {\n if (config.mandatory && !config.exclude && !isUndefined(config.default) && !isNull(config.default)) {\n return encodeURIComponent(isArray(config.default) ? config.default.join(',') : config.default)\n }\n return null\n }\n return encodeURIComponent(value)\n }\n if (isArray(value)) {\n if (value.length === 0) {\n if (config.mandatory && !config.exclude && isArray(config.default)) {\n return config.default.map((item) => (isString(item) ? encodeURIComponent(item) : item)).join(',')\n }\n return null\n }\n return value.map((item) => (isString(item) ? encodeURIComponent(item) : item)).join(',')\n }\n if (isNumber(value) || isBoolean(value)) {\n return value\n }\n\n return null\n }\n\n const queryAdd = (key: string, value: any): void => {\n q.value.push(key + '=' + value)\n }\n\n const queryBuild = (): string => {\n return '?' + q.value.join('&')\n }\n\n const querySetFilters = (filterData: FilterData<any>, filterConfig: FilterConfig<any>): void => {\n const isSimpleFilters = filterConfig.general.simpleFilters\n for (const filterName in filterData) {\n const filterFieldValue = filterData[filterName] as AllowedFilterValues\n const filterFieldConfig = filterConfig.fields[filterName]\n if (isUndefined(filterFieldConfig) || filterFieldConfig.exclude) {\n continue\n }\n const name = filterFieldConfig.apiName || filterName\n if (filterFieldConfig.type === 'timeInterval' && !isUndefined(filterFieldConfig.related)) {\n const data = resolveTimeIntervalFilter(\n filterName,\n filterFieldConfig.related,\n filterData,\n filterConfig,\n filterFieldConfig.mandatory,\n filterFieldConfig.exclude\n )\n if (isNull(data)) {\n continue\n }\n const filterFieldConfigRelated = fieldConfig(filterConfig, filterFieldConfig.related)\n const nameRelated = filterFieldConfigRelated.apiName || filterFieldConfig.related\n if (isSimpleFilters) {\n queryAdd(name, data.from)\n queryAdd(nameRelated, data.until)\n continue\n }\n if (data.from) queryAddFilter('gte', name, data.from)\n if (data.until) {\n queryAddFilter('lte', nameRelated, data.until)\n }\n continue\n }\n const value = getValue(filterFieldValue, filterFieldConfig)\n if (isNull(value)) {\n continue\n }\n if (isSimpleFilters) {\n queryAdd(name, value)\n continue\n }\n queryAddFilter(filterFieldConfig.variant, name, value)\n }\n }\n\n return {\n resolveTimeIntervalFilter,\n querySetLimit,\n querySetOffset,\n querySetOrder,\n queryAddFilter,\n querySetFilters,\n queryAdd,\n queryBuild,\n q,\n }\n}\n"],"mappings":";;;;;;AAoBA,SAAgBA,IAAqB;CACnC,IAAMC,IAAIC,EAAc,CAAC,CAAC,GAEpBC,KAAiB,MAAwB;EAC7C,EAAS,SAASC,CAAK;CACzB,GAEMC,KAAkB,GAAc,MAAwB;EAC5D,EAAS,UAAU,KAAK,IAAI,IAAIC,IAAO,KAAKC,CAAK,CAAC;CACpD,GAEMC,KAAiB,GAAsB,MAAwB;EACnE,AAAI,CAACC,EAAOC,CAAK,KAAKA,EAAM,SAAS,KAAGC,EAAS,WAAWD,IAAQ,KAAKE,IAAOC,EAAU,OAAOA,EAAU,GAAG;CAChH,GAEMC,KAAe,MACfC,EAAUX,CAAK,IACVA,IAAQ,MAAM,MAEhBA,GAGHY,KAAkB,GAA8B,GAAe,MAA2C;EAC9G,AAAIC,EAASb,CAAK,KAAKA,EAAM,WAAW,KACxCH,EAAE,MAAM,KAAK,YAAYiB,IAAgB,MAAMR,IAAQ,OAAOI,EAAYV,CAAK,CAAC;CAClF,GAGMe,KAAe,GAAiC,MAAiB;EACrE,IAAMT,IAAQU,EAAa,OAAOC;EAClC,IAAIC,EAAYZ,CAAK,GAAG,MAAU,MAAM,qCAAqCW,EAAK,oBAAoB;EACtG,OAAOX;CACT,GAEMa,KACJ,GACA,GACA,GACA,GACA,GACA,MAIG;EACH,IAAIC,IAAYC,EAAWC,IACvBC,IAAaF,EAAWG;EAO5B,IANInB,EAAOe,CAAS,KAAKK,KAAa,CAACC,MACrC,IAAYX,EAAYC,GAAcM,CAAQ,CAAC,CAAC,UAE9CjB,EAAOkB,CAAU,KAAKE,KAAa,CAACC,MACtC,IAAaX,EAAYC,GAAcQ,CAAS,CAAC,CAAC,UAEhDX,EAASO,CAAS,KAAKP,EAASU,CAAU,GAC5C,OAAO;GACL,MAAMH;GACN,OAAOG;EACT;EAEF,IAAMI,IAAMC,EAAY,GAClBC,IAAUC,EAAeH,CAAG;EAClC,QAAQP,GAAR;GACE,KAAKW,EAA2B,cAC9B,OAAOC,EAAiBH,GAAS,OAAO,GAAG,EAAK;GAElD,KAAKE,EAA2B,WAC9B,OAAOC,EAAiBH,GAAS,OAAO,IAAI,EAAK;GAEnD,KAAKE,EAA2B,aAC9B,OAAOC,EAAiBH,GAAS,OAAO,IAAI,EAAI;GAElD,SACE,IAAII,EAASb,CAAS,GACpB,OAAO;IACL,MAAMc,EAAUC,EAAkBf,IAAY,IAAIS,CAAO,CAAC;IAC1D,OAAOF;GACT;EAGN;EACA,OAAO;CACT,GAEMS,KAAY,GAA4B,MACxC/B,EAAOL,CAAK,IACVqC,EAAO,aAAa,CAACA,EAAO,WAAW,CAACnB,EAAYmB,EAAO,OAAO,IAC7DC,EAAQD,EAAO,OAAO,IAAIA,EAAO,QAAQ,KAAK,GAAG,IAAIA,EAAO,UAE9D,OAELxB,EAASb,CAAK,IACZA,EAAM,WAAW,IACfqC,EAAO,aAAa,CAACA,EAAO,WAAW,CAACnB,EAAYmB,EAAO,OAAO,KAAK,CAAChC,EAAOgC,EAAO,OAAO,IACxF,mBAAmBC,EAAQD,EAAO,OAAO,IAAIA,EAAO,QAAQ,KAAK,GAAG,IAAIA,EAAO,OAAO,IAExF,OAEF,mBAAmBrC,CAAK,IAE7BsC,EAAQtC,CAAK,IACXA,EAAM,WAAW,IACfqC,EAAO,aAAa,CAACA,EAAO,WAAWC,EAAQD,EAAO,OAAO,IACxDA,EAAO,QAAQ,KAAK,MAAUxB,EAAS0B,CAAI,IAAI,mBAAmBA,CAAI,IAAIA,CAAK,CAAC,CAAC,KAAK,GAAG,IAE3F,OAEFvC,EAAM,KAAK,MAAUa,EAAS0B,CAAI,IAAI,mBAAmBA,CAAI,IAAIA,CAAK,CAAC,CAAC,KAAK,GAAG,IAErFN,EAASjC,CAAK,KAAKW,EAAUX,CAAK,IAC7BA,IAGF,MAGHO,KAAY,GAAa,MAAqB;EAClD,EAAE,MAAM,KAAKiC,IAAM,MAAMxC,CAAK;CAChC;CAoDA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,kBApDuB,GAA6B,MAA0C;GAC9F,IAAMyC,IAAkBzB,EAAa,QAAQ;GAC7C,KAAK,IAAM0B,KAAcrB,GAAY;IACnC,IAAMsB,IAAmBtB,EAAWqB,IAC9BE,IAAoB5B,EAAa,OAAO0B;IAC9C,IAAIxB,EAAY0B,CAAiB,KAAKA,EAAkB,SACtD;IAEF,IAAM3B,IAAO2B,EAAkB,WAAWF;IAC1C,IAAIE,EAAkB,SAAS,kBAAkB,CAAC1B,EAAY0B,EAAkB,OAAO,GAAG;KACxF,IAAMC,IAAO1B,EACXuB,GACAE,EAAkB,SAClBvB,GACAL,GACA4B,EAAkB,WAClBA,EAAkB,OACpB;KACA,IAAIvC,EAAOwC,CAAI,GACb;KAGF,IAAMC,IAD2B/B,EAAYC,GAAc4B,EAAkB,OACzD,CAAA,CAAyB,WAAWA,EAAkB;KAC1E,IAAIH,GAAiB;MAEnB,AADAlC,EAASU,GAAM4B,EAAK,IAAI,GACxBtC,EAASuC,GAAaD,EAAK,KAAK;MAChC;KACF;KAEA,AADIA,EAAK,QAAMjC,EAAe,OAAOK,GAAM4B,EAAK,IAAI,GAChDA,EAAK,SACPjC,EAAe,OAAOkC,GAAaD,EAAK,KAAK;KAE/C;IACF;IACA,IAAM7C,IAAQoC,EAASO,GAAkBC,CAAiB;IAC1D,AAAIvC,EAAOL,CAAK,MAGZyC,IACFlC,EAASU,GAAMjB,CAAK,IAGtBY,EAAegC,EAAkB,SAAS3B,GAAMjB,CAAK;GACvD;EACF;EASE;EACA,kBAzDO,MAAMH,EAAE,MAAM,KAAK,GAAG;EA0D7B;CACF;AACF"}
@@ -9,12 +9,9 @@ export type ExecuteRequestParams<B> = {
9
9
  /** Stops this one call, leaving the instance's other calls alone. */
10
10
  signal?: AbortSignal;
11
11
  /**
12
- * `false`: a failure of this one call is thrown as ever, and not handed to the api error logger.
13
- *
14
- * For a caller that repeats a request on a timer and has reported its first failure already: a poll that
15
- * asks every few seconds through an outage would otherwise write the same failure down each time. It is the
16
- * caller's to say which call that is, call by call; it is not a way to make a kind of request quiet, and an
17
- * instance has no such switch.
12
+ * `false`: a failure of this call is still thrown but not sent to the api error logger.
13
+ * For pollers that already reported the first failure, so an outage
14
+ * is not logged on every tick. It is set per call, not per instance.
18
15
  */
19
16
  report?: boolean;
20
17
  };
@@ -28,60 +25,40 @@ export type UseApiRequestParams = {
28
25
  validationEntity?: string;
29
26
  urlTemplate?: string;
30
27
  urlParams?: UrlParams;
31
- /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */
32
28
  options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>;
33
- /** Each call supersedes the one before it -- the autocomplete shape. */
29
+ /** Each call cancels the previous one, as for autocomplete. */
34
30
  cancelPrevious?: boolean;
35
31
  };
36
32
  export type UseApiRequestReturnType<R, B> = {
37
33
  execute: (params?: ExecuteRequestParams<B>) => Promise<R>;
38
34
  abort: () => void;
39
35
  /**
40
- * True while this instance has a request in flight, false once the last one settles.
41
- *
42
- * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in
43
- * a `finally`, and that `finally` belongs to whichever call ended -- including one that
44
- * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting
45
- * for is still running. This one never dips between a superseded call and the one that replaced it.
46
- *
47
- * Two things to know before replacing a hand-rolled flag with it.
48
- *
49
- * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a
50
- * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it
51
- * for this one turns the spinner off too early. Keep your own where it means more than "this helper
52
- * is working".
53
- *
54
- * It belongs to the instance, so it is only reachable if you hold the instance. A factory that
55
- * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the
56
- * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the
57
- * instance to where the caller lives first.
36
+ * True while this instance has a request in flight. Unlike a caller-cleared
37
+ * `finally` flag, it does not dip when `cancelPrevious` supersedes a call.
38
+ * It covers only this helper's work. Keep your own flag if it also spans follow-up fetches or mapping.
39
+ * It belongs to the instance. A factory that builds one per call cannot
40
+ * expose `loading`, `abort` or `cancelPrevious`, so hoist the instance first.
58
41
  */
59
42
  loading: Ref<boolean>;
60
43
  };
61
44
  /**
62
45
  * A request to an endpoint that always answers with a body.
63
- *
64
- * A response without one is the endpoint breaking its own contract, not an empty answer, so it fails
65
- * like any other error rather than handing back a value the declared type does not admit. An
66
- * endpoint that answers nothing is `useApiCommand`; one that may answer either is `optionalBody`.
67
- *
68
- * `R` excludes `null`, `undefined` and `void` on purpose: those are ways of saying "no body", and a
69
- * caller saying that has chosen the wrong helper. It is also what makes the migration visible --
70
- * every `useApiRequest<void, …>` in the fleet stops compiling and names itself.
46
+ * A response without a body breaks the contract and fails like any other error.
47
+ * Use `useApiCommand` for endpoints that answer nothing, and `optionalBody` for endpoints that may answer either.
48
+ * `R` excludes `null`, `undefined` and `void` on purpose, so `useApiRequest<void, …>` does not compile.
71
49
  */
72
50
  export declare function useApiRequest<R extends NonNullable<unknown>, B = never>(params: UseApiRequestParams & {
73
51
  optionalBody?: false;
74
52
  }): UseApiRequestReturnType<R, B>;
75
53
  /**
76
- * The same, for an endpoint where a body is optional and its absence is a legitimate answer. The
77
- * caller narrows, which is the point -- use it only where the endpoint really is documented that way.
54
+ * Same as above, for an endpoint where a missing body is a legitimate answer. The caller must narrow.
55
+ * Use it only where the endpoint is documented that way.
78
56
  */
79
57
  export declare function useApiRequest<R extends NonNullable<unknown>, B = never>(params: UseApiRequestParams & {
80
58
  optionalBody: true;
81
59
  }): UseApiRequestReturnType<R | undefined, B>;
82
60
  /**
83
- * A request that asks the backend to do something and reads nothing back -- a delete, or a call that
84
- * only starts work and answers 202. Any successful status resolves; a body, if one arrives, is
85
- * ignored rather than typed.
61
+ * A request that reads nothing back, such as a delete or a call that starts work and answers 202.
62
+ * Any successful status resolves. A body, if one arrives, is ignored.
86
63
  */
87
64
  export declare const useApiCommand: <B = never>(params: UseApiRequestParams) => UseApiRequestReturnType<void, B>;
@@ -1 +1 @@
1
- {"version":3,"file":"useApiRequest.js","names":["createRequest","params","abortable","createAbortable","templateOverride","paramsOverride","reported","executeParams","template","isDefined","urlTemplate","resolvedParams","urlParams","url","dispatched","res","isUndefined","AnzuFatalError","requestUrl","replaceUrlParameters","axiosConfig","isNull","body","config","ownedByHelper","options","abortSignal","instance","client","signal","isValidHTTPStatus","AnzuApiResponseCodeError","interpret","requestedUrl","err","context","error","mapApiError","report","useApiRequest","optionalBody","hasBody","useApiCommand"],"sources":["../../../../src/domains/api/composables/useApiRequest.ts"],"sourcesContent":["import { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig, Method } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { Ref } from 'vue'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport {\n type Abortable,\n createAbortable,\n hasBody,\n ownedByHelper,\n requestedUrl,\n} from '@/domains/api/composables/request'\n\nexport type ExecuteRequestParams<B> = {\n urlTemplate?: string\n urlParams?: UrlParams\n body?: B\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n /**\n * `false`: a failure of this one call is thrown as ever, and not handed to the api error logger.\n *\n * For a caller that repeats a request on a timer and has reported its first failure already: a poll that\n * asks every few seconds through an outage would otherwise write the same failure down each time. It is the\n * caller's to say which call that is, call by call; it is not a way to make a kind of request quiet, and an\n * instance has no such switch.\n */\n report?: boolean\n}\n\nexport type UseApiRequestParams = {\n client: AxiosClientFn\n method: Method\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n /** Anything axios takes except what this helper decides: the method, the url, the body and the signal. */\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n /** Each call supersedes the one before it -- the autocomplete shape. */\n cancelPrevious?: boolean\n}\n\nexport type UseApiRequestReturnType<R, B> = {\n execute: (params?: ExecuteRequestParams<B>) => Promise<R>\n abort: () => void\n /**\n * True while this instance has a request in flight, false once the last one settles.\n *\n * It is here so a caller does not have to keep its own: the hand-rolled version is a ref cleared in\n * a `finally`, and that `finally` belongs to whichever call ended -- including one that\n * `cancelPrevious` just superseded, which turns the spinner off while the call the user is waiting\n * for is still running. This one never dips between a superseded call and the one that replaced it.\n *\n * Two things to know before replacing a hand-rolled flag with it.\n *\n * It covers what this helper does and nothing the caller does afterwards. A flag that also spans a\n * follow-up cached fetch, a mapping pass or a second endpoint is not the same flag, and swapping it\n * for this one turns the spinner off too early. Keep your own where it means more than \"this helper\n * is working\".\n *\n * It belongs to the instance, so it is only reachable if you hold the instance. A factory that\n * builds one per call and hands back the promise alone -- `const { execute } = useX()` inside the\n * function that calls it -- cannot expose `loading`, `abort` or `cancelPrevious` at all. Hoist the\n * instance to where the caller lives first.\n */\n loading: Ref<boolean>\n}\n\n// The url is only ever used to say which request the message is about, and a helper that failed\n// before it had one still has to be able to say something. Handed over as a function because\n// building it costs a render and the successful reading of a response does not need it.\ntype Interpret<R> = (res: { status: number; data: unknown }, url: () => string | undefined) => R\n\nconst createRequest = <R, B>(params: UseApiRequestParams, interpret: Interpret<R>): UseApiRequestReturnType<R, B> => {\n const {\n client,\n method,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable: Abortable = createAbortable({ cancelPrevious })\n\n const execute = async (executeParams: ExecuteRequestParams<B> = {}): Promise<R> => {\n const {\n urlTemplate: templateOverride,\n urlParams: paramsOverride,\n body,\n signal,\n report: reported = true,\n } = executeParams\n\n const template = isDefined(templateOverride) ? templateOverride : urlTemplate\n const resolvedParams = isDefined(paramsOverride) ? paramsOverride : urlParams\n // Assigned inside `run`, at the moment there is a url to ask for; undefined until then, which is\n // what a failure before dispatch honestly reports. An empty string is a different answer: that\n // is a call whose url really is the client root, and it gets rendered as one.\n let url: string | undefined\n // The config axios used, kept for the failures this helper raises after reading the response:\n // they are not axios errors and carry no config of their own, and rebuilding one describes the\n // request as the client would send it now rather than as it was sent.\n let dispatched: AxiosRequestConfig | undefined\n\n try {\n const res = await abortable.run((abortSignal) => {\n // Inside `run`, and inside the try with it: `run` opens the generation and, with\n // `cancelPrevious`, stops the call before this one, so a call that throws on its way to the\n // wire still supersedes its predecessor instead of leaving it current. And a caller that\n // forgot the template gets the same error class as every other failure rather than a bare\n // `Error` nothing in the fleet is written to catch.\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n const requestUrl =\n template !== '' && isDefined(resolvedParams) ? replaceUrlParameters(template, resolvedParams) : template\n\n const axiosConfig: AxiosRequestConfig = { method, url: requestUrl }\n // `null` omits the body, as it always has -- a caller that means to send JSON `null` wraps it.\n if (!isNull(body) && !isUndefined(body)) axiosConfig.data = JSON.stringify(body)\n\n // `options` first, then what this helper owns: a caller cannot reach in and set the method,\n // the url, the body or the signal through it. The type says so too; this is for javascript\n // callers and for anything typed loosely enough to slip past it.\n const config = { ...ownedByHelper(options), ...axiosConfig, signal: abortSignal }\n const instance = client()\n\n // Recorded last, when nothing between here and the call can throw any more. A body that will\n // not serialise, or a client factory that fails, is a request that never happened, and the\n // report has to be able to say so rather than name a url nobody asked for.\n url = requestUrl\n\n return instance.request(config)\n }, signal)\n\n dispatched = res.config\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // The url the report will name, so a message and the context beside it cannot disagree about\n // which request failed when an interceptor rewrote it on the way out.\n return interpret(res, () => requestedUrl(client, url, options, undefined, dispatched))\n } catch (err: unknown) {\n // Built once and handed to both, the way the batch does it: half the work on the failure path,\n // and one place that could go wrong instead of two.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n const error = mapApiError(err, context)\n\n throw reported ? report(error, context) : error\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\n/**\n * A request to an endpoint that always answers with a body.\n *\n * A response without one is the endpoint breaking its own contract, not an empty answer, so it fails\n * like any other error rather than handing back a value the declared type does not admit. An\n * endpoint that answers nothing is `useApiCommand`; one that may answer either is `optionalBody`.\n *\n * `R` excludes `null`, `undefined` and `void` on purpose: those are ways of saying \"no body\", and a\n * caller saying that has chosen the wrong helper. It is also what makes the migration visible --\n * every `useApiRequest<void, …>` in the fleet stops compiling and names itself.\n */\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody?: false }\n): UseApiRequestReturnType<R, B>\n/**\n * The same, for an endpoint where a body is optional and its absence is a legitimate answer. The\n * caller narrows, which is the point -- use it only where the endpoint really is documented that way.\n */\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody: true }\n): UseApiRequestReturnType<R | undefined, B>\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody?: boolean }\n): UseApiRequestReturnType<R | undefined, B> {\n const optionalBody = params.optionalBody === true\n\n return createRequest<R | undefined, B>(params, (res, url) => {\n // 204 is decided by status alone, before the body is looked at: it carries none by definition,\n // so anything that arrived with one is not something to hand on. A 202 may legitimately carry a\n // body, which is why it is not in here and falls through to `hasBody` like any other success.\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n if (optionalBody) return undefined\n\n throw new AnzuApiResponseCodeError(res.status)\n }\n\n if (hasBody(res)) return res.data as R\n if (optionalBody) return undefined\n\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + url())\n })\n}\n\n/**\n * A request that asks the backend to do something and reads nothing back -- a delete, or a call that\n * only starts work and answers 202. Any successful status resolves; a body, if one arrives, is\n * ignored rather than typed.\n */\nexport const useApiCommand = <B = never>(params: UseApiRequestParams): UseApiRequestReturnType<void, B> =>\n createRequest<void, B>(params, () => undefined)\n"],"mappings":";;;;;;;;;AAkFA,IAAMA,KAAuB,GAA6B,MAA2D;CACnH,IAAM,EACJ,WACA,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,OACfC,GACEC,IAAuBC,EAAgB,EAAE,kBAAe,CAAC;CA0E/D,OAAO;EAAE,gBAxEc,IAAyC,CAAC,MAAkB;GACjF,IAAM,EACJ,aAAaC,GACb,WAAWC,GACX,SACA,WACA,QAAQC,IAAW,OACjBC,GAEEC,IAAWC,EAAUL,CAAgB,IAAIA,IAAmBM,GAC5DC,IAAiBF,EAAUJ,CAAc,IAAIA,IAAiBO,GAIhEC,GAIAC;GAEJ,IAAI;IACF,IAAMC,IAAM,MAAMb,EAAU,KAAK,MAAgB;KAM/C,IAAIc,EAAYR,CAAQ,GAAG,MAAM,IAAIS,EAAe,KAAA,GAAW,2BAA2B;KAC1F,IAAMC,IACJV,MAAa,MAAMC,EAAUE,CAAc,IAAIQ,EAAqBX,GAAUG,CAAc,IAAIH,GAE5FY,IAAkC;MAAE;MAAQ,KAAKF;KAAW;KAElE,AAAI,CAACG,EAAOC,CAAI,KAAK,CAACN,EAAYM,CAAI,MAAG,EAAY,OAAO,KAAK,UAAUA,CAAI;KAK/E,IAAMC,IAAS;MAAE,GAAGC,EAAcC,CAAO;MAAG,GAAGL;MAAa,QAAQM;KAAY,GAC1EC,IAAWC,EAAO;KAOxB,OAFA,IAAMV,GAECS,EAAS,QAAQJ,CAAM;IAChC,GAAGM,CAAM;IAGT,IADA,IAAad,EAAI,QACb,CAACe,EAAkBf,EAAI,MAAM,GAAG,MAAM,IAAIgB,EAAyBhB,EAAI,MAAM;IAIjF,OAAOiB,EAAUjB,SAAWkB,EAAaL,GAAQf,GAAKY,GAAS,KAAA,GAAWX,CAAU,CAAC;GACvF,SAASoB,GAAc;IAGrB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKF,EAAaL,GAAQf,GAAKY,GAASS,GAAKpB,CAAU;IACzD,GAEMsB,IAAQC,EAAYH,GAAKC,CAAO;IAEtC,MAAM7B,IAAWgC,EAAOF,GAAOD,CAAO,IAAIC;GAC5C;EACF;EAEkB,OAAOlC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE;AAuBA,SAAgBqC,EACd,GAC2C;CAC3C,IAAMC,IAAevC,EAAO,iBAAiB;CAE7C,OAAOD,EAAgCC,IAAS,GAAK,MAAQ;EAI3D,IAAIc,EAAI,WAAA,KAAmC;GACzC,IAAIyB,GAAc;GAElB,MAAM,IAAIT,EAAyBhB,EAAI,MAAM;EAC/C;EAEA,IAAI0B,EAAQ1B,CAAG,GAAG,OAAOA,EAAI;EAC7B,IAAI,IAEJ,MAAM,IAAIgB,EAAyBhB,EAAI,QAAQ,KAAA,GAAW,oCAAoCF,EAAI,CAAC;CACrG,CAAC;AACH;AAOA,IAAa6B,KAA4B,MACvC1C,EAAuBC,SAAc,KAAA,CAAS"}
1
+ {"version":3,"file":"useApiRequest.js","names":["createRequest","params","abortable","createAbortable","templateOverride","paramsOverride","reported","executeParams","template","isDefined","urlTemplate","resolvedParams","urlParams","url","dispatched","res","isUndefined","AnzuFatalError","requestUrl","replaceUrlParameters","axiosConfig","isNull","body","config","ownedByHelper","options","abortSignal","instance","client","signal","isValidHTTPStatus","AnzuApiResponseCodeError","interpret","requestedUrl","err","context","error","mapApiError","report","useApiRequest","optionalBody","hasBody","useApiCommand"],"sources":["../../../../src/domains/api/composables/useApiRequest.ts"],"sourcesContent":["import { AnzuApiResponseCodeError } from '@/shared/error/AnzuApiResponseCodeError'\nimport { AnzuFatalError } from '@/shared/error/AnzuFatalError'\nimport { replaceUrlParameters, type UrlParams } from '@/domains/api/utils/apiHelper'\nimport { isDefined, isNull, isUndefined } from '@/shared/utils/common'\nimport { isValidHTTPStatus } from '@/domains/api/utils/response'\nimport type { AxiosRequestConfig, Method } from 'axios'\nimport { HTTP_STATUS_NO_CONTENT } from '@/shared/statusCodes'\nimport type { Ref } from 'vue'\nimport type { AxiosClientFn } from '@/domains/api/utils/client'\nimport { mapApiError, report } from '@/domains/api/utils/apiErrors'\nimport {\n type Abortable,\n createAbortable,\n hasBody,\n ownedByHelper,\n requestedUrl,\n} from '@/domains/api/composables/request'\n\nexport type ExecuteRequestParams<B> = {\n urlTemplate?: string\n urlParams?: UrlParams\n body?: B\n /** Stops this one call, leaving the instance's other calls alone. */\n signal?: AbortSignal\n /**\n * `false`: a failure of this call is still thrown but not sent to the api error logger.\n * For pollers that already reported the first failure, so an outage\n * is not logged on every tick. It is set per call, not per instance.\n */\n report?: boolean\n}\n\nexport type UseApiRequestParams = {\n client: AxiosClientFn\n method: Method\n system: string\n entity: string\n /** i18n scope for field-level validation failures; defaults to `system` / `entity`. */\n validationSystem?: string\n validationEntity?: string\n urlTemplate?: string\n urlParams?: UrlParams\n options?: Omit<AxiosRequestConfig, 'method' | 'url' | 'data' | 'signal'>\n /** Each call cancels the previous one, as for autocomplete. */\n cancelPrevious?: boolean\n}\n\nexport type UseApiRequestReturnType<R, B> = {\n execute: (params?: ExecuteRequestParams<B>) => Promise<R>\n abort: () => void\n /**\n * True while this instance has a request in flight. Unlike a caller-cleared\n * `finally` flag, it does not dip when `cancelPrevious` supersedes a call.\n * It covers only this helper's work. Keep your own flag if it also spans follow-up fetches or mapping.\n * It belongs to the instance. A factory that builds one per call cannot\n * expose `loading`, `abort` or `cancelPrevious`, so hoist the instance first.\n */\n loading: Ref<boolean>\n}\n\n// The url only identifies the request in error messages, and may be missing if the helper failed before\n// building it. It is a function because building it costs a render that successful reads do not need.\ntype Interpret<R> = (res: { status: number; data: unknown }, url: () => string | undefined) => R\n\nconst createRequest = <R, B>(params: UseApiRequestParams, interpret: Interpret<R>): UseApiRequestReturnType<R, B> => {\n const {\n client,\n method,\n system,\n entity,\n validationSystem,\n validationEntity,\n urlTemplate,\n urlParams,\n options = {},\n cancelPrevious = false,\n } = params\n const abortable: Abortable = createAbortable({ cancelPrevious })\n\n const execute = async (executeParams: ExecuteRequestParams<B> = {}): Promise<R> => {\n const {\n urlTemplate: templateOverride,\n urlParams: paramsOverride,\n body,\n signal,\n report: reported = true,\n } = executeParams\n\n const template = isDefined(templateOverride) ? templateOverride : urlTemplate\n const resolvedParams = isDefined(paramsOverride) ? paramsOverride : urlParams\n // Set in `run` once there is a url. `undefined` means the failure happened before\n // dispatch. An empty string is a real url (the client root) and is rendered as such.\n let url: string | undefined\n // The config axios actually sent. Errors raised after reading the response are not axios errors and have\n // no config. Rebuilding one would describe the request as it would be sent now, not as it was sent.\n let dispatched: AxiosRequestConfig | undefined\n\n try {\n const res = await abortable.run((abortSignal) => {\n // Throw inside `run` and its try. `run` opens the generation and, with `cancelPrevious`,\n // stops the previous call, so a call that throws before sending still supersedes it.\n // It also gives a missing template the same error class as other failures, not a bare `Error`.\n if (isUndefined(template)) throw new AnzuFatalError(undefined, 'Url template is undefined')\n const requestUrl =\n template !== '' && isDefined(resolvedParams) ? replaceUrlParameters(template, resolvedParams) : template\n\n const axiosConfig: AxiosRequestConfig = { method, url: requestUrl }\n // `null` omits the body. To send JSON `null`, the caller wraps it.\n if (!isNull(body) && !isUndefined(body)) axiosConfig.data = JSON.stringify(body)\n\n // `options` goes first so a caller cannot override the method, url, body or signal.\n // The type already forbids this. The spread order protects JavaScript and loosely typed callers.\n const config = { ...ownedByHelper(options), ...axiosConfig, signal: abortSignal }\n const instance = client()\n\n // Set `url` last, when nothing before the call can throw.\n // If serialising the body or the client factory fails, no request happened and the report must not name a url.\n url = requestUrl\n\n return instance.request(config)\n }, signal)\n\n dispatched = res.config\n if (!isValidHTTPStatus(res.status)) throw new AnzuApiResponseCodeError(res.status)\n\n // The url the report names, so the message and context agree when an interceptor rewrote the request.\n return interpret(res, () => requestedUrl(client, url, options, undefined, dispatched))\n } catch (err: unknown) {\n // Built once and shared by both, as in the batch.\n const context = {\n system,\n entity,\n validationSystem,\n validationEntity,\n url: requestedUrl(client, url, options, err, dispatched),\n }\n\n const error = mapApiError(err, context)\n\n throw reported ? report(error, context) : error\n }\n }\n\n return { execute, abort: abortable.abort, loading: abortable.loading }\n}\n\n/**\n * A request to an endpoint that always answers with a body.\n * A response without a body breaks the contract and fails like any other error.\n * Use `useApiCommand` for endpoints that answer nothing, and `optionalBody` for endpoints that may answer either.\n * `R` excludes `null`, `undefined` and `void` on purpose, so `useApiRequest<void, …>` does not compile.\n */\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody?: false }\n): UseApiRequestReturnType<R, B>\n/**\n * Same as above, for an endpoint where a missing body is a legitimate answer. The caller must narrow.\n * Use it only where the endpoint is documented that way.\n */\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody: true }\n): UseApiRequestReturnType<R | undefined, B>\nexport function useApiRequest<R extends NonNullable<unknown>, B = never>(\n params: UseApiRequestParams & { optionalBody?: boolean }\n): UseApiRequestReturnType<R | undefined, B> {\n const optionalBody = params.optionalBody === true\n\n return createRequest<R | undefined, B>(params, (res, url) => {\n // 204 is decided by status alone, because it carries no body by definition.\n // 202 may carry a body, so it falls through to `hasBody` like any other success.\n if (res.status === HTTP_STATUS_NO_CONTENT) {\n if (optionalBody) return undefined\n\n throw new AnzuApiResponseCodeError(res.status)\n }\n\n if (hasBody(res)) return res.data as R\n if (optionalBody) return undefined\n\n throw new AnzuApiResponseCodeError(res.status, undefined, 'Expected a response body, url: ' + url())\n })\n}\n\n/**\n * A request that reads nothing back, such as a delete or a call that starts work and answers 202.\n * Any successful status resolves. A body, if one arrives, is ignored.\n */\nexport const useApiCommand = <B = never>(params: UseApiRequestParams): UseApiRequestReturnType<void, B> =>\n createRequest<void, B>(params, () => undefined)\n"],"mappings":";;;;;;;;;AAgEA,IAAMA,KAAuB,GAA6B,MAA2D;CACnH,IAAM,EACJ,WACA,WACA,WACA,WACA,qBACA,qBACA,gBACA,cACA,aAAU,CAAC,GACX,oBAAiB,OACfC,GACEC,IAAuBC,EAAgB,EAAE,kBAAe,CAAC;CAkE/D,OAAO;EAAE,gBAhEc,IAAyC,CAAC,MAAkB;GACjF,IAAM,EACJ,aAAaC,GACb,WAAWC,GACX,SACA,WACA,QAAQC,IAAW,OACjBC,GAEEC,IAAWC,EAAUL,CAAgB,IAAIA,IAAmBM,GAC5DC,IAAiBF,EAAUJ,CAAc,IAAIA,IAAiBO,GAGhEC,GAGAC;GAEJ,IAAI;IACF,IAAMC,IAAM,MAAMb,EAAU,KAAK,MAAgB;KAI/C,IAAIc,EAAYR,CAAQ,GAAG,MAAM,IAAIS,EAAe,KAAA,GAAW,2BAA2B;KAC1F,IAAMC,IACJV,MAAa,MAAMC,EAAUE,CAAc,IAAIQ,EAAqBX,GAAUG,CAAc,IAAIH,GAE5FY,IAAkC;MAAE;MAAQ,KAAKF;KAAW;KAElE,AAAI,CAACG,EAAOC,CAAI,KAAK,CAACN,EAAYM,CAAI,MAAG,EAAY,OAAO,KAAK,UAAUA,CAAI;KAI/E,IAAMC,IAAS;MAAE,GAAGC,EAAcC,CAAO;MAAG,GAAGL;MAAa,QAAQM;KAAY,GAC1EC,IAAWC,EAAO;KAMxB,OAFA,IAAMV,GAECS,EAAS,QAAQJ,CAAM;IAChC,GAAGM,CAAM;IAGT,IADA,IAAad,EAAI,QACb,CAACe,EAAkBf,EAAI,MAAM,GAAG,MAAM,IAAIgB,EAAyBhB,EAAI,MAAM;IAGjF,OAAOiB,EAAUjB,SAAWkB,EAAaL,GAAQf,GAAKY,GAAS,KAAA,GAAWX,CAAU,CAAC;GACvF,SAASoB,GAAc;IAErB,IAAMC,IAAU;KACd;KACA;KACA;KACA;KACA,KAAKF,EAAaL,GAAQf,GAAKY,GAASS,GAAKpB,CAAU;IACzD,GAEMsB,IAAQC,EAAYH,GAAKC,CAAO;IAEtC,MAAM7B,IAAWgC,EAAOF,GAAOD,CAAO,IAAIC;GAC5C;EACF;EAEkB,OAAOlC,EAAU;EAAO,SAASA,EAAU;CAAQ;AACvE;AAkBA,SAAgBqC,EACd,GAC2C;CAC3C,IAAMC,IAAevC,EAAO,iBAAiB;CAE7C,OAAOD,EAAgCC,IAAS,GAAK,MAAQ;EAG3D,IAAIc,EAAI,WAAA,KAAmC;GACzC,IAAIyB,GAAc;GAElB,MAAM,IAAIT,EAAyBhB,EAAI,MAAM;EAC/C;EAEA,IAAI0B,EAAQ1B,CAAG,GAAG,OAAOA,EAAI;EAC7B,IAAI,IAEJ,MAAM,IAAIgB,EAAyBhB,EAAI,QAAQ,KAAA,GAAW,oCAAoCF,EAAI,CAAC;CACrG,CAAC;AACH;AAMA,IAAa6B,KAA4B,MACvC1C,EAAuBC,SAAc,KAAA,CAAS"}