@lenne.tech/ng-base 18.1.3 → 22.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/CLAUDE.md +55 -0
  2. package/LICENSE +2 -2
  3. package/README.md +237 -44
  4. package/fesm2022/lenne.tech-ng-base-ai.mjs +771 -0
  5. package/fesm2022/lenne.tech-ng-base-ai.mjs.map +1 -0
  6. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs +945 -0
  7. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs.map +1 -0
  8. package/fesm2022/lenne.tech-ng-base-auth.mjs +454 -0
  9. package/fesm2022/lenne.tech-ng-base-auth.mjs.map +1 -0
  10. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs +825 -0
  11. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs.map +1 -0
  12. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs +351 -0
  13. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs.map +1 -0
  14. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs +1046 -0
  15. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs.map +1 -0
  16. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs +4 -0
  17. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs.map +1 -0
  18. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs +179 -0
  19. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs.map +1 -0
  20. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs +26 -0
  21. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs.map +1 -0
  22. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs +62 -0
  23. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs.map +1 -0
  24. package/fesm2022/lenne.tech-ng-base-bug-server.mjs +818 -0
  25. package/fesm2022/lenne.tech-ng-base-bug-server.mjs.map +1 -0
  26. package/fesm2022/lenne.tech-ng-base-bug.mjs +196 -0
  27. package/fesm2022/lenne.tech-ng-base-bug.mjs.map +1 -0
  28. package/fesm2022/lenne.tech-ng-base-files-ui.mjs +445 -0
  29. package/fesm2022/lenne.tech-ng-base-files-ui.mjs.map +1 -0
  30. package/fesm2022/lenne.tech-ng-base-files.mjs +474 -0
  31. package/fesm2022/lenne.tech-ng-base-files.mjs.map +1 -0
  32. package/fesm2022/lenne.tech-ng-base-server.mjs +408 -0
  33. package/fesm2022/lenne.tech-ng-base-server.mjs.map +1 -0
  34. package/fesm2022/lenne.tech-ng-base-share.mjs +76 -0
  35. package/fesm2022/lenne.tech-ng-base-share.mjs.map +1 -0
  36. package/fesm2022/lenne.tech-ng-base-sync.mjs +1096 -0
  37. package/fesm2022/lenne.tech-ng-base-sync.mjs.map +1 -0
  38. package/fesm2022/lenne.tech-ng-base-testing.mjs +171 -0
  39. package/fesm2022/lenne.tech-ng-base-testing.mjs.map +1 -0
  40. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs +124 -0
  41. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs.map +1 -0
  42. package/fesm2022/lenne.tech-ng-base-ui.mjs +34645 -0
  43. package/fesm2022/lenne.tech-ng-base-ui.mjs.map +1 -0
  44. package/fesm2022/lenne.tech-ng-base-utils.mjs +287 -0
  45. package/fesm2022/lenne.tech-ng-base-utils.mjs.map +1 -0
  46. package/fesm2022/lenne.tech-ng-base.mjs +615 -910
  47. package/fesm2022/lenne.tech-ng-base.mjs.map +1 -1
  48. package/i18n/auth/de.json +17 -0
  49. package/i18n/auth/en.json +17 -0
  50. package/i18n/bug/de.json +85 -0
  51. package/i18n/bug/en.json +85 -0
  52. package/i18n/de.json +8 -0
  53. package/i18n/en.json +8 -0
  54. package/i18n/files/de.json +27 -0
  55. package/i18n/files/en.json +27 -0
  56. package/i18n/share/de.json +8 -0
  57. package/i18n/share/en.json +8 -0
  58. package/i18n/ui/de.json +38 -0
  59. package/i18n/ui/en.json +38 -0
  60. package/package.json +127 -58
  61. package/types/lenne.tech-ng-base-ai.d.ts +845 -0
  62. package/types/lenne.tech-ng-base-auth-provide.d.ts +604 -0
  63. package/types/lenne.tech-ng-base-auth.d.ts +320 -0
  64. package/types/lenne.tech-ng-base-bug-provide.d.ts +272 -0
  65. package/types/lenne.tech-ng-base-bug-rolldown-runtime-C25Le4-w.d.ts +1 -0
  66. package/types/lenne.tech-ng-base-bug-server.d.ts +316 -0
  67. package/types/lenne.tech-ng-base-bug.d.ts +202 -0
  68. package/types/lenne.tech-ng-base-files-ui.d.ts +116 -0
  69. package/types/lenne.tech-ng-base-files.d.ts +288 -0
  70. package/types/lenne.tech-ng-base-server.d.ts +262 -0
  71. package/types/lenne.tech-ng-base-share.d.ts +21 -0
  72. package/types/lenne.tech-ng-base-sync.d.ts +380 -0
  73. package/types/lenne.tech-ng-base-testing.d.ts +327 -0
  74. package/types/lenne.tech-ng-base-ui-provide.d.ts +65 -0
  75. package/types/lenne.tech-ng-base-ui.d.ts +7744 -0
  76. package/types/lenne.tech-ng-base-utils.d.ts +150 -0
  77. package/types/lenne.tech-ng-base.d.ts +503 -0
  78. package/ui/styles/components/accordion.css +3 -0
  79. package/ui/styles/components/alert-dialog.css +4 -0
  80. package/ui/styles/components/alert.css +3 -0
  81. package/ui/styles/components/aspect-ratio.css +3 -0
  82. package/ui/styles/components/attachment.css +4 -0
  83. package/ui/styles/components/autocomplete.css +4 -0
  84. package/ui/styles/components/avatar.css +3 -0
  85. package/ui/styles/components/badge.css +3 -0
  86. package/ui/styles/components/breadcrumb.css +3 -0
  87. package/ui/styles/components/bubble.css +3 -0
  88. package/ui/styles/components/button-group.css +3 -0
  89. package/ui/styles/components/button.css +3 -0
  90. package/ui/styles/components/calendar.css +5 -0
  91. package/ui/styles/components/card.css +3 -0
  92. package/ui/styles/components/checkbox.css +3 -0
  93. package/ui/styles/components/code-block.css +4 -0
  94. package/ui/styles/components/collapsible.css +3 -0
  95. package/ui/styles/components/combobox.css +5 -0
  96. package/ui/styles/components/command.css +5 -0
  97. package/ui/styles/components/context-menu.css +3 -0
  98. package/ui/styles/components/date-picker.css +7 -0
  99. package/ui/styles/components/dialog.css +4 -0
  100. package/ui/styles/components/drawer.css +3 -0
  101. package/ui/styles/components/dropdown-menu.css +3 -0
  102. package/ui/styles/components/empty.css +3 -0
  103. package/ui/styles/components/field.css +5 -0
  104. package/ui/styles/components/hover-card.css +3 -0
  105. package/ui/styles/components/index.css +91 -0
  106. package/ui/styles/components/input-group.css +6 -0
  107. package/ui/styles/components/input-otp.css +3 -0
  108. package/ui/styles/components/input.css +3 -0
  109. package/ui/styles/components/item.css +4 -0
  110. package/ui/styles/components/kbd.css +3 -0
  111. package/ui/styles/components/label.css +3 -0
  112. package/ui/styles/components/lt-breadcrumb.css +3 -0
  113. package/ui/styles/components/lt-bug-attachments.css +5 -0
  114. package/ui/styles/components/lt-bug-journey-timeline.css +5 -0
  115. package/ui/styles/components/lt-bug-report-dialog.css +15 -0
  116. package/ui/styles/components/lt-bug-report.css +4 -0
  117. package/ui/styles/components/lt-color-mode-button.css +3 -0
  118. package/ui/styles/components/lt-confirm-dialog.css +4 -0
  119. package/ui/styles/components/lt-data-view.css +5 -0
  120. package/ui/styles/components/lt-date-picker.css +3 -0
  121. package/ui/styles/components/lt-date-time-picker.css +5 -0
  122. package/ui/styles/components/lt-enter-action.css +2 -0
  123. package/ui/styles/components/lt-footer.css +3 -0
  124. package/ui/styles/components/lt-form-field.css +4 -0
  125. package/ui/styles/components/lt-header.css +5 -0
  126. package/ui/styles/components/lt-imports.css +21 -0
  127. package/ui/styles/components/lt-navigation-menu.css +3 -0
  128. package/ui/styles/components/lt-notice.css +3 -0
  129. package/ui/styles/components/lt-overlay-defaults.css +3 -0
  130. package/ui/styles/components/lt-page-card.css +3 -0
  131. package/ui/styles/components/lt-page-title.css +2 -0
  132. package/ui/styles/components/lt-password-input.css +4 -0
  133. package/ui/styles/components/lt-readonly-field.css +2 -0
  134. package/ui/styles/components/lt-select.css +4 -0
  135. package/ui/styles/components/lt-text-field.css +5 -0
  136. package/ui/styles/components/lt-toolbar-item.css +2 -0
  137. package/ui/styles/components/lt-toolbar.css +3 -0
  138. package/ui/styles/components/lt-tus-upload-component.css +5 -0
  139. package/ui/styles/components/marker.css +3 -0
  140. package/ui/styles/components/menubar.css +3 -0
  141. package/ui/styles/components/message-scroller.css +4 -0
  142. package/ui/styles/components/message.css +3 -0
  143. package/ui/styles/components/native-select.css +3 -0
  144. package/ui/styles/components/navigation-menu.css +3 -0
  145. package/ui/styles/components/pagination.css +4 -0
  146. package/ui/styles/components/popover.css +3 -0
  147. package/ui/styles/components/progress.css +3 -0
  148. package/ui/styles/components/questionnaire.css +4 -0
  149. package/ui/styles/components/radio-group.css +3 -0
  150. package/ui/styles/components/resizable.css +3 -0
  151. package/ui/styles/components/select.css +3 -0
  152. package/ui/styles/components/separator.css +3 -0
  153. package/ui/styles/components/sheet.css +4 -0
  154. package/ui/styles/components/sidebar.css +9 -0
  155. package/ui/styles/components/skeleton.css +3 -0
  156. package/ui/styles/components/slider.css +3 -0
  157. package/ui/styles/components/sonner.css +4 -0
  158. package/ui/styles/components/spinner.css +3 -0
  159. package/ui/styles/components/switch.css +3 -0
  160. package/ui/styles/components/table.css +3 -0
  161. package/ui/styles/components/tabs.css +4 -0
  162. package/ui/styles/components/textarea.css +3 -0
  163. package/ui/styles/components/toggle-group.css +4 -0
  164. package/ui/styles/components/toggle.css +3 -0
  165. package/ui/styles/components/tooltip.css +3 -0
  166. package/ui/styles/components/trace.css +3 -0
  167. package/ui/styles/components/typography.css +3 -0
  168. package/ui/styles/components/utils.css +2 -0
  169. package/ui/styles/core.css +137 -0
  170. package/ui/styles/palette.css +94 -0
  171. package/ui/styles/theme.css +14 -0
  172. package/ui/styles/transitions.css +131 -0
  173. package/base-cms/index.d.ts +0 -5
  174. package/base-cms/interfaces/base-cms-module-config.interface.d.ts +0 -16
  175. package/base-cms/pages/base-cms/base-cms.component.d.ts +0 -92
  176. package/base-cms/public-api.d.ts +0 -5
  177. package/base-components/components/breadcrumb/breadcrumb.component.d.ts +0 -10
  178. package/base-components/components/change-password/change-password.component.d.ts +0 -24
  179. package/base-components/components/checkbox/checkbox.component.d.ts +0 -12
  180. package/base-components/components/delete-account/delete-account.component.d.ts +0 -15
  181. package/base-components/components/fab-button/fab-button.component.d.ts +0 -16
  182. package/base-components/components/input/input.component.d.ts +0 -27
  183. package/base-components/components/loading-bar/loading-bar.component.d.ts +0 -17
  184. package/base-components/components/model-form/model-form-base.component.d.ts +0 -64
  185. package/base-components/components/model-form/model-form.component.d.ts +0 -139
  186. package/base-components/components/model-form-sub/model-form-sub.component.d.ts +0 -56
  187. package/base-components/components/model-table/model-table.component.d.ts +0 -115
  188. package/base-components/components/refence-input/refence-input.component.d.ts +0 -84
  189. package/base-components/components/select/select.component.d.ts +0 -25
  190. package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +0 -10
  191. package/base-components/components/tags/tags.component.d.ts +0 -60
  192. package/base-components/components/textarea/textarea.component.d.ts +0 -21
  193. package/base-components/components/toast/toast.component.d.ts +0 -19
  194. package/base-components/components/upload-image/upload-image.component.d.ts +0 -111
  195. package/base-components/directives/back-button.directive.d.ts +0 -9
  196. package/base-components/directives/context-menu.directive.d.ts +0 -22
  197. package/base-components/directives/sort.directive.d.ts +0 -15
  198. package/base-components/directives/stop-propagation.directive.d.ts +0 -10
  199. package/base-components/index.d.ts +0 -5
  200. package/base-components/pipes/ellipses.pipe.d.ts +0 -10
  201. package/base-components/public-api.d.ts +0 -26
  202. package/base-prototype/index.d.ts +0 -5
  203. package/base-prototype/pages/email-verification/email-verification.component.d.ts +0 -18
  204. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +0 -26
  205. package/base-prototype/pages/login/login.component.d.ts +0 -33
  206. package/base-prototype/pages/profile/profile.component.d.ts +0 -24
  207. package/base-prototype/pages/register/register.component.d.ts +0 -31
  208. package/base-prototype/pages/set-password/set-password.component.d.ts +0 -29
  209. package/base-prototype/public-api.d.ts +0 -9
  210. package/esm2022/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -3
  211. package/esm2022/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -5
  212. package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +0 -238
  213. package/esm2022/base-cms/public-api.mjs +0 -8
  214. package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -23
  215. package/esm2022/base-components/components/change-password/change-password.component.mjs +0 -97
  216. package/esm2022/base-components/components/checkbox/checkbox.component.mjs +0 -38
  217. package/esm2022/base-components/components/delete-account/delete-account.component.mjs +0 -59
  218. package/esm2022/base-components/components/fab-button/fab-button.component.mjs +0 -24
  219. package/esm2022/base-components/components/input/input.component.mjs +0 -75
  220. package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +0 -37
  221. package/esm2022/base-components/components/model-form/model-form-base.component.mjs +0 -145
  222. package/esm2022/base-components/components/model-form/model-form.component.mjs +0 -591
  223. package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -117
  224. package/esm2022/base-components/components/model-table/model-table.component.mjs +0 -478
  225. package/esm2022/base-components/components/refence-input/refence-input.component.mjs +0 -278
  226. package/esm2022/base-components/components/select/select.component.mjs +0 -62
  227. package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -33
  228. package/esm2022/base-components/components/tags/tags.component.mjs +0 -227
  229. package/esm2022/base-components/components/textarea/textarea.component.mjs +0 -79
  230. package/esm2022/base-components/components/toast/toast.component.mjs +0 -69
  231. package/esm2022/base-components/components/upload-image/upload-image.component.mjs +0 -346
  232. package/esm2022/base-components/directives/back-button.directive.mjs +0 -25
  233. package/esm2022/base-components/directives/context-menu.directive.mjs +0 -112
  234. package/esm2022/base-components/directives/sort.directive.mjs +0 -61
  235. package/esm2022/base-components/directives/stop-propagation.directive.mjs +0 -24
  236. package/esm2022/base-components/lenne.tech-ng-base-base-components.mjs +0 -5
  237. package/esm2022/base-components/pipes/ellipses.pipe.mjs +0 -23
  238. package/esm2022/base-components/public-api.mjs +0 -30
  239. package/esm2022/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -5
  240. package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +0 -60
  241. package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -78
  242. package/esm2022/base-prototype/pages/login/login.component.mjs +0 -114
  243. package/esm2022/base-prototype/pages/profile/profile.component.mjs +0 -87
  244. package/esm2022/base-prototype/pages/register/register.component.mjs +0 -100
  245. package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +0 -91
  246. package/esm2022/base-prototype/public-api.mjs +0 -11
  247. package/esm2022/lenne.tech-ng-base.mjs +0 -5
  248. package/esm2022/public-api.mjs +0 -25
  249. package/esm2022/shared/classes/auth.class.mjs +0 -14
  250. package/esm2022/shared/classes/basic-user.class.mjs +0 -49
  251. package/esm2022/shared/classes/graphql-enum.class.mjs +0 -10
  252. package/esm2022/shared/classes/graphql-meta.class.mjs +0 -345
  253. package/esm2022/shared/classes/graphql-type.class.mjs +0 -14
  254. package/esm2022/shared/classes/helper.class.mjs +0 -307
  255. package/esm2022/shared/classes/sort.class.mjs +0 -38
  256. package/esm2022/shared/classes/standard.class.mjs +0 -40
  257. package/esm2022/shared/decorators/debounce.decorator.mjs +0 -12
  258. package/esm2022/shared/enums/comparison-operator.enum.mjs +0 -16
  259. package/esm2022/shared/enums/graphql-request-type.enum.mjs +0 -10
  260. package/esm2022/shared/enums/logical-operator.enum.mjs +0 -10
  261. package/esm2022/shared/enums/skeleton-type.enum.mjs +0 -7
  262. package/esm2022/shared/enums/sort-order.enum.mjs +0 -6
  263. package/esm2022/shared/enums/toast-type.enum.mjs +0 -8
  264. package/esm2022/shared/functions/ws-client.function.mjs +0 -39
  265. package/esm2022/shared/interfaces/base-module-config.interface.mjs +0 -3
  266. package/esm2022/shared/interfaces/breadcrumb.interface.mjs +0 -2
  267. package/esm2022/shared/interfaces/can-component-deactivate.interface.mjs +0 -2
  268. package/esm2022/shared/interfaces/cms-enum-values.interface.mjs +0 -2
  269. package/esm2022/shared/interfaces/cms-field-config.interface.mjs +0 -2
  270. package/esm2022/shared/interfaces/cms-model-config.interface.mjs +0 -2
  271. package/esm2022/shared/interfaces/cms-table-field.interface.mjs +0 -2
  272. package/esm2022/shared/interfaces/combined-filter-input.interface.mjs +0 -2
  273. package/esm2022/shared/interfaces/compress-options.interface.mjs +0 -2
  274. package/esm2022/shared/interfaces/cropping-options.interface.mjs +0 -2
  275. package/esm2022/shared/interfaces/field-object.interface.mjs +0 -2
  276. package/esm2022/shared/interfaces/field.interface.mjs +0 -2
  277. package/esm2022/shared/interfaces/filter-input.interface.mjs +0 -2
  278. package/esm2022/shared/interfaces/find-args.interface.mjs +0 -2
  279. package/esm2022/shared/interfaces/graphql-crud-type.interface.mjs +0 -2
  280. package/esm2022/shared/interfaces/graphql-fields-object.interface.mjs +0 -2
  281. package/esm2022/shared/interfaces/graphql-options.interface.mjs +0 -2
  282. package/esm2022/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  283. package/esm2022/shared/interfaces/graphql-type-collection.interface.mjs +0 -2
  284. package/esm2022/shared/interfaces/login-config.interface.mjs +0 -2
  285. package/esm2022/shared/interfaces/register-config.interface.mjs +0 -2
  286. package/esm2022/shared/interfaces/single-filter-input.interface.mjs +0 -2
  287. package/esm2022/shared/interfaces/sort-input.interface.mjs +0 -2
  288. package/esm2022/shared/interfaces/time-components.interface.mjs +0 -2
  289. package/esm2022/shared/interfaces/toast.interface.mjs +0 -2
  290. package/esm2022/shared/lenne.tech-ng-base-shared.mjs +0 -5
  291. package/esm2022/shared/public-api.mjs +0 -74
  292. package/esm2022/shared/services/auth.service.mjs +0 -152
  293. package/esm2022/shared/services/breadcrumb.service.mjs +0 -69
  294. package/esm2022/shared/services/cms.service.mjs +0 -82
  295. package/esm2022/shared/services/file.service.mjs +0 -86
  296. package/esm2022/shared/services/forms.service.mjs +0 -61
  297. package/esm2022/shared/services/graphql-meta.service.mjs +0 -132
  298. package/esm2022/shared/services/graphql-plus.service.mjs +0 -93
  299. package/esm2022/shared/services/graphql.service.mjs +0 -510
  300. package/esm2022/shared/services/image.service.mjs +0 -102
  301. package/esm2022/shared/services/loader.service.mjs +0 -78
  302. package/esm2022/shared/services/navigation.service.mjs +0 -38
  303. package/esm2022/shared/services/scroll.service.mjs +0 -207
  304. package/esm2022/shared/services/storage.service.mjs +0 -149
  305. package/esm2022/shared/services/toast.service.mjs +0 -39
  306. package/esm2022/shared/services/user.service.mjs +0 -160
  307. package/esm2022/shared/services/ws.service.mjs +0 -17
  308. package/esm2022/shared/types/graphql-fields.type.mjs +0 -2
  309. package/esm2022/shared/types/storage.type.mjs +0 -2
  310. package/esm2022/shared/validators/email.validator.mjs +0 -7
  311. package/esm2022/shared/validators/match.validator.mjs +0 -22
  312. package/esm2022/shared/validators/secure-password.validator.mjs +0 -7
  313. package/esm2022/src/base.module.mjs +0 -64
  314. package/esm2022/src/decorators/auto-unsubscribe.decorator.mjs +0 -23
  315. package/esm2022/src/directives/lazy-load.directive.mjs +0 -48
  316. package/esm2022/src/directives/match-height.directive.mjs +0 -92
  317. package/esm2022/src/directives/resizable.directive.mjs +0 -92
  318. package/esm2022/src/factories/apollo-options.factory.mjs +0 -108
  319. package/esm2022/src/functions/extract-files.function.mjs +0 -87
  320. package/esm2022/src/guards/auth.guard.mjs +0 -91
  321. package/esm2022/src/guards/can-deactivate.guard.mjs +0 -16
  322. package/esm2022/src/guards/logout.guard.mjs +0 -34
  323. package/esm2022/src/pipes/date-ago.pipe.mjs +0 -64
  324. package/esm2022/src/pipes/safe-html.pipe.mjs +0 -22
  325. package/esm2022/src/services/fullscreen.service.mjs +0 -51
  326. package/esm2022/src/services/seo.service.mjs +0 -117
  327. package/esm2022/src/services/theme.service.mjs +0 -44
  328. package/fesm2022/lenne.tech-ng-base-base-cms.mjs +0 -251
  329. package/fesm2022/lenne.tech-ng-base-base-cms.mjs.map +0 -1
  330. package/fesm2022/lenne.tech-ng-base-base-components.mjs +0 -2917
  331. package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +0 -1
  332. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs +0 -505
  333. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
  334. package/fesm2022/lenne.tech-ng-base-shared.mjs +0 -2863
  335. package/fesm2022/lenne.tech-ng-base-shared.mjs.map +0 -1
  336. package/index.d.ts +0 -5
  337. package/public-api.d.ts +0 -17
  338. package/shared/classes/auth.class.d.ts +0 -10
  339. package/shared/classes/basic-user.class.d.ts +0 -27
  340. package/shared/classes/graphql-enum.class.d.ts +0 -7
  341. package/shared/classes/graphql-meta.class.d.ts +0 -66
  342. package/shared/classes/graphql-type.class.d.ts +0 -13
  343. package/shared/classes/helper.class.d.ts +0 -99
  344. package/shared/classes/sort.class.d.ts +0 -12
  345. package/shared/classes/standard.class.d.ts +0 -32
  346. package/shared/decorators/debounce.decorator.d.ts +0 -1
  347. package/shared/enums/comparison-operator.enum.d.ts +0 -14
  348. package/shared/enums/graphql-request-type.enum.d.ts +0 -8
  349. package/shared/enums/logical-operator.enum.d.ts +0 -8
  350. package/shared/enums/skeleton-type.enum.d.ts +0 -5
  351. package/shared/enums/sort-order.enum.d.ts +0 -4
  352. package/shared/enums/toast-type.enum.d.ts +0 -6
  353. package/shared/functions/ws-client.function.d.ts +0 -5
  354. package/shared/index.d.ts +0 -5
  355. package/shared/interfaces/base-module-config.interface.d.ts +0 -61
  356. package/shared/interfaces/breadcrumb.interface.d.ts +0 -4
  357. package/shared/interfaces/can-component-deactivate.interface.d.ts +0 -7
  358. package/shared/interfaces/cms-enum-values.interface.d.ts +0 -4
  359. package/shared/interfaces/cms-field-config.interface.d.ts +0 -45
  360. package/shared/interfaces/cms-model-config.interface.d.ts +0 -14
  361. package/shared/interfaces/cms-table-field.interface.d.ts +0 -10
  362. package/shared/interfaces/combined-filter-input.interface.d.ts +0 -9
  363. package/shared/interfaces/compress-options.interface.d.ts +0 -15
  364. package/shared/interfaces/cropping-options.interface.d.ts +0 -12
  365. package/shared/interfaces/field-object.interface.d.ts +0 -6
  366. package/shared/interfaces/field.interface.d.ts +0 -5
  367. package/shared/interfaces/filter-input.interface.d.ts +0 -9
  368. package/shared/interfaces/find-args.interface.d.ts +0 -11
  369. package/shared/interfaces/graphql-crud-type.interface.d.ts +0 -7
  370. package/shared/interfaces/graphql-fields-object.interface.d.ts +0 -6
  371. package/shared/interfaces/graphql-options.interface.d.ts +0 -11
  372. package/shared/interfaces/graphql-plus-options.interfacen.d.ts +0 -9
  373. package/shared/interfaces/graphql-type-collection.interface.d.ts +0 -7
  374. package/shared/interfaces/login-config.interface.d.ts +0 -6
  375. package/shared/interfaces/register-config.interface.d.ts +0 -4
  376. package/shared/interfaces/single-filter-input.interface.d.ts +0 -11
  377. package/shared/interfaces/sort-input.interface.d.ts +0 -5
  378. package/shared/interfaces/time-components.interface.d.ts +0 -6
  379. package/shared/interfaces/toast.interface.d.ts +0 -8
  380. package/shared/public-api.d.ts +0 -65
  381. package/shared/services/auth.service.d.ts +0 -44
  382. package/shared/services/breadcrumb.service.d.ts +0 -32
  383. package/shared/services/cms.service.d.ts +0 -27
  384. package/shared/services/file.service.d.ts +0 -22
  385. package/shared/services/forms.service.d.ts +0 -14
  386. package/shared/services/graphql-meta.service.d.ts +0 -45
  387. package/shared/services/graphql-plus.service.d.ts +0 -27
  388. package/shared/services/graphql.service.d.ts +0 -71
  389. package/shared/services/image.service.d.ts +0 -27
  390. package/shared/services/loader.service.d.ts +0 -32
  391. package/shared/services/navigation.service.d.ts +0 -15
  392. package/shared/services/scroll.service.d.ts +0 -85
  393. package/shared/services/storage.service.d.ts +0 -49
  394. package/shared/services/toast.service.d.ts +0 -15
  395. package/shared/services/user.service.d.ts +0 -77
  396. package/shared/services/ws.service.d.ts +0 -8
  397. package/shared/types/graphql-fields.type.d.ts +0 -5
  398. package/shared/types/storage.type.d.ts +0 -4
  399. package/shared/validators/email.validator.d.ts +0 -1
  400. package/shared/validators/match.validator.d.ts +0 -4
  401. package/shared/validators/secure-password.validator.d.ts +0 -1
  402. package/src/base.module.d.ts +0 -16
  403. package/src/decorators/auto-unsubscribe.decorator.d.ts +0 -5
  404. package/src/directives/lazy-load.directive.d.ts +0 -17
  405. package/src/directives/match-height.directive.d.ts +0 -20
  406. package/src/directives/resizable.directive.d.ts +0 -26
  407. package/src/factories/apollo-options.factory.d.ts +0 -16
  408. package/src/functions/extract-files.function.d.ts +0 -15
  409. package/src/guards/auth.guard.d.ts +0 -27
  410. package/src/guards/can-deactivate.guard.d.ts +0 -10
  411. package/src/guards/logout.guard.d.ts +0 -16
  412. package/src/pipes/date-ago.pipe.d.ts +0 -34
  413. package/src/pipes/safe-html.pipe.d.ts +0 -13
  414. package/src/services/fullscreen.service.d.ts +0 -18
  415. package/src/services/seo.service.d.ts +0 -61
  416. package/src/services/theme.service.d.ts +0 -17
@@ -0,0 +1,474 @@
1
+ import * as i0 from "@angular/core";
2
+ import { DestroyRef, InjectionToken, Service, assertInInjectionContext, computed, inject, isDevMode, makeEnvironmentProviders, signal } from "@angular/core";
3
+ import { LT_FETCH, LT_RUNTIME_CONFIG, LtApiUrlService, isLtAbsoluteUrl, mergeLtFeatureOptions } from "@lenne.tech/ng-base";
4
+ import { LtAuthStateService } from "@lenne.tech/ng-base/auth/provide";
5
+ const LT_FILES_DEFAULTS = {
6
+ filesBasePath: "/files",
7
+ tus: {
8
+ defaultChunkSize: 5242880,
9
+ defaultEndpoint: "/tus",
10
+ resolveAgainstApi: true
11
+ }
12
+ };
13
+ const LT_FILES_INPUT_OPTIONS = new InjectionToken("LT_FILES_INPUT_OPTIONS", { factory: () => ({}) });
14
+ const LT_FILES_OPTIONS = new InjectionToken("LT_FILES_OPTIONS", { factory: () => {
15
+ const input = inject(LT_FILES_INPUT_OPTIONS);
16
+ const runtime = inject(LT_RUNTIME_CONFIG, { optional: true });
17
+ return {
18
+ filesBasePath: input.filesBasePath ?? LT_FILES_DEFAULTS.filesBasePath,
19
+ tus: mergeLtFeatureOptions(LT_FILES_DEFAULTS.tus, input.tus, runtime?.lt.tus)
20
+ };
21
+ } });
22
+ function provideLtFiles(options = {}) {
23
+ return makeEnvironmentProviders([{
24
+ provide: LT_FILES_INPUT_OPTIONS,
25
+ useValue: options
26
+ }]);
27
+ }
28
+ var LtFileService = class LtFileService {
29
+ api = inject(LtApiUrlService);
30
+ fetch = inject(LT_FETCH);
31
+ options = inject(LT_FILES_OPTIONS);
32
+ async getFileInfo(id) {
33
+ if (!id) return null;
34
+ if (!isLtMongoId(id)) return id;
35
+ try {
36
+ const response = await this.fetch(`${this.baseUrl()}/info/${encodeURIComponent(id)}`, {
37
+ credentials: "include",
38
+ headers: { accept: "application/json" },
39
+ method: "GET"
40
+ });
41
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
42
+ const info = await response.json();
43
+ return info && typeof info === "object" ? info : null;
44
+ } catch (error) {
45
+ if (isDevMode()) console.error("[@lenne.tech/ng-base] Error fetching file info:", error);
46
+ return null;
47
+ }
48
+ }
49
+ getFileUrl(id) {
50
+ return `${this.baseUrl()}/id/${encodeURIComponent(id)}`;
51
+ }
52
+ getDownloadUrl(id, _filename) {
53
+ return this.getFileUrl(id);
54
+ }
55
+ formatFileSize(bytes) {
56
+ return formatLtFileSize(bytes);
57
+ }
58
+ formatDuration(seconds) {
59
+ return formatLtDuration(seconds);
60
+ }
61
+ isValidMongoID(id) {
62
+ return isLtMongoId(id);
63
+ }
64
+ baseUrl() {
65
+ const basePath = this.options.filesBasePath || "/files";
66
+ return this.api.buildUrl(basePath).replace(/\/+$/, "");
67
+ }
68
+ static ɵfac = i0.ɵɵngDeclareFactory({
69
+ minVersion: "12.0.0",
70
+ version: "22.2.4",
71
+ ngImport: i0,
72
+ type: LtFileService,
73
+ deps: [],
74
+ target: i0.ɵɵFactoryTarget.Service
75
+ });
76
+ static ɵprov = i0.ɵɵngDeclareService({
77
+ minVersion: "22.0.0",
78
+ version: "22.2.4",
79
+ ngImport: i0,
80
+ type: LtFileService
81
+ });
82
+ };
83
+ i0.ɵɵngDeclareClassMetadata({
84
+ minVersion: "12.0.0",
85
+ version: "22.2.4",
86
+ ngImport: i0,
87
+ type: LtFileService,
88
+ decorators: [{ type: Service }]
89
+ });
90
+ function formatLtFileSize(bytes) {
91
+ if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
92
+ const units = [
93
+ "B",
94
+ "KB",
95
+ "MB",
96
+ "GB",
97
+ "TB"
98
+ ];
99
+ const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
100
+ return `${parseFloat((bytes / 1024 ** exponent).toFixed(2))} ${units[exponent]}`;
101
+ }
102
+ function formatLtDuration(seconds) {
103
+ if (!Number.isFinite(seconds) || seconds < 60) return `${Math.max(0, Math.round(Number.isFinite(seconds) ? seconds : 0))}s`;
104
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;
105
+ return `${Math.floor(seconds / 3600)}h ${Math.floor(seconds % 3600 / 60)}m`;
106
+ }
107
+ function isLtMongoId(id) {
108
+ return typeof id === "string" && /^[a-f\d]{24}$/i.test(id);
109
+ }
110
+ const LT_TUS_CLIENT_MISSING_MESSAGE = "[@lenne.tech/ng-base] tus-js-client is not installed. Install it to use uploads: pnpm add tus-js-client (or npm install tus-js-client).";
111
+ let tusClient = null;
112
+ function loadLtTusClient() {
113
+ tusClient ??= import("tus-js-client").then((module) => {
114
+ const candidate = module;
115
+ const client = candidate.Upload ? candidate : candidate.default;
116
+ if (!client?.Upload) throw new Error(LT_TUS_CLIENT_MISSING_MESSAGE);
117
+ return client;
118
+ }, () => {
119
+ throw new Error(LT_TUS_CLIENT_MISSING_MESSAGE);
120
+ });
121
+ tusClient.catch(() => tusClient = null);
122
+ return tusClient;
123
+ }
124
+ const LT_TUS_CLIENT_LOADER = new InjectionToken("LT_TUS_CLIENT_LOADER", { factory: () => loadLtTusClient });
125
+ const LT_TUS_FILE_ID_HEADER = "X-File-Id";
126
+ const LT_TUS_RETRY_DELAYS = [
127
+ 0,
128
+ 1e3,
129
+ 3e3,
130
+ 5e3,
131
+ 1e4
132
+ ];
133
+ const DEFAULT_PARALLEL_UPLOADS = 3;
134
+ var LtSpeedTracker = class {
135
+ lastBytes = 0;
136
+ lastTime = 0;
137
+ smoothed = 0;
138
+ baseline = true;
139
+ reset(bytes) {
140
+ this.lastBytes = bytes;
141
+ this.lastTime = Date.now();
142
+ this.smoothed = 0;
143
+ this.baseline = true;
144
+ }
145
+ sample(bytes) {
146
+ const now = Date.now();
147
+ if (this.baseline && bytes < this.lastBytes) this.lastBytes = bytes;
148
+ const seconds = (now - this.lastTime) / 1e3;
149
+ if (seconds > 0 && bytes >= this.lastBytes) {
150
+ const current = (bytes - this.lastBytes) / seconds;
151
+ this.smoothed = this.smoothed === 0 ? current : this.smoothed * .7 + current * .3;
152
+ this.lastBytes = bytes;
153
+ this.lastTime = now;
154
+ this.baseline = false;
155
+ }
156
+ return Math.round(this.smoothed);
157
+ }
158
+ };
159
+ function injectLtTusUpload(options = {}) {
160
+ assertInInjectionContext(injectLtTusUpload);
161
+ const filesOptions = inject(LT_FILES_OPTIONS);
162
+ const api = inject(LtApiUrlService);
163
+ const authState = inject(LtAuthStateService);
164
+ const loadClient = inject(LT_TUS_CLIENT_LOADER);
165
+ const items = signal([], ...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
166
+ const tusUploads = /* @__PURE__ */ new Map();
167
+ const speedTrackers = /* @__PURE__ */ new Map();
168
+ const generations = /* @__PURE__ */ new Map();
169
+ const queue = [];
170
+ let sequence = 0;
171
+ let destroyed = false;
172
+ const uploads = items.asReadonly();
173
+ const isUploading = computed(() => items().some((item) => item.status === "uploading"), ...ngDevMode ? [{ debugName: "isUploading" }] : /* istanbul ignore next */ []);
174
+ const totalProgress = computed(() => {
175
+ const list = items();
176
+ if (list.length === 0) return idleProgress(0);
177
+ const bytesUploaded = list.reduce((sum, item) => sum + item.progress.bytesUploaded, 0);
178
+ const bytesTotal = list.reduce((sum, item) => sum + item.progress.bytesTotal, 0);
179
+ const speed = list.reduce((sum, item) => sum + item.progress.speed, 0);
180
+ return {
181
+ bytesTotal,
182
+ bytesUploaded,
183
+ percentage: bytesTotal > 0 ? Math.round(bytesUploaded / bytesTotal * 100) : 0,
184
+ remainingTime: speed > 0 ? Math.ceil((bytesTotal - bytesUploaded) / speed) : 0,
185
+ speed
186
+ };
187
+ }, ...ngDevMode ? [{ debugName: "totalProgress" }] : /* istanbul ignore next */ []);
188
+ function config() {
189
+ const defined = Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
190
+ return {
191
+ ...defined,
192
+ autoStart: defined.autoStart ?? true,
193
+ chunkSize: defined.chunkSize || filesOptions.tus.defaultChunkSize,
194
+ endpoint: defined.endpoint || filesOptions.tus.defaultEndpoint,
195
+ parallelUploads: Math.max(1, defined.parallelUploads || DEFAULT_PARALLEL_UPLOADS),
196
+ retryDelays: defined.retryDelays ?? [...LT_TUS_RETRY_DELAYS]
197
+ };
198
+ }
199
+ function resolveEndpoint(endpoint) {
200
+ if (!endpoint || filesOptions.tus.resolveAgainstApi === false || isLtAbsoluteUrl(endpoint)) return endpoint;
201
+ return api.buildUrl(endpoint.startsWith("/") ? endpoint : `/${endpoint}`);
202
+ }
203
+ function get(id) {
204
+ return items().find((item) => item.id === id);
205
+ }
206
+ function update(id, changes) {
207
+ let updated;
208
+ items.update((list) => list.map((item) => {
209
+ if (item.id !== id) return item;
210
+ updated = {
211
+ ...item,
212
+ ...changes
213
+ };
214
+ return updated;
215
+ }));
216
+ return updated;
217
+ }
218
+ function invalidate(id) {
219
+ generations.set(id, (generations.get(id) ?? 0) + 1);
220
+ }
221
+ function dequeue(id) {
222
+ const index = queue.indexOf(id);
223
+ if (index >= 0) queue.splice(index, 1);
224
+ }
225
+ function uploadingCount() {
226
+ return items().filter((item) => item.status === "uploading").length;
227
+ }
228
+ function pump() {
229
+ if (destroyed) return;
230
+ const limit = config().parallelUploads;
231
+ while (queue.length > 0 && uploadingCount() < limit) {
232
+ const id = queue.shift();
233
+ const item = get(id);
234
+ if (item && (item.status === "idle" || item.status === "paused")) begin(id);
235
+ }
236
+ }
237
+ function enqueue(ids) {
238
+ for (const id of ids) if (!queue.includes(id)) queue.push(id);
239
+ pump();
240
+ }
241
+ function begin(id) {
242
+ const item = get(id);
243
+ const tusUpload = tusUploads.get(id);
244
+ if (destroyed || !item || !tusUpload || item.status === "uploading" || item.status === "completed") return;
245
+ dequeue(id);
246
+ invalidate(id);
247
+ const generation = generations.get(id);
248
+ speedTrackers.get(id)?.reset(item.progress.bytesUploaded);
249
+ update(id, {
250
+ error: void 0,
251
+ startedAt: /* @__PURE__ */ new Date(),
252
+ status: "uploading"
253
+ });
254
+ const stillWanted = () => !destroyed && generations.get(id) === generation && get(id)?.status === "uploading";
255
+ (tusUpload.url ? Promise.resolve([]) : tusUpload.findPreviousUploads().catch(() => [])).then((previousUploads) => {
256
+ if (!stillWanted()) return;
257
+ const previous = latest(previousUploads);
258
+ if (previous) tusUpload.resumeFromPreviousUpload(previous);
259
+ tusUpload.start();
260
+ });
261
+ }
262
+ function settle(id) {
263
+ invalidate(id);
264
+ pump();
265
+ }
266
+ function createTusUpload(client, item, resolved) {
267
+ let fileId;
268
+ const callerSetsAuthorization = Object.keys(resolved.headers ?? {}).some((name) => name.toLowerCase() === "authorization");
269
+ const upload = new client.Upload(item.file, {
270
+ chunkSize: resolved.chunkSize,
271
+ endpoint: resolveEndpoint(resolved.endpoint),
272
+ headers: resolved.headers,
273
+ metadata: {
274
+ filename: item.file.name,
275
+ filetype: item.file.type,
276
+ ...resolved.metadata,
277
+ ...item.metadata
278
+ },
279
+ onAfterResponse: (_req, res) => {
280
+ fileId = res.getHeader("X-File-Id") || fileId;
281
+ },
282
+ onBeforeRequest: (req) => {
283
+ const xhr = req.getUnderlyingObject();
284
+ if (xhr && typeof xhr === "object" && "withCredentials" in xhr) xhr.withCredentials = true;
285
+ if (!callerSetsAuthorization && authState.getAuthMode() === "jwt") {
286
+ const token = authState.getJwtToken();
287
+ if (token) req.setHeader("Authorization", `Bearer ${token}`);
288
+ }
289
+ },
290
+ onError: (error) => {
291
+ const failed = update(item.id, {
292
+ error: error.message,
293
+ progress: {
294
+ ...get(item.id)?.progress ?? item.progress,
295
+ remainingTime: 0,
296
+ speed: 0
297
+ },
298
+ status: "error"
299
+ });
300
+ settle(item.id);
301
+ if (failed) config().onError?.(failed, error);
302
+ },
303
+ onProgress: (bytesUploaded, bytesTotal) => {
304
+ const current = get(item.id);
305
+ if (!current || current.status !== "uploading") return;
306
+ const speed = speedTrackers.get(item.id)?.sample(bytesUploaded) ?? 0;
307
+ const progress = {
308
+ bytesTotal,
309
+ bytesUploaded,
310
+ percentage: bytesTotal > 0 ? Math.min(100, Math.round(bytesUploaded / bytesTotal * 100)) : 0,
311
+ remainingTime: speed > 0 ? Math.ceil((bytesTotal - bytesUploaded) / speed) : 0,
312
+ speed
313
+ };
314
+ const updated = update(item.id, { progress });
315
+ if (updated) config().onProgress?.(updated);
316
+ },
317
+ onShouldRetry: (error) => {
318
+ const status = error.originalResponse?.getStatus?.();
319
+ return !(status && status >= 400 && status < 500 && status !== 429);
320
+ },
321
+ onSuccess: () => {
322
+ const current = get(item.id);
323
+ if (!current) return;
324
+ const bytesTotal = current.progress.bytesTotal || item.file.size;
325
+ const completed = update(item.id, {
326
+ completedAt: /* @__PURE__ */ new Date(),
327
+ error: void 0,
328
+ fileId,
329
+ progress: {
330
+ bytesTotal,
331
+ bytesUploaded: bytesTotal,
332
+ percentage: 100,
333
+ remainingTime: 0,
334
+ speed: 0
335
+ },
336
+ status: "completed",
337
+ url: upload.url ?? void 0
338
+ });
339
+ settle(item.id);
340
+ if (completed) config().onSuccess?.(completed);
341
+ },
342
+ removeFingerprintOnSuccess: true,
343
+ retryDelays: resolved.retryDelays
344
+ });
345
+ return upload;
346
+ }
347
+ async function addFiles(files) {
348
+ const list = (Array.isArray(files) ? files : [files]).filter(Boolean);
349
+ if (list.length === 0) return [];
350
+ const client = await loadClient();
351
+ if (destroyed) return [];
352
+ const resolved = config();
353
+ const ids = [];
354
+ for (const file of list) {
355
+ const id = `upload_${Date.now().toString(36)}_${++sequence}_${Math.random().toString(36).slice(2, 8)}`;
356
+ const item = {
357
+ file,
358
+ id,
359
+ metadata: resolved.metadata,
360
+ progress: idleProgress(file.size),
361
+ status: "idle"
362
+ };
363
+ tusUploads.set(id, createTusUpload(client, item, resolved));
364
+ speedTrackers.set(id, new LtSpeedTracker());
365
+ items.update((current) => [...current, item]);
366
+ ids.push(id);
367
+ }
368
+ if (resolved.autoStart) enqueue(ids);
369
+ return ids;
370
+ }
371
+ function startUpload(id) {
372
+ begin(id);
373
+ }
374
+ function startAll() {
375
+ enqueue(items().filter((item) => item.status === "idle" || item.status === "paused").map((item) => item.id));
376
+ }
377
+ function pauseUpload(id) {
378
+ const item = get(id);
379
+ const tusUpload = tusUploads.get(id);
380
+ if (!item || !tusUpload) return;
381
+ if (item.status === "uploading") {
382
+ invalidate(id);
383
+ tusUpload.abort().catch(() => void 0);
384
+ update(id, {
385
+ progress: {
386
+ ...item.progress,
387
+ remainingTime: 0,
388
+ speed: 0
389
+ },
390
+ status: "paused"
391
+ });
392
+ pump();
393
+ } else if (item.status === "idle") {
394
+ dequeue(id);
395
+ update(id, { status: "paused" });
396
+ }
397
+ }
398
+ function pauseAll() {
399
+ items().filter((item) => item.status === "uploading").forEach((item) => pauseUpload(item.id));
400
+ }
401
+ function resumeUpload(id) {
402
+ if (get(id)?.status === "paused") begin(id);
403
+ }
404
+ function resumeAll() {
405
+ enqueue(items().filter((item) => item.status === "paused").map((item) => item.id));
406
+ }
407
+ function cancelUpload(id) {
408
+ const tusUpload = tusUploads.get(id);
409
+ invalidate(id);
410
+ dequeue(id);
411
+ if (tusUpload) tusUpload.abort().catch(() => void 0);
412
+ tusUploads.delete(id);
413
+ speedTrackers.delete(id);
414
+ generations.delete(id);
415
+ items.update((list) => list.filter((item) => item.id !== id));
416
+ pump();
417
+ }
418
+ function cancelAll() {
419
+ items().forEach((item) => cancelUpload(item.id));
420
+ }
421
+ function removeUpload(id) {
422
+ cancelUpload(id);
423
+ }
424
+ function clearCompleted() {
425
+ items().filter((item) => item.status === "completed").forEach((item) => removeUpload(item.id));
426
+ }
427
+ function retryUpload(id) {
428
+ if (get(id)?.status === "error") {
429
+ update(id, {
430
+ error: void 0,
431
+ status: "idle"
432
+ });
433
+ begin(id);
434
+ }
435
+ }
436
+ inject(DestroyRef).onDestroy(() => {
437
+ destroyed = true;
438
+ queue.length = 0;
439
+ for (const tusUpload of tusUploads.values()) tusUpload.abort().catch(() => void 0);
440
+ });
441
+ return {
442
+ addFiles,
443
+ cancelAll,
444
+ cancelUpload,
445
+ clearCompleted,
446
+ getUpload: get,
447
+ isUploading,
448
+ pauseAll,
449
+ pauseUpload,
450
+ removeUpload,
451
+ resumeAll,
452
+ resumeUpload,
453
+ retryUpload,
454
+ startAll,
455
+ startUpload,
456
+ totalProgress,
457
+ uploads
458
+ };
459
+ }
460
+ function idleProgress(bytesTotal) {
461
+ return {
462
+ bytesTotal,
463
+ bytesUploaded: 0,
464
+ percentage: 0,
465
+ remainingTime: 0,
466
+ speed: 0
467
+ };
468
+ }
469
+ function latest(previousUploads) {
470
+ return [...previousUploads].sort((a, b) => Date.parse(b.creationTime ?? "") - Date.parse(a.creationTime ?? "") || 0)[0];
471
+ }
472
+ export { LT_FILES_DEFAULTS, LT_FILES_OPTIONS, LT_TUS_CLIENT_LOADER, LT_TUS_CLIENT_MISSING_MESSAGE, LT_TUS_FILE_ID_HEADER, LT_TUS_RETRY_DELAYS, LtFileService, formatLtDuration, formatLtFileSize, injectLtTusUpload, isLtMongoId, loadLtTusClient, provideLtFiles };
473
+
474
+ //# sourceMappingURL=lenne.tech-ng-base-files.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lenne.tech-ng-base-files.mjs","names":[],"sources":["../../../projects/ng-base/files/src/lib/files-options.ts","../../../projects/ng-base/files/src/lib/file-service.ts","../../../projects/ng-base/files/src/lib/tus-client.ts","../../../projects/ng-base/files/src/lib/tus-upload.ts"],"sourcesContent":["import { inject, InjectionToken, makeEnvironmentProviders, type EnvironmentProviders } from '@angular/core';\nimport { LT_RUNTIME_CONFIG, mergeLtFeatureOptions } from '@lenne.tech/ng-base';\n\n/** TUS options of `provideLtFiles({ tus })`; runtime overrides `NG_PUBLIC_LT_TUS_*`. */\nexport interface LtTusOptions {\n /** Chunk size in bytes (default 5 MB). */\n defaultChunkSize?: number;\n /**\n * TUS endpoint (default **`/tus`**, nest-server's default; nuxt-extensions defaulted to `/files/upload`). Relative values\n * are paths on the API while `resolveAgainstApi` is on; absolute URLs are used as they are.\n */\n defaultEndpoint?: string;\n /** Resolve a relative endpoint against the API base URL (default `true`). Turn off only behind an own same-origin proxy. */\n resolveAgainstApi?: boolean;\n}\n\n/** Options of `provideLtFiles()`. */\nexport interface LtFilesOptions {\n /** Base path of nest-server's file controller for info/download URLs (default `/files`). */\n filesBasePath?: string;\n /** TUS upload options. */\n tus?: LtTusOptions;\n}\n\n/** Resolved files options. */\nexport interface LtResolvedFilesOptions {\n filesBasePath: string;\n tus: Required<LtTusOptions>;\n}\n\n/** Defaults of {@link LtFilesOptions}. */\nexport const LT_FILES_DEFAULTS: LtResolvedFilesOptions = {\n filesBasePath: '/files',\n tus: { defaultChunkSize: 5 * 1024 * 1024, defaultEndpoint: '/tus', resolveAgainstApi: true },\n};\n\nconst LT_FILES_INPUT_OPTIONS = new InjectionToken<LtFilesOptions>('LT_FILES_INPUT_OPTIONS', { factory: () => ({}) });\n\n/** Resolved files options (defaults ← `provideLtFiles(options)` ← runtime `NG_PUBLIC_LT_TUS_*`). */\nexport const LT_FILES_OPTIONS = new InjectionToken<LtResolvedFilesOptions>('LT_FILES_OPTIONS', {\n factory: () => {\n const input = inject(LT_FILES_INPUT_OPTIONS);\n const runtime = inject(LT_RUNTIME_CONFIG, { optional: true });\n return {\n filesBasePath: input.filesBasePath ?? LT_FILES_DEFAULTS.filesBasePath,\n tus: mergeLtFeatureOptions(LT_FILES_DEFAULTS.tus, input.tus, runtime?.lt.tus),\n };\n },\n});\n\n/** Files providers (TUS upload defaults, file info/download base path). Optional when the defaults fit. */\nexport function provideLtFiles(options: LtFilesOptions = {}): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: LT_FILES_INPUT_OPTIONS, useValue: options }]);\n}\n","import { inject, isDevMode, Service } from '@angular/core';\nimport { LT_FETCH, LtApiUrlService } from '@lenne.tech/ng-base';\n\nimport { LT_FILES_OPTIONS } from './files-options';\nimport type { LtFileInfo, LtFileState } from './upload-types';\n\n/**\n * nest-server file helpers (counterpart of `useLtFile()`). URLs are resolved against the API base URL (fix: the Nuxt\n * version built them relative to the app origin), under `filesBasePath` of `provideLtFiles()` (default `/files`).\n */\n@Service()\nexport class LtFileService implements LtFileState {\n private readonly api = inject(LtApiUrlService);\n private readonly fetch = inject(LT_FETCH);\n private readonly options = inject(LT_FILES_OPTIONS);\n\n /** `GET <api>/files/info/:id` with credentials; `null` for empty ids or on error, a non-ObjectId string is returned as is. */\n async getFileInfo(id: string | undefined): Promise<LtFileInfo | null | string> {\n if (!id) {\n return null;\n }\n if (!isLtMongoId(id)) {\n return id;\n }\n try {\n const response = await this.fetch(`${this.baseUrl()}/info/${encodeURIComponent(id)}`, {\n credentials: 'include',\n headers: { accept: 'application/json' },\n method: 'GET',\n });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n const info = (await response.json()) as LtFileInfo | null;\n return info && typeof info === 'object' ? info : null;\n } catch (error) {\n if (isDevMode()) {\n console.error('[@lenne.tech/ng-base] Error fetching file info:', error);\n }\n return null;\n }\n }\n\n /**\n * `<api>/files/id/:id` — nest-server's `GET files/id/:id` (CoreFileController), which streams the file (or redirects\n * to a presigned S3 URL) after the rights check (`file.downloadRoles`, default admin).\n */\n getFileUrl(id: string): string {\n return `${this.baseUrl()}/id/${encodeURIComponent(id)}`;\n }\n\n /**\n * Download URL. nest-server sets `Content-Disposition` from the stored filename on `GET files/id/:id`, so this is the\n * same URL as {@link getFileUrl}; `filename` is accepted for API compatibility with nuxt-extensions and ignored (the\n * server has no rename parameter — nuxt-extensions' `/files/download/:id` does not exist in nest-server 12.5).\n */\n getDownloadUrl(id: string, _filename?: string): string {\n return this.getFileUrl(id);\n }\n\n /** 1024-based `B`/`KB`/`MB`/`GB`/`TB` with two decimals. */\n formatFileSize(bytes: number): string {\n return formatLtFileSize(bytes);\n }\n\n /** `Ns`, `Nm Ns`, `Nh Nm`. */\n formatDuration(seconds: number): string {\n return formatLtDuration(seconds);\n }\n\n /** `/^[a-f\\d]{24}$/i`. */\n isValidMongoID(id: string): boolean {\n return isLtMongoId(id);\n }\n\n /** `<api><filesBasePath>` without a trailing slash; an absolute `filesBasePath` is used as is. */\n private baseUrl(): string {\n const basePath = this.options.filesBasePath || '/files';\n return this.api.buildUrl(basePath).replace(/\\/+$/, '');\n }\n}\n\n/** 1024-based file size with two decimals (`0 B` for non-positive input). */\nexport function formatLtFileSize(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes <= 0) {\n return '0 B';\n }\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n return `${parseFloat((bytes / 1024 ** exponent).toFixed(2))} ${units[exponent]}`;\n}\n\n/** Human readable duration (`45s`, `2m 5s`, `1h 3m`). */\nexport function formatLtDuration(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 60) {\n return `${Math.max(0, Math.round(Number.isFinite(seconds) ? seconds : 0))}s`;\n }\n if (seconds < 3600) {\n return `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;\n }\n return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;\n}\n\n/** Whether `id` is a MongoDB ObjectId (24 hex characters). */\nexport function isLtMongoId(id: string): boolean {\n return typeof id === 'string' && /^[a-f\\d]{24}$/i.test(id);\n}\n","import { InjectionToken } from '@angular/core';\n\n/** The request object tus-js-client hands to `onBeforeRequest` / `onAfterResponse`. */\nexport interface LtTusHttpRequest {\n getUnderlyingObject(): unknown;\n setHeader(header: string, value: string): void;\n}\n\n/** The response object tus-js-client hands to `onAfterResponse` (and inside `DetailedError.originalResponse`). */\nexport interface LtTusHttpResponse {\n getHeader(header: string): null | string | undefined;\n getStatus(): number;\n}\n\n/** A previous upload of the same file found in tus-js-client's URL storage. */\nexport interface LtTusPreviousUpload {\n creationTime?: string;\n}\n\n/** The tus-js-client upload options `injectLtTusUpload()` sets. */\nexport interface LtTusClientUploadOptions {\n chunkSize?: number;\n endpoint?: string;\n headers?: Record<string, string>;\n metadata?: Record<string, string>;\n onAfterResponse?: (req: LtTusHttpRequest, res: LtTusHttpResponse) => void;\n onBeforeRequest?: (req: LtTusHttpRequest) => void;\n onError?: (error: Error) => void;\n onProgress?: (bytesUploaded: number, bytesTotal: number) => void;\n onShouldRetry?: (error: Error & { originalResponse?: LtTusHttpResponse | null }, retryAttempt: number, options: unknown) => boolean;\n onSuccess?: () => void;\n removeFingerprintOnSuccess?: boolean;\n retryDelays?: number[];\n}\n\n/** The part of a tus-js-client `Upload` instance `injectLtTusUpload()` uses. */\nexport interface LtTusClientUpload {\n url: null | string;\n abort(shouldTerminate?: boolean): Promise<void>;\n findPreviousUploads(): Promise<LtTusPreviousUpload[]>;\n resumeFromPreviousUpload(previousUpload: LtTusPreviousUpload): void;\n start(): void;\n}\n\n/** The part of the `tus-js-client` module `injectLtTusUpload()` uses (structural, so the peer stays optional). */\nexport interface LtTusClient {\n Upload: new (file: File, options: LtTusClientUploadOptions) => LtTusClientUpload;\n}\n\n/** Error text when the optional peer `tus-js-client` is missing. */\nexport const LT_TUS_CLIENT_MISSING_MESSAGE =\n '[@lenne.tech/ng-base] tus-js-client is not installed. Install it to use uploads: pnpm add tus-js-client (or npm install tus-js-client).';\n\nlet tusClient: Promise<LtTusClient> | null = null;\n\n/** Load `tus-js-client` lazily (once); rejects with an install hint when the optional peer is missing. */\nexport function loadLtTusClient(): Promise<LtTusClient> {\n tusClient ??= import('tus-js-client').then(\n (module) => {\n const candidate = module as unknown as Partial<LtTusClient> & { default?: Partial<LtTusClient> };\n const client = candidate.Upload ? candidate : candidate.default;\n if (!client?.Upload) {\n throw new Error(LT_TUS_CLIENT_MISSING_MESSAGE);\n }\n return client as LtTusClient;\n },\n () => {\n throw new Error(LT_TUS_CLIENT_MISSING_MESSAGE);\n },\n );\n // A failed load is not cached, so installing the package and reloading the chunk can recover.\n tusClient.catch(() => (tusClient = null));\n return tusClient;\n}\n\n/**\n * Loader of the `tus-js-client` module used by `injectLtTusUpload()` (default: lazy `import('tus-js-client')`).\n * Replace it in tests with a fake client, or to supply a preconfigured build.\n */\nexport const LT_TUS_CLIENT_LOADER = new InjectionToken<() => Promise<LtTusClient>>('LT_TUS_CLIENT_LOADER', {\n factory: () => loadLtTusClient,\n});\n","import { assertInInjectionContext, computed, DestroyRef, inject, signal } from '@angular/core';\nimport { isLtAbsoluteUrl, LtApiUrlService } from '@lenne.tech/ng-base';\nimport { LtAuthStateService } from '@lenne.tech/ng-base/auth/provide';\n\nimport { LT_FILES_OPTIONS } from './files-options';\nimport { LT_TUS_CLIENT_LOADER, type LtTusClientUpload, type LtTusHttpRequest, type LtTusPreviousUpload } from './tus-client';\nimport type { LtTusUploadState, LtUploadItem, LtUploadOptions, LtUploadProgress } from './upload-types';\n\n/** A TUS upload queue with signal state, created by {@link injectLtTusUpload}. */\nexport type LtTusUpload = LtTusUploadState;\n\n/**\n * Response header in which nest-server (11.42.13+, `TUS_FILE_ID_HEADER`) names the stored file. Sent on the response that\n * completes the upload and listed in `Access-Control-Expose-Headers`.\n */\nexport const LT_TUS_FILE_ID_HEADER = 'X-File-Id';\n\n/** Default retry delays of a TUS upload in milliseconds. */\nexport const LT_TUS_RETRY_DELAYS: readonly number[] = [0, 1000, 3000, 5000, 10000];\n\nconst DEFAULT_PARALLEL_UPLOADS = 3;\n\ninterface ResolvedUploadOptions extends LtUploadOptions {\n autoStart: boolean;\n chunkSize: number;\n endpoint: string;\n parallelUploads: number;\n retryDelays: number[];\n}\n\n/** Exponential moving average (0.7 old / 0.3 new) of the upload speed in bytes per second. */\nclass LtSpeedTracker {\n private lastBytes = 0;\n private lastTime = 0;\n private smoothed = 0;\n private baseline = true;\n\n /** Start a new measurement from `bytes` (after a (re)start; the time of a pause does not count). */\n reset(bytes: number): void {\n this.lastBytes = bytes;\n this.lastTime = Date.now();\n this.smoothed = 0;\n this.baseline = true;\n }\n\n /** Record `bytes` uploaded so far and return the smoothed speed. */\n sample(bytes: number): number {\n const now = Date.now();\n if (this.baseline && bytes < this.lastBytes) {\n this.lastBytes = bytes; // a resumed upload reports its offset first\n }\n const seconds = (now - this.lastTime) / 1000;\n if (seconds > 0 && bytes >= this.lastBytes) {\n const current = (bytes - this.lastBytes) / seconds;\n this.smoothed = this.smoothed === 0 ? current : this.smoothed * 0.7 + current * 0.3;\n this.lastBytes = bytes;\n this.lastTime = now;\n this.baseline = false;\n }\n return Math.round(this.smoothed);\n }\n}\n\n/**\n * Create a TUS upload queue (counterpart of `useLtTusUpload()`), bound to the current injection context: running\n * uploads are aborted when the component/service is destroyed.\n *\n * `tus-js-client` (optional peer) is loaded lazily; without it `addFiles` rejects with an install hint.\n * Defaults: `autoStart` true, chunk size and endpoint from `provideLtFiles()`, 3 parallel uploads, retries\n * `[0, 1000, 3000, 5000, 10000]` (none on 4xx except 429), `withCredentials` for the session cookie, Bearer token\n * in JWT mode, the nest-server file id from the `X-File-Id` response header, resume via fingerprints.\n *\n * Options are read whenever an upload is created or started, so an object with getters (e.g. over component inputs)\n * stays current. `undefined` values keep the default. Uploads beyond `parallelUploads` wait in a queue and start as\n * soon as a slot is free; `startUpload`/`resumeUpload`/`retryUpload` of a single item start it right away.\n *\n * @example\n * protected readonly upload = injectLtTusUpload({ onSuccess: (item) => this.attach(item.fileId) });\n */\nexport function injectLtTusUpload(options: LtUploadOptions = {}): LtTusUpload {\n assertInInjectionContext(injectLtTusUpload);\n const filesOptions = inject(LT_FILES_OPTIONS);\n const api = inject(LtApiUrlService);\n const authState = inject(LtAuthStateService);\n const loadClient = inject(LT_TUS_CLIENT_LOADER);\n\n const items = signal<LtUploadItem[]>([]);\n const tusUploads = new Map<string, LtTusClientUpload>();\n const speedTrackers = new Map<string, LtSpeedTracker>();\n /** Start generation per upload: a pause/cancel invalidates a start whose resume lookup is still running. */\n const generations = new Map<string, number>();\n const queue: string[] = [];\n let sequence = 0;\n let destroyed = false;\n\n const uploads = items.asReadonly();\n const isUploading = computed(() => items().some((item) => item.status === 'uploading'));\n const totalProgress = computed<LtUploadProgress>(() => {\n const list = items();\n if (list.length === 0) {\n return idleProgress(0);\n }\n const bytesUploaded = list.reduce((sum, item) => sum + item.progress.bytesUploaded, 0);\n const bytesTotal = list.reduce((sum, item) => sum + item.progress.bytesTotal, 0);\n const speed = list.reduce((sum, item) => sum + item.progress.speed, 0);\n return {\n bytesTotal,\n bytesUploaded,\n percentage: bytesTotal > 0 ? Math.round((bytesUploaded / bytesTotal) * 100) : 0,\n remainingTime: speed > 0 ? Math.ceil((bytesTotal - bytesUploaded) / speed) : 0,\n speed,\n };\n });\n\n function config(): ResolvedUploadOptions {\n const defined = Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined)) as LtUploadOptions;\n return {\n ...defined,\n autoStart: defined.autoStart ?? true,\n chunkSize: defined.chunkSize || filesOptions.tus.defaultChunkSize,\n endpoint: defined.endpoint || filesOptions.tus.defaultEndpoint,\n parallelUploads: Math.max(1, defined.parallelUploads || DEFAULT_PARALLEL_UPLOADS),\n retryDelays: defined.retryDelays ?? [...LT_TUS_RETRY_DELAYS],\n };\n }\n\n /** A relative endpoint is a path on the API (like auth and AI requests) unless `tus.resolveAgainstApi` is off. */\n function resolveEndpoint(endpoint: string): string {\n if (!endpoint || filesOptions.tus.resolveAgainstApi === false || isLtAbsoluteUrl(endpoint)) {\n return endpoint;\n }\n return api.buildUrl(endpoint.startsWith('/') ? endpoint : `/${endpoint}`);\n }\n\n function get(id: string): LtUploadItem | undefined {\n return items().find((item) => item.id === id);\n }\n\n function update(id: string, changes: Partial<LtUploadItem>): LtUploadItem | undefined {\n let updated: LtUploadItem | undefined;\n items.update((list) =>\n list.map((item) => {\n if (item.id !== id) {\n return item;\n }\n updated = { ...item, ...changes };\n return updated;\n }),\n );\n return updated;\n }\n\n function invalidate(id: string): void {\n generations.set(id, (generations.get(id) ?? 0) + 1);\n }\n\n function dequeue(id: string): void {\n const index = queue.indexOf(id);\n if (index >= 0) {\n queue.splice(index, 1);\n }\n }\n\n function uploadingCount(): number {\n return items().filter((item) => item.status === 'uploading').length;\n }\n\n /** Start queued uploads while slots are free. */\n function pump(): void {\n if (destroyed) {\n return;\n }\n const limit = config().parallelUploads;\n while (queue.length > 0 && uploadingCount() < limit) {\n const id = queue.shift() as string;\n const item = get(id);\n if (item && (item.status === 'idle' || item.status === 'paused')) {\n begin(id);\n }\n }\n }\n\n function enqueue(ids: string[]): void {\n for (const id of ids) {\n if (!queue.includes(id)) {\n queue.push(id);\n }\n }\n pump();\n }\n\n function begin(id: string): void {\n const item = get(id);\n const tusUpload = tusUploads.get(id);\n if (destroyed || !item || !tusUpload || item.status === 'uploading' || item.status === 'completed') {\n return;\n }\n dequeue(id);\n invalidate(id);\n const generation = generations.get(id);\n speedTrackers.get(id)?.reset(item.progress.bytesUploaded);\n update(id, { error: undefined, startedAt: new Date(), status: 'uploading' });\n\n const stillWanted = (): boolean => !destroyed && generations.get(id) === generation && get(id)?.status === 'uploading';\n // An upload that already has its URL continues there; a new one looks for an interrupted upload of the same file.\n const lookup: Promise<LtTusPreviousUpload[]> = tusUpload.url ? Promise.resolve([]) : tusUpload.findPreviousUploads().catch(() => []);\n void lookup.then((previousUploads) => {\n if (!stillWanted()) {\n return;\n }\n const previous = latest(previousUploads);\n if (previous) {\n tusUpload.resumeFromPreviousUpload(previous);\n }\n tusUpload.start();\n });\n }\n\n function settle(id: string): void {\n invalidate(id);\n pump();\n }\n\n function createTusUpload(client: Awaited<ReturnType<typeof loadClient>>, item: LtUploadItem, resolved: ResolvedUploadOptions): LtTusClientUpload {\n // Read in `onAfterResponse`, not from `onSuccess`'s payload: tus-js-client passes `{ lastResponse }` to `onSuccess`\n // only from 4.2.0, and the peer range starts at 4.0.0.\n let fileId: string | undefined;\n const callerSetsAuthorization = Object.keys(resolved.headers ?? {}).some((name) => name.toLowerCase() === 'authorization');\n\n const upload: LtTusClientUpload = new client.Upload(item.file, {\n chunkSize: resolved.chunkSize,\n endpoint: resolveEndpoint(resolved.endpoint),\n headers: resolved.headers,\n metadata: {\n filename: item.file.name,\n filetype: item.file.type,\n ...resolved.metadata,\n ...item.metadata,\n },\n onAfterResponse: (_req, res) => {\n // Only the completing response carries it; XHR answers `null` for a header that was not sent or not exposed.\n fileId = res.getHeader(LT_TUS_FILE_ID_HEADER) || fileId;\n },\n onBeforeRequest: (req: LtTusHttpRequest) => {\n const xhr = req.getUnderlyingObject() as { withCredentials?: boolean } | null;\n if (xhr && typeof xhr === 'object' && 'withCredentials' in xhr) {\n xhr.withCredentials = true;\n }\n if (!callerSetsAuthorization && authState.getAuthMode() === 'jwt') {\n const token = authState.getJwtToken();\n if (token) {\n req.setHeader('Authorization', `Bearer ${token}`);\n }\n }\n },\n onError: (error) => {\n const failed = update(item.id, { error: error.message, progress: { ...(get(item.id)?.progress ?? item.progress), remainingTime: 0, speed: 0 }, status: 'error' });\n settle(item.id);\n if (failed) {\n config().onError?.(failed, error);\n }\n },\n onProgress: (bytesUploaded, bytesTotal) => {\n const current = get(item.id);\n if (!current || current.status !== 'uploading') {\n return;\n }\n const speed = speedTrackers.get(item.id)?.sample(bytesUploaded) ?? 0;\n const progress: LtUploadProgress = {\n bytesTotal,\n bytesUploaded,\n percentage: bytesTotal > 0 ? Math.min(100, Math.round((bytesUploaded / bytesTotal) * 100)) : 0,\n remainingTime: speed > 0 ? Math.ceil((bytesTotal - bytesUploaded) / speed) : 0,\n speed,\n };\n const updated = update(item.id, { progress });\n if (updated) {\n config().onProgress?.(updated);\n }\n },\n onShouldRetry: (error) => {\n const status = error.originalResponse?.getStatus?.();\n // No retry on 4xx (except 429 Too Many Requests): the request itself is wrong or not allowed.\n return !(status && status >= 400 && status < 500 && status !== 429);\n },\n onSuccess: () => {\n const current = get(item.id);\n if (!current) {\n return;\n }\n const bytesTotal = current.progress.bytesTotal || item.file.size;\n const completed = update(item.id, {\n completedAt: new Date(),\n error: undefined,\n fileId,\n progress: { bytesTotal, bytesUploaded: bytesTotal, percentage: 100, remainingTime: 0, speed: 0 },\n status: 'completed',\n url: upload.url ?? undefined,\n });\n settle(item.id);\n if (completed) {\n config().onSuccess?.(completed);\n }\n },\n // Keep the fingerprint only for interrupted uploads: a completed one must not be \"resumed\" by the next upload of\n // the same file, which would finish without a request and therefore without an `X-File-Id`.\n removeFingerprintOnSuccess: true,\n retryDelays: resolved.retryDelays,\n });\n return upload;\n }\n\n async function addFiles(files: File | File[]): Promise<string[]> {\n const list = (Array.isArray(files) ? files : [files]).filter(Boolean);\n if (list.length === 0) {\n return [];\n }\n const client = await loadClient();\n if (destroyed) {\n return [];\n }\n const resolved = config();\n const ids: string[] = [];\n for (const file of list) {\n const id = `upload_${Date.now().toString(36)}_${++sequence}_${Math.random().toString(36).slice(2, 8)}`;\n const item: LtUploadItem = { file, id, metadata: resolved.metadata, progress: idleProgress(file.size), status: 'idle' };\n tusUploads.set(id, createTusUpload(client, item, resolved));\n speedTrackers.set(id, new LtSpeedTracker());\n items.update((current) => [...current, item]);\n ids.push(id);\n }\n if (resolved.autoStart) {\n enqueue(ids);\n }\n return ids;\n }\n\n function startUpload(id: string): void {\n begin(id);\n }\n\n function startAll(): void {\n enqueue(\n items()\n .filter((item) => item.status === 'idle' || item.status === 'paused')\n .map((item) => item.id),\n );\n }\n\n function pauseUpload(id: string): void {\n const item = get(id);\n const tusUpload = tusUploads.get(id);\n if (!item || !tusUpload) {\n return;\n }\n if (item.status === 'uploading') {\n invalidate(id);\n void tusUpload.abort().catch(() => undefined);\n update(id, { progress: { ...item.progress, remainingTime: 0, speed: 0 }, status: 'paused' });\n pump();\n } else if (item.status === 'idle') {\n // A queued upload is taken out of the queue.\n dequeue(id);\n update(id, { status: 'paused' });\n }\n }\n\n function pauseAll(): void {\n items()\n .filter((item) => item.status === 'uploading')\n .forEach((item) => pauseUpload(item.id));\n }\n\n function resumeUpload(id: string): void {\n if (get(id)?.status === 'paused') {\n begin(id);\n }\n }\n\n function resumeAll(): void {\n enqueue(\n items()\n .filter((item) => item.status === 'paused')\n .map((item) => item.id),\n );\n }\n\n function cancelUpload(id: string): void {\n const tusUpload = tusUploads.get(id);\n invalidate(id);\n dequeue(id);\n if (tusUpload) {\n void tusUpload.abort().catch(() => undefined);\n }\n tusUploads.delete(id);\n speedTrackers.delete(id);\n generations.delete(id);\n items.update((list) => list.filter((item) => item.id !== id));\n pump();\n }\n\n function cancelAll(): void {\n items().forEach((item) => cancelUpload(item.id));\n }\n\n function removeUpload(id: string): void {\n cancelUpload(id);\n }\n\n function clearCompleted(): void {\n items()\n .filter((item) => item.status === 'completed')\n .forEach((item) => removeUpload(item.id));\n }\n\n function retryUpload(id: string): void {\n if (get(id)?.status === 'error') {\n update(id, { error: undefined, status: 'idle' });\n begin(id);\n }\n }\n\n inject(DestroyRef).onDestroy(() => {\n destroyed = true;\n queue.length = 0;\n for (const tusUpload of tusUploads.values()) {\n void tusUpload.abort().catch(() => undefined);\n }\n });\n\n return {\n addFiles,\n cancelAll,\n cancelUpload,\n clearCompleted,\n getUpload: get,\n isUploading,\n pauseAll,\n pauseUpload,\n removeUpload,\n resumeAll,\n resumeUpload,\n retryUpload,\n startAll,\n startUpload,\n totalProgress,\n uploads,\n };\n}\n\nfunction idleProgress(bytesTotal: number): LtUploadProgress {\n return { bytesTotal, bytesUploaded: 0, percentage: 0, remainingTime: 0, speed: 0 };\n}\n\nfunction latest(previousUploads: LtTusPreviousUpload[]): LtTusPreviousUpload | undefined {\n return [...previousUploads].sort((a, b) => Date.parse(b.creationTime ?? '') - Date.parse(a.creationTime ?? '') || 0)[0];\n}\n"],"mappings":"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"}