http-request-manager 15.0.26 → 18.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 (232) hide show
  1. package/esm2022/http-request-manager.mjs +5 -0
  2. package/esm2022/lib/http-request-manager.module.mjs +146 -0
  3. package/esm2022/lib/http-request-services-demo/database-data-demo/database-data-demo.component.mjs +71 -0
  4. package/esm2022/lib/http-request-services-demo/http-request-services-demo.component.mjs +41 -0
  5. package/esm2022/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.mjs +173 -0
  6. package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.mjs +80 -0
  7. package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.mjs +42 -0
  8. package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.mjs +88 -0
  9. package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.mjs +11 -0
  10. package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.mjs +29 -0
  11. package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.mjs +9 -0
  12. package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.mjs +12 -0
  13. package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.mjs +14 -0
  14. package/esm2022/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.mjs +315 -0
  15. package/esm2022/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.mjs +270 -0
  16. package/esm2022/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.mjs +67 -0
  17. package/esm2022/lib/index.mjs +4 -0
  18. package/esm2022/lib/interceptors/credentials.interceptor.mjs +14 -0
  19. package/esm2022/lib/interceptors/index.mjs +5 -0
  20. package/esm2022/lib/interceptors/models/error-settings.model.mjs +10 -0
  21. package/esm2022/lib/interceptors/proxy-debugger.interceptor.mjs +47 -0
  22. package/esm2022/lib/interceptors/request-error.interceptor.mjs +49 -0
  23. package/esm2022/lib/interceptors/request-header.interceptor.mjs +41 -0
  24. package/esm2022/lib/models/config-http-options.model.mjs +18 -0
  25. package/esm2022/lib/models/config-local-storage-options.model.mjs +12 -0
  26. package/esm2022/lib/models/config-options.model.mjs +12 -0
  27. package/esm2022/lib/models/config-token.model.mjs +8 -0
  28. package/esm2022/lib/models/data-type.enum.mjs +7 -0
  29. package/esm2022/lib/models/database-storage.model.mjs +10 -0
  30. package/esm2022/lib/models/index.mjs +7 -0
  31. package/esm2022/lib/models/retry-options.model.mjs +10 -0
  32. package/esm2022/lib/services/database-manager-services/database.manager.service.mjs +119 -0
  33. package/esm2022/lib/services/database-manager-services/db.storage.service.mjs +143 -0
  34. package/esm2022/lib/services/database-manager-services/index.mjs +4 -0
  35. package/esm2022/lib/services/database-manager-services/models/table-schema.mjs +20 -0
  36. package/esm2022/lib/services/index.mjs +6 -0
  37. package/esm2022/lib/services/local-storage-manager-service/index.mjs +3 -0
  38. package/esm2022/lib/services/local-storage-manager-service/local-storage-manager.service.mjs +302 -0
  39. package/esm2022/lib/services/local-storage-manager-service/models/global-store-options.model.mjs +13 -0
  40. package/esm2022/lib/services/local-storage-manager-service/models/index.mjs +6 -0
  41. package/esm2022/lib/services/local-storage-manager-service/models/setting-options.model.mjs +13 -0
  42. package/esm2022/lib/services/local-storage-manager-service/models/storage-data.model.mjs +10 -0
  43. package/esm2022/lib/services/local-storage-manager-service/models/storage-option.model.mjs +12 -0
  44. package/esm2022/lib/services/local-storage-manager-service/models/storage-type.enum.mjs +7 -0
  45. package/esm2022/lib/services/request-manager-services/http-manager.service.mjs +207 -0
  46. package/esm2022/lib/services/request-manager-services/index.mjs +5 -0
  47. package/esm2022/lib/services/request-manager-services/request.service.mjs +189 -0
  48. package/esm2022/lib/services/request-manager-services/rxjs-operators/countdown.mjs +9 -0
  49. package/esm2022/lib/services/request-manager-services/rxjs-operators/delay-retry.mjs +10 -0
  50. package/esm2022/lib/services/request-manager-services/rxjs-operators/index.mjs +5 -0
  51. package/esm2022/lib/services/request-manager-services/rxjs-operators/request-polling.mjs +14 -0
  52. package/esm2022/lib/services/request-manager-services/rxjs-operators/request-streaming.mjs +19 -0
  53. package/esm2022/lib/services/request-manager-state-service/http-manager-state.store.mjs +267 -0
  54. package/esm2022/lib/services/request-manager-state-service/index.mjs +3 -0
  55. package/esm2022/lib/services/request-manager-state-service/models/api-request.model.mjs +20 -0
  56. package/esm2022/lib/services/request-manager-state-service/models/index.mjs +3 -0
  57. package/esm2022/lib/services/request-manager-state-service/models/request-options.model.mjs +10 -0
  58. package/esm2022/lib/services/utils/app.service.mjs +26 -0
  59. package/esm2022/lib/services/utils/encryption/asymmetrical-encryption.service.mjs +186 -0
  60. package/esm2022/lib/services/utils/encryption/encryption-test.service.mjs +35 -0
  61. package/esm2022/lib/services/utils/encryption/index.mjs +4 -0
  62. package/esm2022/lib/services/utils/encryption/random.mjs +52 -0
  63. package/esm2022/lib/services/utils/encryption/symmetrical-encryption.service.mjs +77 -0
  64. package/esm2022/lib/services/utils/headers.service.mjs +21 -0
  65. package/esm2022/lib/services/utils/index.mjs +6 -0
  66. package/esm2022/lib/services/utils/object-merger.service.mjs +50 -0
  67. package/esm2022/lib/services/utils/path-query.service.mjs +54 -0
  68. package/esm2022/lib/services/utils/utils.service.mjs +155 -0
  69. package/esm2022/public-api.mjs +11 -0
  70. package/fesm2022/http-request-manager.mjs +3444 -0
  71. package/fesm2022/http-request-manager.mjs.map +1 -0
  72. package/http-request-manager-18.0.1.tgz +0 -0
  73. package/index.d.ts +5 -0
  74. package/lib/http-request-manager.module.d.ts +33 -0
  75. package/lib/http-request-services-demo/database-data-demo/database-data-demo.component.d.ts +19 -0
  76. package/lib/http-request-services-demo/http-request-services-demo.component.d.ts +24 -0
  77. package/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.d.ts +56 -0
  78. package/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.d.ts +26 -0
  79. package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.d.ts +13 -0
  80. package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.d.ts +27 -0
  81. package/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.d.ts +12 -0
  82. package/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.d.ts +16 -0
  83. package/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.d.ts +8 -0
  84. package/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.d.ts +14 -0
  85. package/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.d.ts +14 -0
  86. package/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.d.ts +107 -0
  87. package/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.d.ts +122 -0
  88. package/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.d.ts +15 -0
  89. package/lib/index.d.ts +3 -0
  90. package/lib/interceptors/credentials.interceptor.d.ts +8 -0
  91. package/{src/lib/interceptors/index.ts → lib/interceptors/index.d.ts} +0 -2
  92. package/lib/interceptors/models/error-settings.model.d.ts +10 -0
  93. package/lib/interceptors/proxy-debugger.interceptor.d.ts +12 -0
  94. package/lib/interceptors/request-error.interceptor.d.ts +10 -0
  95. package/lib/interceptors/request-header.interceptor.d.ts +15 -0
  96. package/lib/models/config-http-options.model.d.ts +21 -0
  97. package/lib/models/config-local-storage-options.model.d.ts +13 -0
  98. package/lib/models/config-options.model.d.ts +12 -0
  99. package/{src/lib/models/config-token.model.ts → lib/models/config-token.model.d.ts} +1 -2
  100. package/lib/models/data-type.enum.d.ts +5 -0
  101. package/lib/models/database-storage.model.d.ts +10 -0
  102. package/lib/models/index.d.ts +6 -0
  103. package/lib/models/retry-options.model.d.ts +10 -0
  104. package/lib/services/database-manager-services/database.manager.service.d.ts +31 -0
  105. package/lib/services/database-manager-services/db.storage.service.d.ts +26 -0
  106. package/{src/lib/services/database-manager-services/index.ts → lib/services/database-manager-services/index.d.ts} +0 -1
  107. package/lib/services/database-manager-services/models/table-schema.d.ts +11 -0
  108. package/{src/lib/services/index.ts → lib/services/index.d.ts} +0 -4
  109. package/lib/services/local-storage-manager-service/index.d.ts +2 -0
  110. package/lib/services/local-storage-manager-service/local-storage-manager.service.d.ts +86 -0
  111. package/lib/services/local-storage-manager-service/models/global-store-options.model.d.ts +15 -0
  112. package/{src/lib/services/local-storage-manager-service/models/index.ts → lib/services/local-storage-manager-service/models/index.d.ts} +1 -2
  113. package/lib/services/local-storage-manager-service/models/setting-options.model.d.ts +15 -0
  114. package/lib/services/local-storage-manager-service/models/storage-data.model.d.ts +10 -0
  115. package/lib/services/local-storage-manager-service/models/storage-option.model.d.ts +13 -0
  116. package/lib/services/local-storage-manager-service/models/storage-type.enum.d.ts +5 -0
  117. package/lib/services/request-manager-services/http-manager.service.d.ts +41 -0
  118. package/{src/lib/services/request-manager-services/index.ts → lib/services/request-manager-services/index.d.ts} +0 -2
  119. package/lib/services/request-manager-services/request.service.d.ts +27 -0
  120. package/lib/services/request-manager-services/rxjs-operators/countdown.d.ts +2 -0
  121. package/lib/services/request-manager-services/rxjs-operators/delay-retry.d.ts +2 -0
  122. package/lib/services/request-manager-services/rxjs-operators/request-polling.d.ts +7 -0
  123. package/lib/services/request-manager-services/rxjs-operators/request-streaming.d.ts +2 -0
  124. package/lib/services/request-manager-state-service/http-manager-state.store.d.ts +51 -0
  125. package/{src/lib/services/request-manager-state-service/index.ts → lib/services/request-manager-state-service/index.d.ts} +0 -1
  126. package/lib/services/request-manager-state-service/models/api-request.model.d.ts +27 -0
  127. package/{src/lib/services/request-manager-state-service/models/index.ts → lib/services/request-manager-state-service/models/index.d.ts} +0 -1
  128. package/lib/services/request-manager-state-service/models/request-options.model.d.ts +10 -0
  129. package/lib/services/utils/app.service.d.ts +8 -0
  130. package/lib/services/utils/encryption/asymmetrical-encryption.service.d.ts +17 -0
  131. package/lib/services/utils/encryption/encryption-test.service.d.ts +10 -0
  132. package/{src/lib/services/utils/encryption/index.ts → lib/services/utils/encryption/index.d.ts} +0 -2
  133. package/lib/services/utils/encryption/random.d.ts +7 -0
  134. package/lib/services/utils/encryption/symmetrical-encryption.service.d.ts +14 -0
  135. package/lib/services/utils/headers.service.d.ts +10 -0
  136. package/{src/lib/services/utils/index.ts → lib/services/utils/index.d.ts} +0 -2
  137. package/lib/services/utils/object-merger.service.d.ts +12 -0
  138. package/lib/services/utils/path-query.service.d.ts +11 -0
  139. package/lib/services/utils/utils.service.d.ts +24 -0
  140. package/package.json +14 -1
  141. package/{src/public-api.ts → public-api.d.ts} +0 -7
  142. package/ng-package.json +0 -8
  143. package/src/lib/http-request-manager.module.ts +0 -101
  144. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.html +0 -3
  145. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.scss +0 -0
  146. package/src/lib/http-request-services-demo/database-data-demo/database-data-demo.component.ts +0 -105
  147. package/src/lib/http-request-services-demo/http-request-services-demo.component.html +0 -64
  148. package/src/lib/http-request-services-demo/http-request-services-demo.component.scss +0 -6
  149. package/src/lib/http-request-services-demo/http-request-services-demo.component.ts +0 -34
  150. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.html +0 -195
  151. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.scss +0 -17
  152. package/src/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.ts +0 -205
  153. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.html +0 -59
  154. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.scss +0 -60
  155. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.ts +0 -71
  156. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.ts +0 -28
  157. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.html +0 -10
  158. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.scss +0 -29
  159. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.ts +0 -99
  160. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.ts +0 -22
  161. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.html +0 -8
  162. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.scss +0 -19
  163. package/src/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.ts +0 -25
  164. package/src/lib/http-request-services-demo/request-manager-demo/models/app-session.model.ts +0 -30
  165. package/src/lib/http-request-services-demo/request-manager-demo/models/app.model.ts +0 -19
  166. package/src/lib/http-request-services-demo/request-manager-demo/models/get-sample.model.ts +0 -25
  167. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.ts +0 -19
  168. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-details.ts +0 -24
  169. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.ts +0 -30
  170. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-client.model.ts +0 -49
  171. package/src/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.ts +0 -33
  172. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.html +0 -336
  173. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.scss +0 -24
  174. package/src/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.ts +0 -403
  175. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.html +0 -328
  176. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.scss +0 -24
  177. package/src/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.ts +0 -347
  178. package/src/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.ts +0 -88
  179. package/src/lib/index.ts +0 -3
  180. package/src/lib/interceptors/credentials.interceptor.ts +0 -18
  181. package/src/lib/interceptors/models/error-settings.model.ts +0 -22
  182. package/src/lib/interceptors/proxy-debugger.interceptor.ts +0 -46
  183. package/src/lib/interceptors/request-error.interceptor.ts +0 -65
  184. package/src/lib/interceptors/request-header.interceptor.ts +0 -58
  185. package/src/lib/models/config-http-options.model.ts +0 -42
  186. package/src/lib/models/config-local-storage-options.model.ts +0 -27
  187. package/src/lib/models/config-options.model.ts +0 -27
  188. package/src/lib/models/data-type.enum.ts +0 -5
  189. package/src/lib/models/database-storage.model.ts +0 -24
  190. package/src/lib/models/index.ts +0 -9
  191. package/src/lib/models/retry-options.model.ts +0 -22
  192. package/src/lib/services/database-manager-services/database.manager.service.ts +0 -193
  193. package/src/lib/services/database-manager-services/db.storage.service.ts +0 -191
  194. package/src/lib/services/database-manager-services/models/table-schema.ts +0 -35
  195. package/src/lib/services/local-storage-manager-service/index.ts +0 -2
  196. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.spec.ts +0 -71
  197. package/src/lib/services/local-storage-manager-service/local-storage-manager.service.ts +0 -421
  198. package/src/lib/services/local-storage-manager-service/models/global-store-options.model.ts +0 -30
  199. package/src/lib/services/local-storage-manager-service/models/setting-options.model.ts +0 -30
  200. package/src/lib/services/local-storage-manager-service/models/storage-data.model.ts +0 -24
  201. package/src/lib/services/local-storage-manager-service/models/storage-option.model.ts +0 -29
  202. package/src/lib/services/local-storage-manager-service/models/storage-type.enum.ts +0 -5
  203. package/src/lib/services/request-manager-services/README.md +0 -268
  204. package/src/lib/services/request-manager-services/http-manager.service.spec.ts +0 -230
  205. package/src/lib/services/request-manager-services/http-manager.service.ts +0 -274
  206. package/src/lib/services/request-manager-services/request.service.ts +0 -261
  207. package/src/lib/services/request-manager-services/rxjs-operators/countdown.ts +0 -17
  208. package/src/lib/services/request-manager-services/rxjs-operators/delay-retry.ts +0 -16
  209. package/src/lib/services/request-manager-services/rxjs-operators/request-polling.ts +0 -21
  210. package/src/lib/services/request-manager-services/rxjs-operators/request-streaming.ts +0 -32
  211. package/src/lib/services/request-manager-state-service/http-manager-state.store.ts +0 -402
  212. package/src/lib/services/request-manager-state-service/models/api-request.model.ts +0 -50
  213. package/src/lib/services/request-manager-state-service/models/request-options.model.ts +0 -22
  214. package/src/lib/services/utils/app.service.spec.ts +0 -25
  215. package/src/lib/services/utils/app.service.ts +0 -21
  216. package/src/lib/services/utils/encryption/README.md +0 -79
  217. package/src/lib/services/utils/encryption/asymmetrical-encryption.service.ts +0 -282
  218. package/src/lib/services/utils/encryption/encryption-test.service.ts +0 -39
  219. package/src/lib/services/utils/encryption/random.ts +0 -69
  220. package/src/lib/services/utils/encryption/symmetrical-encryption.service.ts +0 -93
  221. package/src/lib/services/utils/headers.service.spec.ts +0 -80
  222. package/src/lib/services/utils/headers.service.ts +0 -18
  223. package/src/lib/services/utils/object-merger.service.spec.ts +0 -16
  224. package/src/lib/services/utils/object-merger.service.ts +0 -60
  225. package/src/lib/services/utils/path-query.service.spec.ts +0 -117
  226. package/src/lib/services/utils/path-query.service.ts +0 -69
  227. package/src/lib/services/utils/utils.service.spec.ts +0 -164
  228. package/src/lib/services/utils/utils.service.ts +0 -192
  229. package/tsconfig.lib.json +0 -32
  230. package/tsconfig.lib.prod.json +0 -10
  231. package/tsconfig.spec.json +0 -14
  232. /package/{src/lib/services/request-manager-services/rxjs-operators/index.ts → lib/services/request-manager-services/rxjs-operators/index.d.ts} +0 -0
@@ -0,0 +1,3444 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Injectable, APP_ID, Inject, InjectionToken, Injector, Optional, EventEmitter, Component, ViewEncapsulation, Input, Output, ViewChild, NgModule } from '@angular/core';
3
+ import { ComponentStore } from '@ngrx/component-store';
4
+ import { map, catchError, filter, delay, finalize, takeWhile, retry, startWith, tap, mergeMap, takeUntil, withLatestFrom, switchMap, concatMap, scan, distinctUntilChanged } from 'rxjs/operators';
5
+ import { HttpClient, HttpHeaders, HttpEventType, HttpHeaderResponse, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
6
+ import * as CryptoJS from 'crypto-js';
7
+ import { from, BehaviorSubject, EMPTY, throwError, defer, interval, timer, Subject, of, Subscription, catchError as catchError$1, map as map$1, tap as tap$1 } from 'rxjs';
8
+ import { ToastMessageDisplayService, ToastDisplay, ToastColors, ToastMessageDisplayModule } from 'toast-message-display';
9
+ import * as i1 from '@ngx-translate/core';
10
+ import { TranslateModule } from '@ngx-translate/core';
11
+ import * as i2 from '@angular/forms';
12
+ import { FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
13
+ import * as i1$1 from '@angular/common';
14
+ import { CommonModule } from '@angular/common';
15
+ import * as i3$1 from '@angular/material/button';
16
+ import { MatButtonModule } from '@angular/material/button';
17
+ import * as i4 from '@angular/material/form-field';
18
+ import { MatFormFieldModule } from '@angular/material/form-field';
19
+ import * as i5 from '@angular/material/select';
20
+ import { MatSelectModule } from '@angular/material/select';
21
+ import * as i6 from '@angular/material/core';
22
+ import * as i7 from '@angular/material/menu';
23
+ import { MatMenuModule } from '@angular/material/menu';
24
+ import * as i8 from '@angular/material/icon';
25
+ import { MatIconModule } from '@angular/material/icon';
26
+ import * as i9 from '@angular/material/table';
27
+ import { MatTableModule } from '@angular/material/table';
28
+ import * as i10 from '@angular/material/progress-bar';
29
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
30
+ import * as i11 from '@angular/material/slide-toggle';
31
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
32
+ import * as i12 from '@angular/material/divider';
33
+ import { MatDividerModule } from '@angular/material/divider';
34
+ import * as i13 from '@angular/material/input';
35
+ import { MatInputModule } from '@angular/material/input';
36
+ import * as i3 from '@angular/material/progress-spinner';
37
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
38
+ import * as i10$1 from '@angular/material/button-toggle';
39
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
40
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
41
+ import { MatChipsModule } from '@angular/material/chips';
42
+ import { MatSidenavModule } from '@angular/material/sidenav';
43
+ import * as i5$1 from '@angular/material/toolbar';
44
+ import { MatToolbarModule } from '@angular/material/toolbar';
45
+ import Dexie from 'dexie';
46
+
47
+ var StorageType;
48
+ (function (StorageType) {
49
+ StorageType[StorageType["GLOBAL"] = 0] = "GLOBAL";
50
+ StorageType[StorageType["SESSION"] = 1] = "SESSION";
51
+ StorageType[StorageType["DB"] = 2] = "DB";
52
+ })(StorageType || (StorageType = {}));
53
+
54
+ class SettingOptions {
55
+ constructor(storage, expires, expiresIn, encrypted) {
56
+ this.storage = storage;
57
+ this.expires = expires;
58
+ this.expiresIn = expiresIn;
59
+ this.encrypted = encrypted;
60
+ }
61
+ static adapt(item) {
62
+ return new SettingOptions((item?.storage) ? item.storage : StorageType.GLOBAL, (item?.expires) ? item.expires : 0, (item?.expiresIn) ? item.expiresIn : '', (item?.encrypted) ? item?.encrypted : false);
63
+ }
64
+ }
65
+
66
+ class StorageOption {
67
+ constructor(id, name = 'untitled', options) {
68
+ this.id = id;
69
+ this.name = name;
70
+ this.options = options;
71
+ }
72
+ static adapt(item) {
73
+ return new StorageOption((item?.id) ? item.id : crypto.randomUUID(), item?.name, (item?.options) ? SettingOptions.adapt(item.options) : SettingOptions.adapt());
74
+ }
75
+ }
76
+
77
+ class GlobalStoreOptions {
78
+ constructor(encryption = false, expiresIn, expires, stores = []) {
79
+ this.encryption = encryption;
80
+ this.expiresIn = expiresIn;
81
+ this.expires = expires;
82
+ this.stores = stores;
83
+ }
84
+ static adapt(item) {
85
+ return new GlobalStoreOptions((item?.encryption) ? item.encryption : false, (item?.expiresIn) ? item.expiresIn : '', (item?.expires) ? item.expires : 0, (item?.stores) ? item.stores.map((item) => StorageOption.adapt(item)) : []);
86
+ }
87
+ }
88
+
89
+ class StorageData {
90
+ constructor(id, data) {
91
+ this.id = id;
92
+ this.data = data;
93
+ }
94
+ static adapt(item) {
95
+ return new StorageData((item?.id) ? item.id : crypto.randomUUID(), (item?.data) ? item.data : null);
96
+ }
97
+ }
98
+
99
+ class UtilsService {
100
+ constructor() {
101
+ this.http = inject(HttpClient);
102
+ this.lc = (str) => str.toLowerCase().replace(/[^\w\s]/g, '').replace(/\s+/g, '_');
103
+ }
104
+ isString(x) {
105
+ return Object.prototype.toString.call(x) === '[object String]';
106
+ }
107
+ isObject(obj) {
108
+ return Object.prototype.toString.call(obj) === '[object Object]';
109
+ }
110
+ JSONToString(value) {
111
+ return (this.isObject(value)) ? JSON.stringify(value) : value;
112
+ }
113
+ stringToJSON(value) {
114
+ return (this.isJSON(value)) ? JSON.parse(value) : value;
115
+ }
116
+ isJSON(str) {
117
+ try {
118
+ JSON.parse(str);
119
+ }
120
+ catch (e) {
121
+ return false;
122
+ }
123
+ return true;
124
+ }
125
+ getValueByProp(obj, prop) {
126
+ if (typeof obj === 'undefined')
127
+ return false;
128
+ return obj[prop];
129
+ }
130
+ objectsEqual(x, y) {
131
+ const ok = Object.keys, tx = typeof x, ty = typeof y;
132
+ return x && y && tx === 'object' && tx === ty ? (ok(x).length === ok(y).length &&
133
+ ok(x).every((key) => this.objectsEqual(x[key], y[key]))) : (x === y);
134
+ }
135
+ getJSON(file) {
136
+ return this.http.get(`assets/data/${file}`);
137
+ }
138
+ get today() {
139
+ return new Date().getMilliseconds() / 1000;
140
+ }
141
+ base32ToHex(base32) {
142
+ const base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
143
+ const charToValue = (char) => base32chars.indexOf(char.toUpperCase());
144
+ let bits = '';
145
+ let hex = '';
146
+ for (let i = 0; i < base32.length; i++) {
147
+ const val = charToValue(base32.charAt(i));
148
+ bits += val.toString(2).padStart(5, '0');
149
+ }
150
+ for (let i = 0; i + 4 <= bits.length; i += 4) {
151
+ const chunk = bits.substr(i, 4);
152
+ hex += parseInt(chunk, 2).toString(16);
153
+ }
154
+ return hex.toUpperCase();
155
+ }
156
+ binaryToHex(binary) {
157
+ let hex = '';
158
+ for (let i = 0; i < binary.length; i += 8) {
159
+ const byte = binary.substr(i, 8);
160
+ const decimal = parseInt(byte, 2);
161
+ hex += decimal.toString(16).padStart(2, '0');
162
+ }
163
+ return hex.padStart(32, '0').substr(0, 32);
164
+ }
165
+ // y = years, m = months, w = weeks, d = days, hr = hours, mn = minutes else seconds
166
+ // returns epoch time corresponding to the expiry type
167
+ expires(str) {
168
+ if (!str)
169
+ return;
170
+ const match = str.match(/[^0-9]+$/);
171
+ const type = (match) ? str.slice(-match[0].length) : 0;
172
+ const now = Math.floor(new Date().getTime() / 1000);
173
+ let value = 0;
174
+ switch (type) {
175
+ case 'y':
176
+ const years = parseInt(str.slice(0, -1));
177
+ value = now + (years * 31556926);
178
+ break;
179
+ case 'm':
180
+ const months = parseInt(str.slice(0, -1));
181
+ value = now + (months * 2629743);
182
+ break;
183
+ case 'w':
184
+ const weeks = parseInt(str.slice(0, -1));
185
+ value = now + (weeks * 604800);
186
+ break;
187
+ case 'd':
188
+ const days = parseInt(str.slice(0, -1));
189
+ value = now + (days * 86400);
190
+ break;
191
+ case 'hr':
192
+ const hrs = parseInt(str.slice(0, -2));
193
+ value = now + (hrs * 3600);
194
+ break;
195
+ case 'mn':
196
+ const min = parseInt(str.slice(0, -2));
197
+ value = now + (min * 60);
198
+ break;
199
+ default: //seconds
200
+ const sec = parseInt(str.slice(0, -1));
201
+ value = now + (sec);
202
+ break;
203
+ }
204
+ return value;
205
+ }
206
+ hasExpired(expiryDate) {
207
+ if (!expiryDate || expiryDate === 0)
208
+ return false;
209
+ const currentTime = Math.floor(new Date().getTime() / 1000);
210
+ return expiryDate < currentTime;
211
+ }
212
+ hasExpiry(setting) {
213
+ return (setting?.expires) ? true : false;
214
+ }
215
+ expiresIn(expiryDate) {
216
+ if (!expiryDate)
217
+ return;
218
+ const now = Math.floor(new Date().getTime() / 1000);
219
+ let diff = expiryDate - now;
220
+ if (diff <= 0)
221
+ return "Expired";
222
+ const units = [
223
+ { label: 'y', seconds: 31536000 },
224
+ { label: 'm', seconds: 2592000 },
225
+ { label: 'w', seconds: 604800 },
226
+ { label: 'd', seconds: 86400 },
227
+ { label: 'h', seconds: 3600 },
228
+ { label: 'min', seconds: 60 },
229
+ { label: '', seconds: 1 },
230
+ ];
231
+ let result = [];
232
+ for (const unit of units) {
233
+ if (diff >= unit.seconds) {
234
+ const value = Math.floor(diff / unit.seconds);
235
+ diff %= unit.seconds;
236
+ result.push(`${value}${unit.label}${value > 1 ? 's' : ''}`);
237
+ }
238
+ }
239
+ return result.join(', ');
240
+ }
241
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
242
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UtilsService, providedIn: 'root' }); }
243
+ }
244
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UtilsService, decorators: [{
245
+ type: Injectable,
246
+ args: [{
247
+ providedIn: 'root'
248
+ }]
249
+ }], ctorParameters: function () { return []; } });
250
+
251
+ const Random = () => {
252
+ const typedArray = new Uint8Array(1);
253
+ const randomValue = crypto.getRandomValues(typedArray)[0];
254
+ const randomFloat = randomValue / Math.pow(2, 8);
255
+ return randomFloat;
256
+ };
257
+ const RandomNumber = (min, max) => {
258
+ return Math.floor(Random() * max) + min;
259
+ };
260
+ const RandomNumbers = (min, max, length) => {
261
+ const numbers = [];
262
+ for (let i = 0; i < length; i++)
263
+ numbers.push(Math.floor(Random() * max) + min);
264
+ return numbers;
265
+ };
266
+ const RandomNumbersUnique = (min, max, length) => {
267
+ let count = 0;
268
+ // Adjust the length if it exceeds the number of unique numbers possible in the range
269
+ if (length > (max - min + 1)) {
270
+ console.error('error encountered');
271
+ length = max - min + 1;
272
+ }
273
+ console.log('length', length);
274
+ const numbers = [];
275
+ const maxAttempts = length * 100; // Safeguard to prevent infinite loops
276
+ while (numbers.length < length && count < maxAttempts) {
277
+ const num = Math.floor(Random() * max) + min;
278
+ if (!numbers.includes(num)) {
279
+ numbers.push(num);
280
+ }
281
+ }
282
+ if (count >= maxAttempts) {
283
+ throw new Error('Maximum attempts exceeded while generating unique numbers');
284
+ }
285
+ return numbers;
286
+ };
287
+ const RandomStr = () => {
288
+ const typedArray = new Uint8Array(8);
289
+ const array = new Uint32Array(1);
290
+ crypto.getRandomValues(array);
291
+ return array[0].toString(36);
292
+ };
293
+ const RandomSignature = () => {
294
+ const typedArray = new Uint8Array(8);
295
+ const array = new Uint32Array(1);
296
+ crypto.getRandomValues(array);
297
+ return array[0];
298
+ };
299
+ const UUID = () => {
300
+ return self.crypto.randomUUID();
301
+ };
302
+
303
+ // Must provide a value for APP_ID in AppModule->Providers
304
+ // providers: [
305
+ // {
306
+ // provide: APP_ID,
307
+ // useValue: "056991ac-3537-43ab-b5b9-83edf6554eff",
308
+ // },
309
+ class AppService {
310
+ constructor(id) {
311
+ this.id = id;
312
+ this.appID = this.id;
313
+ }
314
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppService, deps: [{ token: APP_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
315
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppService, providedIn: 'root' }); }
316
+ }
317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppService, decorators: [{
318
+ type: Injectable,
319
+ args: [{
320
+ providedIn: 'root'
321
+ }]
322
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
323
+ type: Inject,
324
+ args: [APP_ID]
325
+ }] }]; } });
326
+
327
+ class SymmetricalEncryptionService {
328
+ constructor() {
329
+ this.appService = inject(AppService);
330
+ // TODO: The APP ID is not a string, it is a function
331
+ this.appID = (this.appService.appID) ? this.appService.appID : '';
332
+ if (this.appID === '')
333
+ console.warn('No App Key has been define');
334
+ }
335
+ generateCipherKey() {
336
+ return (RandomSignature().toString() + RandomSignature().toString()).substring(0, 8);
337
+ }
338
+ encrypt(str, key = this.appID) {
339
+ if (!str || key === '')
340
+ return '';
341
+ let _key = CryptoJS.enc.Utf8.parse(key);
342
+ let _iv = CryptoJS.enc.Utf8.parse(key);
343
+ try {
344
+ const encrypted = CryptoJS.AES.encrypt(JSON.stringify(str), _key, {
345
+ keySize: 16,
346
+ iv: _iv,
347
+ mode: CryptoJS.mode.ECB,
348
+ padding: CryptoJS.pad.Pkcs7
349
+ });
350
+ return encrypted.toString();
351
+ }
352
+ catch (error) {
353
+ console.log(error);
354
+ }
355
+ return;
356
+ }
357
+ decrypt(str, key = this.appID) {
358
+ if (!str || key === '')
359
+ return;
360
+ let _key = CryptoJS.enc.Utf8.parse(key);
361
+ let _iv = CryptoJS.enc.Utf8.parse(key);
362
+ try {
363
+ return CryptoJS.AES.decrypt(str, _key, {
364
+ keySize: 16,
365
+ iv: _iv,
366
+ mode: CryptoJS.mode.ECB,
367
+ padding: CryptoJS.pad.Pkcs7
368
+ }).toString(CryptoJS.enc.Utf8);
369
+ }
370
+ catch (error) {
371
+ console.log(error);
372
+ }
373
+ return;
374
+ }
375
+ createSignature(url, len = 16) {
376
+ const sig = CryptoJS.SHA256(url).toString(CryptoJS.enc.Hex);
377
+ return sig.substring(0, len).toUpperCase();
378
+ }
379
+ normalizeURL(url) {
380
+ const normalizedURL = url.replace(/(https?:\/\/)?(www\.)?/, '').replace(/\/+$/, '');
381
+ return normalizedURL;
382
+ }
383
+ generateSignature(url) {
384
+ const normalizedURL = this.normalizeURL(url);
385
+ const hash = CryptoJS.SHA256(normalizedURL);
386
+ const signature = hash.toString(CryptoJS.enc.Hex);
387
+ return signature;
388
+ }
389
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SymmetricalEncryptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
390
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SymmetricalEncryptionService, providedIn: 'root' }); }
391
+ }
392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SymmetricalEncryptionService, decorators: [{
393
+ type: Injectable,
394
+ args: [{
395
+ providedIn: 'root'
396
+ }]
397
+ }], ctorParameters: function () { return []; } });
398
+
399
+ class EncryptionTestService {
400
+ constructor() { }
401
+ isBase64(str) {
402
+ const base64Pattern = /^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i;
403
+ return base64Pattern.test(str);
404
+ }
405
+ isHexadecimal(str) {
406
+ const hexPattern = /^[0-9a-fA-F]+$/;
407
+ return hexPattern.test(str) && (str.length % 2 === 0);
408
+ }
409
+ hasHighEntropy(str) {
410
+ const uniqueChars = new Set(str).size;
411
+ return uniqueChars > str.length * 0.6;
412
+ }
413
+ isEncrypted(str) {
414
+ if (typeof str !== 'string') {
415
+ return false;
416
+ }
417
+ if (this.isBase64(str) || this.isHexadecimal(str)) {
418
+ return true;
419
+ }
420
+ return this.hasHighEntropy(str);
421
+ }
422
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EncryptionTestService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
423
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EncryptionTestService, providedIn: 'root' }); }
424
+ }
425
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EncryptionTestService, decorators: [{
426
+ type: Injectable,
427
+ args: [{
428
+ providedIn: 'root'
429
+ }]
430
+ }], ctorParameters: function () { return []; } });
431
+
432
+ /**
433
+ * An injection token that provides the configuration settings for the application.
434
+ * This token can be used to inject the `ConfigSettings` instance into components or services
435
+ * that require access to the application configuration.
436
+ */
437
+ const CONFIG_SETTINGS_TOKEN = new InjectionToken('http.config');
438
+
439
+ class HeadersService {
440
+ constructor() {
441
+ this.headers = {};
442
+ }
443
+ generateHeaders(headers) {
444
+ const allHeaders = headers ? { ...this.headers, ...headers } : {};
445
+ return { headers: new HttpHeaders(allHeaders) };
446
+ }
447
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeadersService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
448
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeadersService, providedIn: 'root' }); }
449
+ }
450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HeadersService, decorators: [{
451
+ type: Injectable,
452
+ args: [{
453
+ providedIn: 'root'
454
+ }]
455
+ }] });
456
+
457
+ class PathQueryService {
458
+ constructor() {
459
+ this.removeEmptyParams = (obj) => Object.fromEntries(Object.entries(obj)
460
+ .map(([key, value]) => [key, value && typeof value === 'object' ? this.removeEmptyParams(value) : value])
461
+ .filter(([_, value]) => value !== undefined && value !== ""));
462
+ }
463
+ buildAPIPath(server, params) {
464
+ server = (Array.isArray(server)) ? server.join('/') : server;
465
+ const pathObjects = (params) ? params.filter((path) => (!this.isObject(path))) : [];
466
+ const queryObjects = (params) ? params.filter((path) => (this.isObject(path))) : [];
467
+ const query = this.removeEmptyParams(queryObjects.reduce((r, c) => {
468
+ Object.entries(c).forEach(([key, value]) => {
469
+ r[key] = Array.isArray(value) ? value.join(',') : value;
470
+ });
471
+ return r;
472
+ }, {}));
473
+ let path = this.buildRestPath(server, pathObjects);
474
+ return (Object.keys(query).length > 0) ? path + '?' + this.buildQueryPath(query) : path;
475
+ }
476
+ buildRestPath(server, params) {
477
+ server = (server) ? server : '';
478
+ server = (server.charAt(0) === '/') ? server.substring(1) : server;
479
+ return this.cleanUrlPath(server + '/' + params.join('/'));
480
+ }
481
+ buildQueryPath(params) {
482
+ const searchParams = new URLSearchParams();
483
+ for (const key in params) {
484
+ if (Array.isArray(params[key])) {
485
+ params[key].forEach((value) => searchParams.append(key, value));
486
+ }
487
+ else {
488
+ searchParams.append(key, params[key]);
489
+ }
490
+ }
491
+ return searchParams.toString();
492
+ }
493
+ cleanUrlPath(str) {
494
+ return str.replace(/([^:]\/)\/+/g, "$1").replace(/\/$/, '');
495
+ }
496
+ isObject(val) {
497
+ return (val === null) ? false : ((typeof val === 'function') || (typeof val === 'object'));
498
+ }
499
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PathQueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
500
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PathQueryService, providedIn: 'root' }); }
501
+ }
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PathQueryService, decorators: [{
503
+ type: Injectable,
504
+ args: [{
505
+ providedIn: 'root'
506
+ }]
507
+ }] });
508
+
509
+ class AsymmetricalEncryptionService {
510
+ constructor() { }
511
+ generateKeyPair(modulusLength = 2048) {
512
+ // modulusLength - 1024, 2048, 4096
513
+ // hash - SHA-256
514
+ return from(crypto.subtle.generateKey({
515
+ name: "RSA-OAEP",
516
+ modulusLength,
517
+ publicExponent: new Uint8Array([1, 0, 1]),
518
+ hash: { name: "SHA-256" }
519
+ }, true, // Extractable keys
520
+ ["encrypt", "decrypt"]));
521
+ }
522
+ encryptData(publicKey, data) {
523
+ const encodedData = new TextEncoder().encode(data);
524
+ return from(crypto.subtle.encrypt({
525
+ name: "RSA-OAEP"
526
+ }, publicKey, encodedData)).pipe(map(enc => this.arrayBufferToBase64(enc)));
527
+ }
528
+ decryptData(privateKey, encryptedData) {
529
+ const encStr = this.base64ToArrayBuffer(encryptedData);
530
+ return from(crypto.subtle.decrypt({
531
+ name: "RSA-OAEP"
532
+ }, privateKey, encStr).then(decryptedData => {
533
+ return new TextDecoder().decode(decryptedData);
534
+ }));
535
+ }
536
+ pemToArrayBuffer(pem) {
537
+ const b64 = pem.replace(/(-----BEGIN (RSA )?(PRIVATE|PUBLIC) KEY-----|-----END (RSA )?(PRIVATE|PUBLIC) KEY-----|\n)/g, '');
538
+ const binaryString = atob(b64);
539
+ const len = binaryString.length;
540
+ const buffer = new ArrayBuffer(len);
541
+ const view = new Uint8Array(buffer);
542
+ for (let i = 0; i < len; i++) {
543
+ view[i] = binaryString.charCodeAt(i);
544
+ }
545
+ return buffer;
546
+ }
547
+ base64ToArrayBuffer(base64) {
548
+ const binaryString = atob(base64);
549
+ const len = binaryString.length;
550
+ const buffer = new ArrayBuffer(len);
551
+ const view = new Uint8Array(buffer);
552
+ for (let i = 0; i < len; i++) {
553
+ view[i] = binaryString.charCodeAt(i);
554
+ }
555
+ return buffer;
556
+ }
557
+ arrayBufferToBase64(buffer) {
558
+ let binary = '';
559
+ const bytes = new Uint8Array(buffer);
560
+ const len = bytes.byteLength;
561
+ for (let i = 0; i < len; i++) {
562
+ binary += String.fromCharCode(bytes[i]);
563
+ }
564
+ return window.btoa(binary);
565
+ }
566
+ base64ToPEM(base64Key, publicKey = true) {
567
+ const keyType = (publicKey) ? 'PUBLIC' : 'PRIVATE';
568
+ const header = `-----BEGIN ${keyType} KEY-----\n`;
569
+ const footer = `\n-----END ${keyType} KEY-----`;
570
+ const keyBody = base64Key.match(/.{1,64}/g)?.join("\n") || "";
571
+ return header + keyBody + footer;
572
+ }
573
+ pemToCryptoKey(pem, algorithm, extractable, keyUsages, format = "pkcs8" //"raw" | "pkcs8" | "spki"
574
+ ) {
575
+ const buffer = this.pemToArrayBuffer(pem);
576
+ console.log('buffer found ', buffer);
577
+ return from(crypto.subtle.importKey(format, buffer, algorithm, extractable, keyUsages));
578
+ }
579
+ // TESTING
580
+ testGenerateKeys() {
581
+ const testSequence = new BehaviorSubject("");
582
+ const testSequence$ = testSequence.asObservable();
583
+ testSequence.next("Test Generating Keys");
584
+ // GENERATE KEYS
585
+ this.generateKeyPair().subscribe((data) => {
586
+ console.log("GEN-GENERATED KEYS: ", data);
587
+ crypto.subtle.exportKey('spki', data.publicKey)
588
+ .then(key => {
589
+ const publicKeyBase64 = this.arrayBufferToBase64(key);
590
+ console.log("GEN-EXPORT PUBLIC KEY: ", this.base64ToPEM(publicKeyBase64, true));
591
+ });
592
+ crypto.subtle.exportKey('pkcs8', data.privateKey)
593
+ .then(key => {
594
+ const privateKeyBase64 = this.arrayBufferToBase64(key);
595
+ console.log("GEN-EXPORT PRIVATE KEY: ", this.base64ToPEM(privateKeyBase64, false));
596
+ });
597
+ // TEST WITH GENERATED KEYS
598
+ this.encryptData(data.publicKey, "Sample Data here - Mike Bonifacio")
599
+ .subscribe((enc) => {
600
+ console.log("GEN-ENCRYPT==>: ", enc);
601
+ this.decryptData(data.privateKey, enc).subscribe((dec) => {
602
+ testSequence.next('Test Passed');
603
+ testSequence.complete();
604
+ });
605
+ });
606
+ });
607
+ return testSequence$;
608
+ }
609
+ testDecryptionWithKeys() {
610
+ const testSequence = new BehaviorSubject("");
611
+ const testSequence$ = testSequence.asObservable();
612
+ testSequence.next("Test Generating Keys");
613
+ const privateKey = `-----BEGIN PRIVATE KEY-----
614
+ MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDKVBkCWNb9eHVF
615
+ twAA5mdAyvXFix3WavdrsoYRkvtCl8ogDBQf8f6N0bRkDF1zcVHRrNAEyozXDtuD
616
+ kFgSiivBFREI7fiS3sOvduq6FaGXzX0IY6oaVMu8oOPgDvC0yvoohR+0Qxq2d6lP
617
+ SPyHeKQaxP4KxzCJJzB1XAcbd2eFzUUDv25mNlwdVkmW8FI/sAxnJLgPTW78dzfX
618
+ Ddfk+nxdIqxVKSLATnL0kMN7aGJx24UozioAIpzvvvF5/+7HTd1gi6NeCqrAYr3g
619
+ iP364AE26CFwFvHnafO9uNQhlQ+uiNnOoInXByfFGVP+RidSpfLzaxDjs6RDwpol
620
+ h098btONAgMBAAECggEAAVhHM2OD5IkUtuowwcKNaCTKGmrClRE3gMuzJeBsSJEy
621
+ uAReUFILZylcnhegDytSti2vDA9T7xqtO6CU0p3V8LpU89JMOPRb/deirI4UXSpx
622
+ xbNyjirOO6bnrNlOWfKexdQQsikYPzF2iM1Scpr1u9ZDCHZOl1ZYSrkve5My4coP
623
+ 3Gx6tTBqL0jQBfcpf4ES8BH3JSawR/MgqzDS74+bI2VH+kvuPAC1L4fBgaV3VUv0
624
+ nFzim5A3s5VaXPgJbEIghP9BkYGFkeT9ma3nliEZWc96AzsmowFn1ayCvrNVPo9R
625
+ ECD2NnttBiCJZt3H93sR9+OTeA8Bls+aZGlKd5mLAQKBgQDpf8nIYUm/Zmls7/lQ
626
+ QBUSGHEYrbjNsEejQsPgNDtg2EVSxdUkvTn7Wb+HExTk09Z5bNvhaO2532/FH9y8
627
+ ahSXafiMXpfR2olwXdOB9yXXl4F5C0LGnmzGim4OSeWzAX0JCL470KaS0QN3EmoG
628
+ 9F0YCfMnZXNTweSSx4xvlO6ggQKBgQDd01uIolm7z1DIWCwNERAXP2GDwcvxyzYK
629
+ YqJfKDeHt2t6yIzZMMotnPDy+OlcdGspIIHkB5a+SZN5Nt7DUKg/MnyOZ3KbVq41
630
+ k7dR4Ka3LRnGkesy7lSr7ef1rfquyR75OXJQcPWvkFcLu0TMiQhvptatZ8VN+F4n
631
+ fDQELRotDQKBgQCgN+AUT7VT0QjcCBnRV/ddUEoiPenFsYSmYMSYzh5ESIHg1wB2
632
+ 0iS79Iw4Of6nOTg8X1bM57vfQ5Kk90T2P+/bKYqzfqC8DTErWiYsUpKzyTC9Bt4N
633
+ /Vz0Kr5zrX8ggg/yp/4oevYhXav8AzWfigNq4EDpMnKc8TlPAf+5/L50gQKBgQC2
634
+ mLPhPhr1gUszD3l7bA89w7uGlLFHoQoj9FtKTzWervp3QLzIT+QtNeIVb5XQuDg5
635
+ y3uAdEq+6pvNjMBEMJG+K9Xh9v+dJPYUPjsJ2A4D/MkZ7qWX8B2cxSJK1uLim8W2
636
+ S3ZxBvsGgJ9WldmlMCvUlJZkeWYtr4P5psC+q02/xQKBgQCDII/jcV2+lRM2iNTe
637
+ vBijZSaNMEWOK/Y+/HFK8GYKXnB+xNWhrm8rKgWGzpDJAUPMh9Tt+leW9LKEBuzF
638
+ Y1bGblmGm1zsPWpIx05Fdtv9eOJmFnXbGzIsYyhadZnPcQOWhqxtpVxSuul0Jc7Q
639
+ XNq4qPaPXhbQAshgtyBt75DMkw==
640
+ -----END PRIVATE KEY-----`;
641
+ const pubKey = `-----BEGIN PUBLIC KEY-----
642
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylQZAljW/Xh1RbcAAOZn
643
+ QMr1xYsd1mr3a7KGEZL7QpfKIAwUH/H+jdG0ZAxdc3FR0azQBMqM1w7bg5BYEoor
644
+ wRURCO34kt7Dr3bquhWhl819CGOqGlTLvKDj4A7wtMr6KIUftEMatnepT0j8h3ik
645
+ GsT+CscwiScwdVwHG3dnhc1FA79uZjZcHVZJlvBSP7AMZyS4D01u/Hc31w3X5Pp8
646
+ XSKsVSkiwE5y9JDDe2hicduFKM4qACKc777xef/ux03dYIujXgqqwGK94Ij9+uAB
647
+ NughcBbx52nzvbjUIZUProjZzqCJ1wcnxRlT/kYnUqXy82sQ47OkQ8KaJYdPfG7T
648
+ jQIDAQAB
649
+ -----END PUBLIC KEY-----`;
650
+ const algorithm = {
651
+ name: "RSA-OAEP",
652
+ modulusLength: 2048,
653
+ publicExponent: new Uint8Array([1, 0, 1]),
654
+ hash: "SHA-256"
655
+ };
656
+ // ENCRYPT
657
+ this.pemToCryptoKey(pubKey, algorithm, true, ["encrypt"], "spki").subscribe((keyPublic) => {
658
+ // console.log("PUBLIC KEY: ", keyPublic)
659
+ this.encryptData(keyPublic, "Sample Data here - Mike Bonifacio")
660
+ .subscribe((str) => {
661
+ console.log("ENCRYPTED STRING: ", str);
662
+ testSequence.next('encrypted string success');
663
+ });
664
+ });
665
+ const enc = "r7UOuEGBZ6jbVTOIBuv9jFOEtRiedmS27hfW40k7XKCTsQ5VhWup0qu2BA2ANZaGKii/uehJ/RSPiyfGbJ6leJrat0mA1hPqH/XodaBzLMDigvdYM1NSXFZMDa40OpLUIXbPlAvybjcGu7Bal+LMA8htHrFu/OmM/fHI66xOzzpuXSYx0OkWjtY81rUQ1FFkvrkx2jGFPZ0p+Nw/v3Q4cJnet6V63vCueFlD749VMcVXo7pvz4AIPpB+IOy3kbxaYTPakLVioJERU6GFMXWkECuRvohhS9CETcORZtRVRkvhcHk3lxgIhfqojUKYgD6K5dDELDPsWIS+iTG1XIQIlg==";
666
+ // DECRYPTION
667
+ this.pemToCryptoKey(privateKey, algorithm, false, ["decrypt"], "pkcs8").subscribe((key) => {
668
+ // console.log("DECRYPT ===", key)
669
+ this.decryptData(key, enc)
670
+ .pipe(catchError(err => {
671
+ console.log("ERROR: ", err);
672
+ return EMPTY;
673
+ })).subscribe((str) => {
674
+ console.log("DECRYPTED STRING: ", str);
675
+ testSequence.next('decrypted string success');
676
+ });
677
+ });
678
+ return testSequence$;
679
+ }
680
+ ;
681
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AsymmetricalEncryptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
682
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AsymmetricalEncryptionService, providedIn: 'root' }); }
683
+ }
684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AsymmetricalEncryptionService, decorators: [{
685
+ type: Injectable,
686
+ args: [{
687
+ providedIn: 'root'
688
+ }]
689
+ }], ctorParameters: function () { return []; } });
690
+
691
+ function requestStreaming() {
692
+ return input$ => input$.pipe(filter((event) => event.type === HttpEventType.DownloadProgress || event.type === HttpEventType.Response), map((event) => {
693
+ if (event.type === HttpEventType.DownloadProgress) {
694
+ return event.partialText || '';
695
+ }
696
+ else if (event.type === HttpEventType.Response) {
697
+ return event.body;
698
+ }
699
+ }), map((data) => {
700
+ if (typeof data === 'string') {
701
+ const matches = data.match(/{[^}]+}/g) || [];
702
+ return (matches.length > 0) ? matches.map(match => JSON.parse(match)) : data;
703
+ }
704
+ return data;
705
+ }));
706
+ }
707
+
708
+ class RequestService {
709
+ constructor() {
710
+ this.http = inject(HttpClient);
711
+ this.pathQueryService = inject(PathQueryService);
712
+ this.headersService = inject(HeadersService);
713
+ this.isPending = new BehaviorSubject(false);
714
+ this.isPending$ = this.isPending.asObservable().pipe(delay(1));
715
+ this.progress = new BehaviorSubject(0);
716
+ this.progress$ = this.progress.asObservable();
717
+ }
718
+ getRecordRequest(options) {
719
+ const urlPath = this.buildUrlPath(options);
720
+ const headers = this.buildCombinedHeaders(options);
721
+ this.isPending.next(true);
722
+ return (options.stream)
723
+ ? this.http.get(urlPath, headers).pipe(requestStreaming(), this.handleFinalize())
724
+ : this.http.get(urlPath, headers).pipe(this.request(options));
725
+ }
726
+ createRecordRequest(options, data) {
727
+ const urlPath = this.buildUrlPath(options);
728
+ const headers = this.buildCombinedHeaders(options);
729
+ this.isPending.next(true);
730
+ return (options.stream)
731
+ ? this.http.post(urlPath, data, headers).pipe(requestStreaming(), this.handleFinalize())
732
+ : this.http.post(urlPath, data, headers).pipe(this.request(options));
733
+ }
734
+ updateRecordRequest(options, data) {
735
+ const urlPath = this.buildUrlPath(options);
736
+ const headers = this.buildHeaders(options);
737
+ this.isPending.next(true);
738
+ return this.http.put(urlPath, data, headers).pipe(this.request(options));
739
+ }
740
+ deleteRecordRequest(options) {
741
+ const urlPath = this.buildUrlPath(options);
742
+ const headers = this.buildHeaders(options);
743
+ this.isPending.next(true);
744
+ return this.http.delete(urlPath, headers).pipe(this.request(options));
745
+ }
746
+ // Helper functions
747
+ buildUrlPath(options) {
748
+ return this.pathQueryService.buildAPIPath(options.server, options.path);
749
+ }
750
+ buildHeaders(options) {
751
+ return this.headersService.generateHeaders(options.headers);
752
+ }
753
+ buildCombinedHeaders(options) {
754
+ const headers = this.headersService.generateHeaders(options.headers);
755
+ return this.combineHeaders(headers, options.stream || false);
756
+ }
757
+ request(options) {
758
+ return (source$) => {
759
+ return source$.pipe(map(data => {
760
+ if (options?.adapter) {
761
+ return Array.isArray(data)
762
+ ? data.map((item) => options.adapter(item))
763
+ : options.adapter(data);
764
+ }
765
+ return data;
766
+ }));
767
+ };
768
+ }
769
+ downloadFileRequest(options) {
770
+ this.isPending.next(true);
771
+ const urlPath = this.buildUrlPath(options);
772
+ return this.http.get(urlPath, { responseType: 'blob', observe: 'events', reportProgress: true })
773
+ .pipe(map((event) => {
774
+ this.isPending.next(true);
775
+ if (event instanceof HttpHeaderResponse) {
776
+ if (event.status !== 200) {
777
+ this.isPending.next(false);
778
+ throw new Error('Download failed');
779
+ }
780
+ }
781
+ // 0 Sent Request has been sent.
782
+ // 1 UploadProgress Upload is in progress.
783
+ // 2 ResponseHeader Response headers received.
784
+ // 3 DownloadProgress Download is in progress.
785
+ // 4 Response Response is fully received.
786
+ // 5 User Custom user event.
787
+ switch (event.type) {
788
+ case HttpEventType.DownloadProgress:
789
+ const status = (event.total) ? Math.round(event.loaded / (event.total || 1) * 100) : 100;
790
+ this.progress.next(status);
791
+ return status;
792
+ case HttpEventType.Response:
793
+ try {
794
+ const fileNamePath = (options?.saveAs) ? options.saveAs : (options.path) ? options.path[options.path.length - 1] : [];
795
+ const header_content = event.headers.get('Content-Disposition') || '';
796
+ // checks if header_content is not empty and splits the header_content to get the file name
797
+ // otherwise, it will use the fileDownload - contains the file name and extension
798
+ const file = (header_content) ? header_content.split('=')[1].substring(0, header_content.split('=')[1].length) : '';
799
+ const fileName = (fileNamePath !== '') ? fileNamePath : file;
800
+ if (fileName === '') {
801
+ this.isPending.next(false);
802
+ throw new Error('Save File: (file name and extension) not found in Headers or Path');
803
+ }
804
+ this.downloadFile(fileName, event.body);
805
+ this.isPending.next(false);
806
+ return 100;
807
+ }
808
+ catch (error) {
809
+ throw new Error('Download failed');
810
+ }
811
+ default:
812
+ this.isPending.next(false);
813
+ return 0;
814
+ }
815
+ }), catchError(err => {
816
+ return throwError(() => err);
817
+ }));
818
+ }
819
+ handleFinalize() {
820
+ return finalize(() => this.isPending.next(false));
821
+ }
822
+ downloadFile(file, fileData) {
823
+ const navigatorAny = window.navigator;
824
+ const extension = file.split('.')[1].toLowerCase();
825
+ var newBlob = new Blob([fileData], { type: this.createFileType(extension) });
826
+ if (navigatorAny.msSaveOrOpenBlob) {
827
+ navigatorAny.msSaveOrOpenBlob(newBlob, file);
828
+ }
829
+ else {
830
+ const link = document.createElement('a');
831
+ const url = window.URL.createObjectURL(newBlob);
832
+ link.href = url;
833
+ link.download = file;
834
+ link.click();
835
+ window.URL.revokeObjectURL(url);
836
+ }
837
+ }
838
+ createFileType(ext) {
839
+ let fileType = "";
840
+ if (ext == 'pdf' || ext == 'csv') {
841
+ fileType = `application/${ext}`;
842
+ }
843
+ else if (ext == 'jpeg' || ext == 'jpg' || ext == 'png') {
844
+ fileType = `image/${ext}`;
845
+ }
846
+ else if (ext == 'txt') {
847
+ fileType = 'text/plain';
848
+ }
849
+ else if (ext == 'ppt' || ext == 'pot' || ext == 'pps' || ext == 'ppa') {
850
+ fileType = 'application/vnd.ms-powerpoint';
851
+ }
852
+ else if (ext == 'pptx') {
853
+ fileType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
854
+ }
855
+ else if (ext == 'doc' || ext == 'dot') {
856
+ fileType = 'application/msword';
857
+ }
858
+ else if (ext == 'docx') {
859
+ fileType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
860
+ }
861
+ else if (ext == 'xls' || ext == 'xlt' || ext == 'xla') {
862
+ fileType = 'application/vnd.ms-excel';
863
+ }
864
+ else if (ext == 'xlsx') {
865
+ fileType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
866
+ }
867
+ return fileType;
868
+ }
869
+ combineHeaders(headers, isStreaming) {
870
+ return (isStreaming) ?
871
+ {
872
+ ...headers,
873
+ observe: 'events',
874
+ responseType: 'text',
875
+ reportProgress: true,
876
+ Accept: 'text/event-stream'
877
+ }
878
+ : headers;
879
+ }
880
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
881
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestService, providedIn: 'root' }); }
882
+ }
883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestService, decorators: [{
884
+ type: Injectable,
885
+ args: [{
886
+ providedIn: 'root'
887
+ }]
888
+ }] });
889
+
890
+ function countdown(duration) {
891
+ return defer(() => {
892
+ const currentCount = { current: duration };
893
+ return interval(1000).pipe(map(() => --currentCount.current), takeWhile(count => count >= 0));
894
+ });
895
+ }
896
+
897
+ const DEFAULT_MAX_RETRIES = 3;
898
+ function delayedRetry(delayMs, maxRetry = DEFAULT_MAX_RETRIES) {
899
+ return (src) => src.pipe(retry({
900
+ count: maxRetry,
901
+ delay: () => timer(delayMs)
902
+ }));
903
+ }
904
+
905
+ /**
906
+ * @param pollInterval
907
+ * @param stopCondition$
908
+ * @param isPending$
909
+ */
910
+ function requestPolling(pollInterval, stopCondition$, isPending$) {
911
+ return (source) => {
912
+ return interval(pollInterval * 1000)
913
+ .pipe(startWith(0), tap(() => isPending$.next(true)), mergeMap(() => source), tap(() => isPending$.next(false)), takeUntil(stopCondition$));
914
+ };
915
+ }
916
+
917
+ class DatabaseStorage {
918
+ constructor(table = '', expiresIn) {
919
+ this.table = table;
920
+ this.expiresIn = expiresIn;
921
+ }
922
+ static adapt(item) {
923
+ return new DatabaseStorage(item?.table, item?.expiresIn);
924
+ }
925
+ }
926
+
927
+ class RetryOptions {
928
+ constructor(times = 0, delay = 3) {
929
+ this.times = times;
930
+ this.delay = delay;
931
+ }
932
+ static adapt(item) {
933
+ return new RetryOptions(item?.times, item?.delay);
934
+ }
935
+ }
936
+
937
+ var DataType;
938
+ (function (DataType) {
939
+ DataType[DataType["ANY"] = 0] = "ANY";
940
+ DataType[DataType["ARRAY"] = 1] = "ARRAY";
941
+ DataType[DataType["OBJECT"] = 2] = "OBJECT";
942
+ })(DataType || (DataType = {}));
943
+
944
+ class ConfigHTTPOptions {
945
+ constructor(server = '', path, headers, polling, retry, stream, displayError) {
946
+ this.server = server;
947
+ this.path = path;
948
+ this.headers = headers;
949
+ this.polling = polling;
950
+ this.retry = retry;
951
+ this.stream = stream;
952
+ this.displayError = displayError;
953
+ }
954
+ static adapt(item) {
955
+ const server = Array.isArray(item?.server) ? item.server.join('/') : item?.server || '';
956
+ const retryOptions = item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt();
957
+ return new ConfigHTTPOptions(server, (item?.path) ? item.path : [], (item?.headers) ? item.headers : {}, item?.polling ? Math.floor(item.polling) : 0, retryOptions, (item?.stream) ? item.stream : false, (item?.displayError) ? item.displayError : false);
958
+ }
959
+ }
960
+
961
+ class LocalStorageOptions {
962
+ constructor(storageName, storageSettingsName, options) {
963
+ this.storageName = storageName;
964
+ this.storageSettingsName = storageSettingsName;
965
+ this.options = options;
966
+ }
967
+ static adapt(item) {
968
+ return new LocalStorageOptions((item?.storageName) ? item.storageName : 'storage', (item?.storageSettingsName) ? item.storageSettingsName : 'global-storage', (item?.options) ? SettingOptions.adapt(item.options) : SettingOptions.adapt());
969
+ }
970
+ }
971
+
972
+ class ConfigOptions {
973
+ constructor(httpRequestOptions, LocalStorageOptions) {
974
+ this.httpRequestOptions = httpRequestOptions;
975
+ this.LocalStorageOptions = LocalStorageOptions;
976
+ }
977
+ static adapt(item) {
978
+ return new ConfigOptions((item?.httpRequestOptions) ? ConfigHTTPOptions.adapt(item.httpRequestOptions) : undefined, (item?.LocalStorageOptions) ? LocalStorageOptions.adapt(item.LocalStorageOptions) : undefined);
979
+ }
980
+ }
981
+
982
+ class HTTPManagerService extends RequestService {
983
+ constructor(configOptions) {
984
+ super();
985
+ this.configOptions = configOptions;
986
+ this.toastMessage = inject(ToastMessageDisplayService);
987
+ this.ng_injector = inject(Injector);
988
+ this.objectMergerService = inject(ObjectMergerService);
989
+ this.countdown = new BehaviorSubject(0);
990
+ this.countdown$ = this.countdown.asObservable();
991
+ this.error = new BehaviorSubject(false);
992
+ this.error$ = this.error.asObservable();
993
+ this.data = new BehaviorSubject(null);
994
+ this.data$ = this.data.asObservable();
995
+ this.polling$ = new Subject();
996
+ this.config = ApiRequest.adapt();
997
+ this.config = (configOptions) ? ApiRequest.adapt(configOptions.httpRequestOptions) : this.config;
998
+ }
999
+ // REQUESTS
1000
+ getRequest(options, params) {
1001
+ this.isPending.next(true);
1002
+ this.data.next(null);
1003
+ const updatedOptions = this.defineReqOptions(options, params);
1004
+ const func = this.getRecordRequest;
1005
+ const requests = this.createRequest(func, updatedOptions);
1006
+ return this.createObservable(updatedOptions, requests, func.name)
1007
+ .pipe(tap(data => this.data.next(data))).pipe(finalize(() => this.isPending.next(false)), catchError((err) => {
1008
+ if (updatedOptions.displayError)
1009
+ this.handleErrorWithSnackBar(err);
1010
+ this.isPending.next(false);
1011
+ return this.handleError(err);
1012
+ }));
1013
+ }
1014
+ postRequest(data, options, params) {
1015
+ this.isPending.next(true);
1016
+ this.data.next(null);
1017
+ const updatedOptions = this.defineReqOptions(options, params);
1018
+ const func = this.createRecordRequest;
1019
+ const requests = this.createRequest(func, updatedOptions, data);
1020
+ return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => this.data.next(data)))
1021
+ .pipe(finalize(() => this.isPending.next(false)), catchError((err) => {
1022
+ if (updatedOptions.displayError)
1023
+ this.handleErrorWithSnackBar(err);
1024
+ this.isPending.next(false);
1025
+ return this.handleError(err);
1026
+ }));
1027
+ }
1028
+ putRequest(data, options, params) {
1029
+ this.isPending.next(true);
1030
+ this.data.next(null);
1031
+ const updatedOptions = this.defineReqOptions(options, params);
1032
+ const func = this.updateRecordRequest;
1033
+ const requests = this.createRequest(func, updatedOptions, data);
1034
+ return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => this.data.next(data)))
1035
+ .pipe(finalize(() => this.isPending.next(false)), catchError((err) => {
1036
+ if (updatedOptions.displayError)
1037
+ this.handleErrorWithSnackBar(err);
1038
+ this.isPending.next(false);
1039
+ return this.handleError(err);
1040
+ }));
1041
+ }
1042
+ deleteRequest(options, params) {
1043
+ this.isPending.next(true);
1044
+ this.data.next(null);
1045
+ const updatedOptions = this.defineReqOptions(options, params);
1046
+ const func = this.deleteRecordRequest;
1047
+ const requests = this.createRequest(func, updatedOptions);
1048
+ return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => this.data.next(data)))
1049
+ .pipe(finalize(() => this.isPending.next(false)), catchError((err) => {
1050
+ if (updatedOptions.displayError)
1051
+ this.handleErrorWithSnackBar(err);
1052
+ this.isPending.next(false);
1053
+ return this.handleError(err);
1054
+ }));
1055
+ }
1056
+ downloadRequest(options, params, saveAs) {
1057
+ this.isPending.next(true);
1058
+ const updatedOptions = this.defineReqOptions(options, params);
1059
+ const func = this.downloadFileRequest;
1060
+ const requests = this.createRequest(func, updatedOptions);
1061
+ return this.createObservable(updatedOptions, requests, func.name)
1062
+ .pipe(catchError((err) => {
1063
+ this.error.next(true);
1064
+ this.isPending.next(false);
1065
+ return this.handleError(err);
1066
+ }));
1067
+ }
1068
+ createObservable(options, request$, funcName) {
1069
+ const polling = options.polling ? (options.polling > 0 ? true : false) : false;
1070
+ const isPolling = polling &&
1071
+ !(funcName === 'deleteRecordRequest' || funcName === 'updateRecordRequest' || funcName === 'createRecordRequest')
1072
+ ? true
1073
+ : false;
1074
+ this.polling$.next();
1075
+ const polling$ = (isPolling && options.polling) || 0 >= 3
1076
+ ? request$.pipe(requestPolling((options.polling || 0) + 1, this.polling$, this.isPending), tap(() => this.countdown.next(0)), tap(() => {
1077
+ if (!options.polling)
1078
+ return;
1079
+ const count = options.polling ? options.polling : 0;
1080
+ // console.log('COUNT:', count);
1081
+ countdown(count)
1082
+ .pipe(map((x) => {
1083
+ // console.log('XX:', count, x);
1084
+ const pollingInSec = options.polling || 0;
1085
+ const percentageCompleted = ((pollingInSec - x) / pollingInSec) * 100;
1086
+ return Math.round(percentageCompleted);
1087
+ }))
1088
+ .subscribe((countDownValue) => {
1089
+ // console.log(this.countdown.value, countDownValue);
1090
+ this.countdown.next(countDownValue);
1091
+ });
1092
+ }))
1093
+ : request$.pipe(catchError((err) => {
1094
+ if (err instanceof HttpErrorResponse) {
1095
+ this.error.next(true);
1096
+ return this.handleError(err);
1097
+ }
1098
+ return throwError(() => err);
1099
+ }));
1100
+ return polling$.pipe(catchError((err, caught) => {
1101
+ if (err instanceof HttpErrorResponse) {
1102
+ this.error.next(true);
1103
+ if (isPolling)
1104
+ this.stopPolling();
1105
+ return this.handleError(err);
1106
+ }
1107
+ return throwError(() => err);
1108
+ }), (options?.retry && options.retry.times > 0)
1109
+ ? delayedRetry((options.retry.delay || 3) * 1000, (options.retry.times || 0) - 1)
1110
+ : (source) => source);
1111
+ }
1112
+ createRequest(func, options, data) {
1113
+ const dataItem = this.prepareRequestData(options, data, func.name);
1114
+ return func.bind(this)(dataItem.options, dataItem.data);
1115
+ }
1116
+ prepareRequestData(options, data, funcName) {
1117
+ if ((options.mapper && funcName === 'updateRecordRequest') || funcName === 'createRecordRequest') {
1118
+ if (options?.mapper) {
1119
+ data = options.mapper
1120
+ ? Array.isArray(data)
1121
+ ? map((item) => options.mapper(item))
1122
+ : options.mapper(data)
1123
+ : data;
1124
+ }
1125
+ }
1126
+ else {
1127
+ if (options?.adapter) {
1128
+ data = Array.isArray(data)
1129
+ ? map((item) => options.adapter(item))
1130
+ : options.adapter(data);
1131
+ }
1132
+ }
1133
+ return { options: options, data: data };
1134
+ }
1135
+ // MISC
1136
+ handleError(error) {
1137
+ this.error.next(error.message || `${error.status} - ${error.statusText}`);
1138
+ return throwError(() => error);
1139
+ }
1140
+ handleErrorWithSnackBar(error) {
1141
+ const displayError = ToastDisplay.adapt({
1142
+ message: error.message || `${error.status} - ${error.statusText}`,
1143
+ action: 'OK',
1144
+ color: ToastColors.ERROR,
1145
+ icon: 'error',
1146
+ duration: 5 * 1000, //5 seconds
1147
+ });
1148
+ this.toastMessage.toastMessage(displayError);
1149
+ }
1150
+ stopPolling() {
1151
+ this.isPending.next(false);
1152
+ this.polling$.next();
1153
+ }
1154
+ defineReqOptions(options, params) {
1155
+ const req = ApiRequest.adapt(options);
1156
+ if (req?.path)
1157
+ req.path = (params) ? [...req.path, ...params] : req.path;
1158
+ const optionsReq = (req) ? req : ApiRequest.adapt();
1159
+ const updatedOptions = this.objectMergerService.mergeOptions(optionsReq);
1160
+ return updatedOptions;
1161
+ }
1162
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerService, deps: [{ token: CONFIG_SETTINGS_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
1163
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerService, providedIn: 'root' }); }
1164
+ }
1165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerService, decorators: [{
1166
+ type: Injectable,
1167
+ args: [{
1168
+ providedIn: 'root',
1169
+ }]
1170
+ }], ctorParameters: function () { return [{ type: ConfigOptions, decorators: [{
1171
+ type: Optional
1172
+ }, {
1173
+ type: Inject,
1174
+ args: [CONFIG_SETTINGS_TOKEN]
1175
+ }] }]; } });
1176
+
1177
+ class ApiRequest {
1178
+ constructor(server = '', path, headers, adapter, mapper, polling, retry, stream, displayError, saveAs) {
1179
+ this.server = server;
1180
+ this.path = path;
1181
+ this.headers = headers;
1182
+ this.adapter = adapter;
1183
+ this.mapper = mapper;
1184
+ this.polling = polling;
1185
+ this.retry = retry;
1186
+ this.stream = stream;
1187
+ this.displayError = displayError;
1188
+ this.saveAs = saveAs;
1189
+ }
1190
+ static adapt(item) {
1191
+ const server = Array.isArray(item?.server) ? item.server.join('/') : item?.server || '';
1192
+ return new ApiRequest(server, (item?.path) ? item.path : [], (item?.headers) ? item.headers : {}, item?.adapter, item?.mapper, item?.polling ? Math.floor(item.polling) : 0, item?.retry ? RetryOptions.adapt(item.retry) : RetryOptions.adapt(), (item?.stream) ? item.stream : false, (item?.displayError) ? item.displayError : false, item?.saveAs);
1193
+ }
1194
+ }
1195
+
1196
+ class RequestOptions {
1197
+ constructor(path = [], headers = {}) {
1198
+ this.path = path;
1199
+ this.headers = headers;
1200
+ }
1201
+ static adapt(item) {
1202
+ return new RequestOptions(item?.path, item?.headers);
1203
+ }
1204
+ }
1205
+
1206
+ class ObjectMergerService {
1207
+ constructor(configOptions) {
1208
+ this.configOptions = configOptions;
1209
+ if (!this.configOptions)
1210
+ this.configOptions = ConfigOptions.adapt();
1211
+ }
1212
+ mergeOptions(options = ApiRequest.adapt()) {
1213
+ const configForRoot = (this.configOptions?.httpRequestOptions) ? this.configOptions.httpRequestOptions : ConfigHTTPOptions.adapt();
1214
+ const mergedOptions = ApiRequest.adapt(options);
1215
+ mergedOptions.server = (options && options.server === '') ? configForRoot?.server || '' : options.server;
1216
+ mergedOptions.path = [...options.path || [], ...configForRoot?.path || []];
1217
+ mergedOptions.headers = { ...options.headers || {}, ...configForRoot?.headers || {} };
1218
+ mergedOptions.retry = (options && (options?.retry?.times !== 0 || options?.retry?.delay !== 3)) ? options.retry : configForRoot?.retry || { times: 0, delay: 3 };
1219
+ mergedOptions.polling = (options && options?.polling !== 0) ? options.polling : configForRoot?.polling || 0;
1220
+ mergedOptions.displayError = (options && options?.displayError) ? options.displayError : configForRoot?.displayError || false;
1221
+ mergedOptions.stream = (options && options?.stream) ? options.stream : configForRoot?.stream || false;
1222
+ return mergedOptions;
1223
+ }
1224
+ mergeStorageOptions(options = SettingOptions.adapt()) {
1225
+ const configForRoot = (this.configOptions?.LocalStorageOptions) ? this.configOptions.LocalStorageOptions : LocalStorageOptions.adapt();
1226
+ const configForRootOptions = configForRoot.options || LocalStorageOptions.adapt().options;
1227
+ const mergedOptions = SettingOptions.adapt(options);
1228
+ mergedOptions.storage = (options && options.storage === 0) ? configForRootOptions?.storage || 0 : options.storage;
1229
+ mergedOptions.expires = (options && options.expires === 0) ? configForRootOptions?.expires || 0 : options.expires;
1230
+ mergedOptions.expiresIn = (options && options.expiresIn === '') ? configForRootOptions?.expiresIn || '' : options.expiresIn;
1231
+ mergedOptions.encrypted = (options && !options.encrypted) ? configForRootOptions?.encrypted || false : options.encrypted;
1232
+ return mergedOptions;
1233
+ }
1234
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ObjectMergerService, deps: [{ token: CONFIG_SETTINGS_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
1235
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ObjectMergerService, providedIn: 'root' }); }
1236
+ }
1237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ObjectMergerService, decorators: [{
1238
+ type: Injectable,
1239
+ args: [{
1240
+ providedIn: 'root'
1241
+ }]
1242
+ }], ctorParameters: function () { return [{ type: ConfigOptions, decorators: [{
1243
+ type: Inject,
1244
+ args: [CONFIG_SETTINGS_TOKEN]
1245
+ }, {
1246
+ type: Optional
1247
+ }] }]; } });
1248
+
1249
+ const storage = {
1250
+ localStores: [],
1251
+ sessionStores: [],
1252
+ settings: [],
1253
+ };
1254
+ class LocalStorageManagerService extends ComponentStore {
1255
+ startTimer() {
1256
+ const timer$ = interval(1000 * 3).pipe(withLatestFrom(this.data$), map(([_, state]) => state), tap((state) => {
1257
+ const expired = this.expired(state) ? this.expired(state) : [];
1258
+ if (expired.length > 0) {
1259
+ const ids = expired.map((item) => item.id);
1260
+ const updatedState = {
1261
+ ...state,
1262
+ localStores: state.localStores.filter((item) => !ids.includes(item.id)),
1263
+ sessionStores: state.sessionStores.filter((item) => !ids.includes(item.id)),
1264
+ settings: state.settings.filter((item) => !ids.includes(item.id)),
1265
+ };
1266
+ this.persistState(updatedState);
1267
+ this.updateState(updatedState);
1268
+ }
1269
+ }));
1270
+ timer$.subscribe();
1271
+ }
1272
+ constructor(configOptions) {
1273
+ super(storage);
1274
+ this.configOptions = configOptions;
1275
+ this.storageName = 'storage';
1276
+ this.storageSettingsName = 'global-storage';
1277
+ this.defaultOptions = SettingOptions.adapt();
1278
+ this.stateRetrieved = false;
1279
+ this.encrypted = false;
1280
+ this.app = inject(AppService);
1281
+ this.utils = inject(UtilsService);
1282
+ this.objectMergerService = inject(ObjectMergerService);
1283
+ this.encryption = inject(SymmetricalEncryptionService);
1284
+ this.encryptionTest = inject(EncryptionTestService);
1285
+ // SELECTORS
1286
+ this.data$ = this.select((state) => state);
1287
+ this.stores$ = this.select((state) => state.settings);
1288
+ this.storeExists$ = (store) => this.select(this.data$, (data) => data.settings.find(item => item.name === store) ? true : false);
1289
+ this.store$ = (store) => this.select(this.data$, (data) => {
1290
+ const foundStore = data.settings.find(item => item.name === store);
1291
+ if (foundStore) {
1292
+ const options = SettingOptions.adapt(foundStore.options);
1293
+ const found = foundStore.options?.storage === StorageType.GLOBAL
1294
+ ? data.localStores.find(item => item.id === foundStore.id)
1295
+ : data.sessionStores.find(item => item.id === foundStore.id);
1296
+ if (!found) {
1297
+ this.deleteStore({ name: store });
1298
+ return;
1299
+ }
1300
+ if (!this.app?.appID) {
1301
+ console.warn('No App ID found - AppId not Provided');
1302
+ return;
1303
+ }
1304
+ const storageData = (options.encrypted) ? this.encryption.decrypt(found.data, this.app.appID) : found.data;
1305
+ return (this.isString(storageData)) ? JSON.parse(storageData) : storageData;
1306
+ }
1307
+ else {
1308
+ return null;
1309
+ }
1310
+ });
1311
+ this.settings$ = this.select(state => (state) ? state.settings : storage.settings);
1312
+ this.setting$ = (store) => this.select(this.data$, (state) => {
1313
+ const foundSetting = state.settings.find(item => item.name === store);
1314
+ return (foundSetting) ? foundSetting : null;
1315
+ });
1316
+ this.persistence$ = this.data$
1317
+ .subscribe(data => {
1318
+ if (this.stateRetrieved)
1319
+ this.persistState(data);
1320
+ });
1321
+ this.updateState = this.updater((state, updatedState) => ({
1322
+ ...updatedState,
1323
+ }));
1324
+ this.setStore = this.updater((state, store) => {
1325
+ const settings = StorageOption.adapt(store);
1326
+ settings.options = this.objectMergerService.mergeStorageOptions(settings.options);
1327
+ const type = store.options.storage;
1328
+ const hasStore = this.hasGlobalStorage(type, store.id);
1329
+ store.name = this.validStoreName(store.name);
1330
+ if (!hasStore) {
1331
+ console.warn(`No such Store: ${store.name}`);
1332
+ return state;
1333
+ }
1334
+ else {
1335
+ const str = this.encryptionTest.isEncrypted(store.data) ? store.data : JSON.stringify(store.data);
1336
+ const dataStr = (this.isObjectOrArray(str)) ? (store.options.encrypted) ? this.encryption.encrypt(str, this.app.appID) : store.data : store.data;
1337
+ const localData = (dataStr && settings.options?.storage === StorageType.GLOBAL) ? [{ data: dataStr, id: settings.id }] : [];
1338
+ const sessionData = (dataStr && settings.options?.storage === StorageType.SESSION) ? [{ data: dataStr, id: settings.id }] : [];
1339
+ return {
1340
+ ...state,
1341
+ localStores: [...state.localStores, ...localData],
1342
+ sessionStores: [...state.sessionStores, ...sessionData],
1343
+ settings: [...state.settings, ...[settings]],
1344
+ };
1345
+ }
1346
+ });
1347
+ this.createStore = this.updater((state, store) => {
1348
+ const settings = StorageOption.adapt(store);
1349
+ settings.options = this.objectMergerService.mergeStorageOptions(settings.options);
1350
+ const foundStore = state?.settings.some(item => item.name === store.name);
1351
+ const expires = (settings.options?.expiresIn) ? this.utils.expires(settings.options?.expiresIn) : 0;
1352
+ if (settings.options)
1353
+ settings.options.expires = expires;
1354
+ store.name = this.validStoreName(store.name);
1355
+ if (foundStore) {
1356
+ return state;
1357
+ }
1358
+ else {
1359
+ if (!this.isObjectOrArray(store.data)) {
1360
+ console.warn('Data must ba an Object or Array');
1361
+ return;
1362
+ }
1363
+ store.data = (this.isString(store.data)) ? JSON.parse(store.data) : store.data;
1364
+ const dataStr = (store.options.encrypted) ? this.encryption.encrypt(store.data, this.app.appID) : store.data;
1365
+ const localData = (settings.options?.storage === StorageType.GLOBAL) ? [{ data: dataStr, id: settings.id }] : [];
1366
+ const sessionData = (settings.options?.storage === StorageType.SESSION) ? [{ data: dataStr, id: settings.id }] : [];
1367
+ return {
1368
+ ...state,
1369
+ localStores: [...state.localStores, ...localData],
1370
+ sessionStores: [...state.sessionStores, ...sessionData],
1371
+ settings: [...state.settings, ...[settings]],
1372
+ };
1373
+ }
1374
+ });
1375
+ this.updateStore = this.updater((state, store) => {
1376
+ store.name = this.validStoreName(store.name);
1377
+ const settings = state.settings.find(item => item.name === store.name);
1378
+ if (settings) {
1379
+ const type = settings.options?.storage;
1380
+ const hasStore = this.hasGlobalStorage(type, settings.id || '');
1381
+ if (!hasStore) {
1382
+ console.warn(`No such Store: ${store.name}`);
1383
+ }
1384
+ else {
1385
+ const dataStr = (settings.options?.encrypted) ? this.encryption.encrypt(store.data, this.app.appID) : store.data;
1386
+ const localData = (dataStr && settings.options?.storage === StorageType.GLOBAL) ? [{ data: dataStr, id: settings.id }] : [];
1387
+ const sessionData = (dataStr && settings.options?.storage === StorageType.SESSION) ? [{ data: dataStr, id: settings.id }] : [];
1388
+ state.localStores = state.localStores.filter(item => item.id !== settings.id);
1389
+ state.sessionStores = state.sessionStores.filter(item => item.id !== settings.id);
1390
+ return {
1391
+ ...state,
1392
+ localStores: [...state.localStores, ...localData],
1393
+ sessionStores: [...state.sessionStores, ...sessionData],
1394
+ };
1395
+ }
1396
+ }
1397
+ return state;
1398
+ });
1399
+ this.deleteStore = this.updater((state, store) => {
1400
+ store.name = this.validStoreName(store.name);
1401
+ const id = state.settings.find(item => item.name === store.name)?.id;
1402
+ if (id) {
1403
+ const settings = state.settings.filter(item => item.id !== id);
1404
+ const localData = state.localStores.filter(item => item.id !== id);
1405
+ const sessionData = state.sessionStores.filter(item => item.id !== id);
1406
+ return {
1407
+ ...state,
1408
+ localStores: [...localData],
1409
+ sessionStores: [...sessionData],
1410
+ settings: [...settings],
1411
+ };
1412
+ }
1413
+ else {
1414
+ console.warn(`No such Store: ${store.name}`);
1415
+ return state;
1416
+ }
1417
+ });
1418
+ this.isObjectOrArray = (obj) => {
1419
+ let parsed;
1420
+ try {
1421
+ parsed = (typeof obj === 'object') ? obj : JSON.parse(obj);
1422
+ }
1423
+ catch (e) {
1424
+ return false;
1425
+ }
1426
+ if (Array.isArray(parsed)) {
1427
+ const allStringsOrObjectsOrNumbers = parsed.every(item => typeof item === 'string' ||
1428
+ typeof item === 'object' && item !== null ||
1429
+ typeof item === 'number');
1430
+ return allStringsOrObjectsOrNumbers;
1431
+ }
1432
+ return typeof parsed === 'object' && parsed !== null;
1433
+ };
1434
+ this.storageName = configOptions?.LocalStorageOptions?.storageName || this.storageName;
1435
+ this.storageSettingsName = configOptions?.LocalStorageOptions?.storageSettingsName || this.storageSettingsName;
1436
+ this.defaultOptions = configOptions?.LocalStorageOptions?.options || this.defaultOptions;
1437
+ this.retrieveState();
1438
+ this.startTimer();
1439
+ }
1440
+ resetStore() {
1441
+ const newState = {
1442
+ localStores: [],
1443
+ sessionStores: [],
1444
+ settings: [],
1445
+ };
1446
+ this.updateState(newState);
1447
+ this.persistState(newState);
1448
+ }
1449
+ persistState(state) {
1450
+ if (!state)
1451
+ return;
1452
+ const strLocal = JSON.stringify(state.localStores);
1453
+ localStorage.setItem(this.storageName, strLocal);
1454
+ const strSession = JSON.stringify(state.sessionStores);
1455
+ sessionStorage.setItem(this.storageName, strSession);
1456
+ const settingsStr = this.encryption.encrypt(state.settings, this.app.appID);
1457
+ localStorage.setItem(this.storageSettingsName, settingsStr || '');
1458
+ }
1459
+ expired(state) {
1460
+ if (!state)
1461
+ return [];
1462
+ return state.settings?.filter(item => (item.options?.expires || 0) > 0 && this.utils.hasExpired(item.options?.expires || 0));
1463
+ }
1464
+ retrieveState() {
1465
+ const str = localStorage.getItem(this.storageSettingsName);
1466
+ const localStr = localStorage.getItem(this.storageName);
1467
+ const sessionStr = sessionStorage.getItem(this.storageName);
1468
+ const localData = (localStr) ? JSON.parse(localStr) : null;
1469
+ const sessionData = (sessionStr) ? JSON.parse(sessionStr) : null;
1470
+ const decryptedStr = str ? this.encryption.decrypt(str, this.app.appID) : null;
1471
+ const settings = (decryptedStr && decryptedStr !== null) ? JSON.parse(decryptedStr) : [];
1472
+ settings.forEach(store => {
1473
+ const expired = (store.options?.expires || 0) > 0 && this.utils.hasExpired(store.options?.expires || 0);
1474
+ if (!expired) {
1475
+ const hasStorage = this.hasGlobalStorage(store.options?.storage, store.id || '');
1476
+ if (!hasStorage) {
1477
+ this.createStore({ id: store.id, name: store.name, data: [], options: SettingOptions.adapt(store.options) });
1478
+ }
1479
+ else {
1480
+ const storeData = (store.options?.storage === StorageType.GLOBAL) ? localData.find(item => item.id === store.id) : sessionData.find(item => item.id === store.id);
1481
+ this.setStore({ id: store.id || '', name: store.name, data: storeData?.data, options: SettingOptions.adapt(store.options) });
1482
+ }
1483
+ }
1484
+ });
1485
+ this.stateRetrieved = true;
1486
+ }
1487
+ isString(obj) {
1488
+ return (Object.prototype.toString.call(obj) === '[object String]');
1489
+ }
1490
+ fixAndParseJSON(jsonString) {
1491
+ const fixedString = jsonString
1492
+ .replace(/'/g, '"')
1493
+ .replace(/([{,]\s*)(\w+)\s*:/g, '$1"$2":')
1494
+ .replace(/,\s*(\}|\])/g, '$1');
1495
+ try {
1496
+ return JSON.parse(fixedString);
1497
+ }
1498
+ catch (error) {
1499
+ throw new Error('Failed to parse JSON: ' + error.message);
1500
+ }
1501
+ }
1502
+ validStoreName(str) {
1503
+ return str
1504
+ .toLowerCase() // Convert to lowercase
1505
+ .replace(/\s+/g, '_') // Replace spaces with underscores
1506
+ .replace(/[^ -~]/g, ''); // Remove non-ASCII characters
1507
+ }
1508
+ hasGlobalStorage(type = StorageType.GLOBAL, id) {
1509
+ const strData = [];
1510
+ if (type === StorageType.GLOBAL) {
1511
+ const str = localStorage.getItem(this.storageName);
1512
+ strData.push(...(str ? JSON.parse(str) : []));
1513
+ }
1514
+ else {
1515
+ const str = sessionStorage.getItem(this.storageName);
1516
+ strData.push(...(str ? JSON.parse(str) : []));
1517
+ }
1518
+ const found = strData.find(store => store.id === id);
1519
+ return (found) ? true : false;
1520
+ }
1521
+ ngOnDestroy() {
1522
+ this.persistence$.unsubscribe();
1523
+ }
1524
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageManagerService, deps: [{ token: CONFIG_SETTINGS_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
1525
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageManagerService, providedIn: 'root' }); }
1526
+ }
1527
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageManagerService, decorators: [{
1528
+ type: Injectable,
1529
+ args: [{ providedIn: 'root' }]
1530
+ }], ctorParameters: function () { return [{ type: ConfigOptions, decorators: [{
1531
+ type: Optional
1532
+ }, {
1533
+ type: Inject,
1534
+ args: [CONFIG_SETTINGS_TOKEN]
1535
+ }] }]; } });
1536
+
1537
+ const API_OPTS = new InjectionToken('API_OPTS');
1538
+ const defaultState = {
1539
+ data: [],
1540
+ dataObject: null,
1541
+ };
1542
+ class HTTPManagerStateService extends ComponentStore {
1543
+ constructor(apiOptions = ApiRequest.adapt(), dataType, database) {
1544
+ super(defaultState);
1545
+ this.apiOptions = apiOptions;
1546
+ this.dataType = dataType;
1547
+ this.database = database;
1548
+ this.httpManagerService = inject(HTTPManagerService);
1549
+ this.error$ = this.httpManagerService.error$;
1550
+ this.isPending$ = this.httpManagerService.isPending$.pipe(delay(1));
1551
+ // PAGINATION
1552
+ this.page = new BehaviorSubject(0);
1553
+ this.page$ = this.page.asObservable();
1554
+ this.totalPages = new BehaviorSubject(0);
1555
+ this.totalPages$ = this.totalPages.asObservable();
1556
+ this.percentage = new BehaviorSubject(0);
1557
+ this.percentage$ = this.percentage.asObservable();
1558
+ // ----------
1559
+ this.hasDatabase = false;
1560
+ this.streamedResponse = [];
1561
+ // --------------------------------------------------------------------------------------------------
1562
+ // SELECTORS
1563
+ this.data$ = this.select(({ data, dataObject }) => {
1564
+ const isArray = (this.dataType === DataType.ARRAY) ? true : false;
1565
+ return (isArray) ? data : dataObject;
1566
+ });
1567
+ this.selectRecord$ = (id) => this.select(this.data$, (data) => {
1568
+ if (this.dataType === DataType.ARRAY && Array.isArray(data)) {
1569
+ return data.find(item => item.id === id);
1570
+ }
1571
+ else {
1572
+ return data.id === id ? data : null;
1573
+ }
1574
+ });
1575
+ // --------------------------------------------------------------------------------------------------
1576
+ // UPDATERS
1577
+ this.setData$ = this.updater((state, data) => {
1578
+ if (!data)
1579
+ return state;
1580
+ if (this.dataType === DataType.ARRAY) {
1581
+ const dataArray = Array.isArray(data) ? data : [data];
1582
+ const stateDataSample = (state.data.length > 0) ? Object.keys(state.data[0]) : [];
1583
+ const newDataSample = (dataArray.length > 0) ? Object.keys(dataArray[0]) : [];
1584
+ const isSame = (state.data.length === 0) ? false : stateDataSample.every((value, index) => value === newDataSample[index]);
1585
+ const updatedData = (!isSame && dataArray.length !== 0) ? this.updateArrayState([], dataArray) : this.updateArrayState(state.data, dataArray);
1586
+ return { ...state, data: updatedData, dataObject: null };
1587
+ }
1588
+ else {
1589
+ const dataObject = this.isEmpty(data) ? null : data;
1590
+ return { ...state, data: [], dataObject: dataObject };
1591
+ }
1592
+ });
1593
+ this.addData$ = this.updater((state, data) => {
1594
+ if (this.dataType === DataType.ARRAY) {
1595
+ const newState = [...state.data, data];
1596
+ return { ...state, ...{ data: newState } };
1597
+ }
1598
+ else {
1599
+ return { ...state, ...{ dataObject: data } };
1600
+ }
1601
+ });
1602
+ this.deleteData$ = this.updater((state, data) => {
1603
+ if (this.dataType === DataType.ARRAY) {
1604
+ const newState = state.data.filter(item => item.id !== data.id);
1605
+ return { ...state, ...{ data: newState } };
1606
+ }
1607
+ else {
1608
+ return { ...state, ...{ dataObject: null } };
1609
+ }
1610
+ });
1611
+ this.updateData$ = this.updater((state, data) => {
1612
+ if (this.dataType === DataType.ARRAY) {
1613
+ const objIndex = state.data.findIndex(item => item.id === data.id);
1614
+ if (objIndex > -1) {
1615
+ const newState = [...state.data];
1616
+ newState[objIndex] = data;
1617
+ return { ...state, ...{ data: newState } };
1618
+ }
1619
+ return state;
1620
+ }
1621
+ else {
1622
+ return { ...state, ...{ dataObject: data } };
1623
+ }
1624
+ });
1625
+ // --------------------------------------------------------------------------------------------------
1626
+ // EFFECTS
1627
+ this.clearRecords = this.effect(data => data.pipe(tap(() => {
1628
+ if (this.dataType === DataType.ARRAY) {
1629
+ this.setData$([]);
1630
+ }
1631
+ else {
1632
+ this.setData$({});
1633
+ }
1634
+ })));
1635
+ this.refreshData = this.effect(data => data.pipe(tap(() => {
1636
+ // this.apiService.flushDatabase(this.otherOptions.database?.table)
1637
+ this.fetchRecords();
1638
+ })));
1639
+ // --------------------------------------------------------------------------------------------------
1640
+ // CRUD OPERATIONS
1641
+ // FETCH RECORDS
1642
+ this.fetchRecords = (options) => this.effect(() => of(RequestOptions.adapt(options)).pipe(switchMap(() => {
1643
+ this.streamedResponse = [];
1644
+ const requestOptions = this.updateRequestOptions(options?.headers);
1645
+ return this.httpManagerService.getRequest(requestOptions, options?.path)
1646
+ .pipe(tap((data) => {
1647
+ data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
1648
+ this.setData$(data);
1649
+ }));
1650
+ })));
1651
+ // CREATE RECORD
1652
+ this.createRecord = (data, options) => this.effect(() => of(data).pipe(switchMap((data) => {
1653
+ this.streamedResponse = [];
1654
+ const requestOptions = this.updateRequestOptions(options?.headers);
1655
+ return this.httpManagerService.postRequest(data, requestOptions, options?.path)
1656
+ .pipe(tap((data) => {
1657
+ data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
1658
+ this.addData$(data);
1659
+ }));
1660
+ })));
1661
+ // UPDATE RECORD
1662
+ this.updateRecord = (data, options) => this.effect(() => of(data).pipe(concatMap((data) => {
1663
+ this.streamedResponse = [];
1664
+ const requestOptions = this.updateRequestOptions(options?.headers);
1665
+ return this.httpManagerService.putRequest(data, requestOptions, options?.path)
1666
+ .pipe(tap((data) => {
1667
+ data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
1668
+ this.updateData$(data);
1669
+ }));
1670
+ })));
1671
+ // DELETE RECORD
1672
+ this.deleteRecord = (options) => this.effect(() => of(options).pipe(concatMap((data) => {
1673
+ this.streamedResponse = [];
1674
+ const requestOptions = this.updateRequestOptions(options?.headers);
1675
+ return this.httpManagerService.deleteRequest(requestOptions, options?.path)
1676
+ .pipe(tap((data) => {
1677
+ data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
1678
+ this.deleteData$(data);
1679
+ }));
1680
+ })));
1681
+ // --------------------------------------------------------------------------------------------------
1682
+ // FETCH STREAM
1683
+ this.createStream = (data, options) => this.effect(() => of(data).pipe(tap(() => this.httpManagerService.isPending.next(true)), switchMap((data) => {
1684
+ const requestOptions = this.updateRequestOptions(options?.headers);
1685
+ return this.httpManagerService.postRequest(data, requestOptions, options?.path)
1686
+ .pipe(tap((res) => {
1687
+ if (res.length > 0)
1688
+ this.setData$(res);
1689
+ this.streamedResponse = res;
1690
+ }), scan((acc, res) => {
1691
+ const previous = acc.current;
1692
+ const current = res;
1693
+ return { previous, current };
1694
+ }, { previous: null, current: null }), tap(({ previous, current }) => {
1695
+ if (previous && JSON.stringify(previous) === JSON.stringify(current)) {
1696
+ this.httpManagerService.isPending.next(false);
1697
+ this.setData$([]);
1698
+ }
1699
+ else {
1700
+ this.httpManagerService.isPending.next(true);
1701
+ }
1702
+ }));
1703
+ })));
1704
+ this.fetchStream = (options) => this.effect(() => of(options).pipe(tap(() => this.httpManagerService.isPending.next(true)), switchMap((options) => {
1705
+ const requestOptions = this.updateRequestOptions(options?.headers);
1706
+ requestOptions.stream = true;
1707
+ return this.httpManagerService.getRequest(requestOptions, options?.path)
1708
+ .pipe(tap((res) => {
1709
+ if (res.length > 0)
1710
+ this.setData$(res);
1711
+ this.streamedResponse = res;
1712
+ }), scan((acc, res) => {
1713
+ const previous = acc.current;
1714
+ const current = res;
1715
+ return { previous, current };
1716
+ }, { previous: null, current: null }), tap(({ previous, current }) => {
1717
+ if (previous && JSON.stringify(previous) === JSON.stringify(current)) {
1718
+ this.httpManagerService.isPending.next(false);
1719
+ this.setData$([]);
1720
+ }
1721
+ else {
1722
+ this.httpManagerService.isPending.next(true);
1723
+ }
1724
+ }));
1725
+ })));
1726
+ this.setApiRequestOptions(apiOptions, dataType, database);
1727
+ }
1728
+ setApiRequestOptions(apiOptions, dataType, database) {
1729
+ this.apiOptions = ApiRequest.adapt(apiOptions);
1730
+ this.dataType = (dataType) ? dataType : DataType.ARRAY;
1731
+ this.hasDatabase = this.database?.table === "" ? false : true;
1732
+ this.database = (this.hasDatabase) ? DatabaseStorage.adapt(database) : undefined;
1733
+ }
1734
+ get ApiRequestOptions() {
1735
+ return this.apiOptions;
1736
+ }
1737
+ initStorage() {
1738
+ // if(this.otherOptions.database) {
1739
+ // console.log('Has Database Option:', this.otherOptions.database.table)
1740
+ // const schema = (this.otherOptions.adapters?.incoming) ? Object.keys(this.otherOptions.adapters.incoming({})).join() : '++id'
1741
+ // this.apiService.initDB(this.otherOptions.database.expiresIn, this.otherOptions.database.table, schema)
1742
+ // }
1743
+ }
1744
+ initializeState(data) {
1745
+ this.setData$(data);
1746
+ }
1747
+ updateArrayState(currentData, newData) {
1748
+ const filterCurrentData = () => {
1749
+ const ids = this.streamedResponse.map((obj) => obj.id);
1750
+ return currentData.filter(obj => (obj.id) ? ids.includes(obj.id) : obj);
1751
+ };
1752
+ const filteredCurrentData = (this.httpManagerService.isPending.value) ? currentData : filterCurrentData();
1753
+ const updatedData = filteredCurrentData.map(item => {
1754
+ const newItem = newData.find(newItem => {
1755
+ const hasId = (newItem?.id && item?.id) ? true : false;
1756
+ return (hasId) ? newItem.id === item.id : JSON.stringify(newItem) === JSON.stringify(item);
1757
+ });
1758
+ return (newItem) ? { ...item, ...newItem } : item;
1759
+ });
1760
+ const addedData = newData.filter(newItem => {
1761
+ return !filteredCurrentData.some(item => {
1762
+ const hasId = (newItem?.id && item?.id) ? true : false;
1763
+ return (hasId) ? item.id === newItem.id : JSON.stringify(newItem) === JSON.stringify(item);
1764
+ });
1765
+ });
1766
+ return [...updatedData, ...addedData];
1767
+ }
1768
+ // --------------------------------------------------------------------------------------------------
1769
+ // MISC
1770
+ isEmpty(obj) {
1771
+ return Object.keys(obj).length === 0;
1772
+ }
1773
+ updateRequestOptions(headers) {
1774
+ const options = ApiRequest.adapt({ ...this.apiOptions });
1775
+ options.headers = (headers)
1776
+ ? { ...options.headers, ...headers }
1777
+ : { ...options.headers };
1778
+ return options;
1779
+ }
1780
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerStateService, deps: [{ token: API_OPTS }, { token: "dataType" }, { token: "database" }], target: i0.ɵɵFactoryTarget.Injectable }); }
1781
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerStateService }); }
1782
+ }
1783
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HTTPManagerStateService, decorators: [{
1784
+ type: Injectable
1785
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1786
+ type: Inject,
1787
+ args: [API_OPTS]
1788
+ }] }, { type: undefined, decorators: [{
1789
+ type: Inject,
1790
+ args: ["dataType"]
1791
+ }] }, { type: undefined, decorators: [{
1792
+ type: Inject,
1793
+ args: ["database"]
1794
+ }] }]; } });
1795
+
1796
+ // export * from "./database-manager-services/index";
1797
+
1798
+ class ErrorDisplaySettings {
1799
+ constructor(displayTime = 3 * 1000, position = 'top') {
1800
+ this.displayTime = displayTime;
1801
+ this.position = position;
1802
+ }
1803
+ static adapt(item) {
1804
+ return new ErrorDisplaySettings((item?.displayTime) ? item.displayTime * 1000 : 3 * 1000, item?.position);
1805
+ }
1806
+ }
1807
+
1808
+ class WithCredentialsInterceptor {
1809
+ intercept(req, next) {
1810
+ req = req.clone({ withCredentials: true });
1811
+ return next.handle(req);
1812
+ }
1813
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WithCredentialsInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1814
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WithCredentialsInterceptor }); }
1815
+ }
1816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WithCredentialsInterceptor, decorators: [{
1817
+ type: Injectable
1818
+ }] });
1819
+
1820
+ class RequestHeadersInterceptor {
1821
+ get currentDate() {
1822
+ const date = new Date();
1823
+ const year = date.getFullYear();
1824
+ const month = String(date.getMonth() + 1).padStart(2, '0');
1825
+ const day = String(date.getDate()).padStart(2, '0');
1826
+ return `${year}-${month}-${day}`;
1827
+ }
1828
+ constructor(translate) {
1829
+ this.translate = translate;
1830
+ this.subscriptions = new Subscription();
1831
+ this.language = 'en-CA';
1832
+ this.subscriptions.add(this.translate.onLangChange
1833
+ .subscribe((params) => {
1834
+ this.language = `${params.lang}-CA`;
1835
+ }));
1836
+ }
1837
+ intercept(request, next) {
1838
+ request = request.clone({
1839
+ setHeaders: {
1840
+ 'Content-Type': 'application/json',
1841
+ 'Accept-Language': this.language || 'en-CA',
1842
+ 'Current-Date': this.currentDate
1843
+ }
1844
+ });
1845
+ return next.handle(request);
1846
+ }
1847
+ ngOnDestroy() {
1848
+ this.subscriptions.unsubscribe();
1849
+ }
1850
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestHeadersInterceptor, deps: [{ token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1851
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestHeadersInterceptor }); }
1852
+ }
1853
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestHeadersInterceptor, decorators: [{
1854
+ type: Injectable
1855
+ }], ctorParameters: function () { return [{ type: i1.TranslateService }]; } });
1856
+
1857
+ class RequestErrorInterceptor {
1858
+ constructor() {
1859
+ this.toastMessage = inject(ToastMessageDisplayService);
1860
+ }
1861
+ intercept(req, next) {
1862
+ return next.handle(req).pipe(catchError$1((error) => {
1863
+ const displayError = ToastDisplay.adapt({
1864
+ message: 'This is a toast message. This is an Error!!',
1865
+ action: 'OK',
1866
+ color: ToastColors.SUCCESS,
1867
+ icon: 'info',
1868
+ duration: 5 * 1000, //5 seconds
1869
+ });
1870
+ if (error.status >= 400 && error.status < 500) {
1871
+ displayError.color = ToastColors.WARN;
1872
+ displayError.message = error.error || `${error.status}: ${error.statusText}`;
1873
+ console.error('Client Error:', {
1874
+ status: error.status,
1875
+ message: error.message,
1876
+ error: error.error,
1877
+ text: error.statusText,
1878
+ });
1879
+ this.toastMessage.toastMessage(displayError);
1880
+ }
1881
+ else if (error.status >= 500) {
1882
+ displayError.color = ToastColors.ERROR;
1883
+ displayError.message = error.error || `${error.status}: ${error.statusText}`;
1884
+ console.error('Server Error:', {
1885
+ status: error.status,
1886
+ message: error.message,
1887
+ error: error.error,
1888
+ text: error.statusText,
1889
+ });
1890
+ this.toastMessage.toastMessage(displayError);
1891
+ }
1892
+ return throwError(() => error);
1893
+ }));
1894
+ }
1895
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestErrorInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1896
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestErrorInterceptor }); }
1897
+ }
1898
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestErrorInterceptor, decorators: [{
1899
+ type: Injectable
1900
+ }] });
1901
+
1902
+ class ClientInfo {
1903
+ constructor(domain = '', service = '', id = 0, name = '') {
1904
+ this.domain = domain;
1905
+ this.service = service;
1906
+ this.id = id;
1907
+ this.name = name;
1908
+ }
1909
+ static adapt(item) {
1910
+ return new ClientInfo(item?.domain, item?.service, item?.id, (item?.first_name || item?.last_name) ? `${item?.first_name} ${item?.last_name}` : '');
1911
+ }
1912
+ }
1913
+
1914
+ class ClientInfoMapper {
1915
+ constructor(id = 0, first_name = '', last_name = '', email = '') {
1916
+ this.id = id;
1917
+ this.first_name = first_name;
1918
+ this.last_name = last_name;
1919
+ this.email = email;
1920
+ }
1921
+ static adapt(item) {
1922
+ const first_name = (item?.name) ? item.name.split(' ')[0] : '';
1923
+ const last_name = (item?.name) ? item.name.split(' ')[1] : '';
1924
+ return new ClientInfoMapper(item?.id, first_name, last_name, item?.email);
1925
+ }
1926
+ }
1927
+
1928
+ class AIPrompt {
1929
+ constructor(response = '') {
1930
+ this.response = response;
1931
+ }
1932
+ static adapt(item) {
1933
+ return new AIPrompt(item?.response);
1934
+ }
1935
+ }
1936
+
1937
+ class DownloadLabels {
1938
+ constructor(error = '', action = '', icon = 'error') {
1939
+ this.error = error;
1940
+ this.action = action;
1941
+ this.icon = icon;
1942
+ }
1943
+ static adapt(item) {
1944
+ return new DownloadLabels(item?.error, item?.action, item?.icon);
1945
+ }
1946
+ }
1947
+
1948
+ class DownloadFileComponent {
1949
+ constructor() {
1950
+ this.subscriptions = new Subscription();
1951
+ this.displayError = 3; // seconds
1952
+ this.diameter = 32;
1953
+ this.mode = 'determinate';
1954
+ this.isPending = false;
1955
+ this.active = false;
1956
+ this.disabled = false;
1957
+ this.error = new EventEmitter();
1958
+ this._progress = 0;
1959
+ this._hasError = false;
1960
+ this.errorTimerActive = false;
1961
+ }
1962
+ set progress(value) {
1963
+ this._progress = value ?? 0;
1964
+ }
1965
+ get progress() {
1966
+ return this._progress;
1967
+ }
1968
+ set hasError(value) {
1969
+ this._hasError = !!value;
1970
+ if (this._hasError && !this.errorTimerActive) {
1971
+ this.errorTimerActive = true;
1972
+ this.active = false;
1973
+ this.error.emit();
1974
+ this.subscriptions.add(timer(this.displayError * 1000)
1975
+ .subscribe((err) => {
1976
+ this._hasError = false;
1977
+ this.errorTimerActive = false;
1978
+ }));
1979
+ }
1980
+ }
1981
+ get hasError() {
1982
+ return this._hasError;
1983
+ }
1984
+ ngOnInit() { }
1985
+ onAction() {
1986
+ this.isPending = false;
1987
+ if (this.event)
1988
+ this.event();
1989
+ }
1990
+ ngOnDestroy() {
1991
+ this.subscriptions.unsubscribe();
1992
+ }
1993
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DownloadFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1994
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DownloadFileComponent, selector: "app-download-file", inputs: { event: "event", displayError: "displayError", diameter: "diameter", mode: "mode", isPending: "isPending", active: "active", disabled: "disabled", progress: "progress", hasError: "hasError" }, outputs: { error: "error" }, ngImport: i0, template: "<ng-container *ngIf=\"!isPending; else DOWNLOADING\">\n <ng-container *ngIf=\"hasError; else NORMAL\">\n <div class=\"width center-txt\" style=\"margin-bottom: 4px;\">\n <mat-icon color=\"warn\" class=\"warn-icon\">warning</mat-icon>\n </div>\n </ng-container>\n <ng-template #NORMAL>\n <ng-container *ngIf=\"active; else ACTION\">\n\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n\n </ng-container>\n <ng-template #ACTION>\n <button data-tracking=\"export-btn\" mat-icon-button (click)=\"onAction()\" class=\"icon-button\" [disabled]=\"disabled\">\n <mat-icon class=\"custom-icon\">file_download</mat-icon>\n </button>\n </ng-template>\n </ng-template>\n</ng-container>\n\n<ng-template #DOWNLOADING>\n <div\n class=\"spinner-container\"\n *ngIf=\"(progress > 0 && progress < 100); else INDETERMINATE\"\n >\n <div class=\"spinner-background\">\n {{progress}}%\n </div>\n <mat-progress-spinner\n color=\"primary\"\n [mode]=\"mode\"\n [value]=\"progress\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n <ng-template #INDETERMINATE>\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n </ng-template>\n\n</ng-template>\n\n\n\n", styles: [":not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:44px;height:44px;font-size:12px;line-height:32px;text-align:center;overflow:hidden;border-radius:50%;border:solid 5px whitesmoke}.center-txt{align-content:center;text-align:-webkit-center}.width{width:48px;height:48px}.icon-button{display:flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0}.container-obj{display:flex;justify-content:center;align-items:center;width:48px;height:48px}.centered-obj-div{text-align:center}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None }); }
1995
+ }
1996
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DownloadFileComponent, decorators: [{
1997
+ type: Component,
1998
+ args: [{ selector: 'app-download-file', encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"!isPending; else DOWNLOADING\">\n <ng-container *ngIf=\"hasError; else NORMAL\">\n <div class=\"width center-txt\" style=\"margin-bottom: 4px;\">\n <mat-icon color=\"warn\" class=\"warn-icon\">warning</mat-icon>\n </div>\n </ng-container>\n <ng-template #NORMAL>\n <ng-container *ngIf=\"active; else ACTION\">\n\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n\n </ng-container>\n <ng-template #ACTION>\n <button data-tracking=\"export-btn\" mat-icon-button (click)=\"onAction()\" class=\"icon-button\" [disabled]=\"disabled\">\n <mat-icon class=\"custom-icon\">file_download</mat-icon>\n </button>\n </ng-template>\n </ng-template>\n</ng-container>\n\n<ng-template #DOWNLOADING>\n <div\n class=\"spinner-container\"\n *ngIf=\"(progress > 0 && progress < 100); else INDETERMINATE\"\n >\n <div class=\"spinner-background\">\n {{progress}}%\n </div>\n <mat-progress-spinner\n color=\"primary\"\n [mode]=\"mode\"\n [value]=\"progress\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n <ng-template #INDETERMINATE>\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n </ng-template>\n\n</ng-template>\n\n\n\n", styles: [":not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:44px;height:44px;font-size:12px;line-height:32px;text-align:center;overflow:hidden;border-radius:50%;border:solid 5px whitesmoke}.center-txt{align-content:center;text-align:-webkit-center}.width{width:48px;height:48px}.icon-button{display:flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0}.container-obj{display:flex;justify-content:center;align-items:center;width:48px;height:48px}.centered-obj-div{text-align:center}\n"] }]
1999
+ }], propDecorators: { event: [{
2000
+ type: Input
2001
+ }], displayError: [{
2002
+ type: Input
2003
+ }], diameter: [{
2004
+ type: Input
2005
+ }], mode: [{
2006
+ type: Input
2007
+ }], isPending: [{
2008
+ type: Input
2009
+ }], active: [{
2010
+ type: Input
2011
+ }], disabled: [{
2012
+ type: Input
2013
+ }], error: [{
2014
+ type: Output
2015
+ }], progress: [{
2016
+ type: Input
2017
+ }], hasError: [{
2018
+ type: Input
2019
+ }] } });
2020
+
2021
+ class FileDownloaderComponent extends HTTPManagerService {
2022
+ set labels(value) {
2023
+ this._labels = (value) ? DownloadLabels.adapt(value) : DownloadLabels.adapt();
2024
+ }
2025
+ get labels() {
2026
+ return this._labels;
2027
+ }
2028
+ constructor() {
2029
+ super();
2030
+ this.delayError = 3;
2031
+ this.apiRequest = ApiRequest.adapt();
2032
+ this.displayErrorMessage = false;
2033
+ this._labels = DownloadLabels.adapt();
2034
+ this.active = false;
2035
+ this.subscription = new Subscription();
2036
+ this.completed = new EventEmitter();
2037
+ this.failed = new EventEmitter();
2038
+ this.disabled = false;
2039
+ }
2040
+ ngOnInit() {
2041
+ }
2042
+ onDownloadStreaming() {
2043
+ if (this.active)
2044
+ return;
2045
+ this.active = true;
2046
+ return this.downloadRequest(this.apiRequest, [])
2047
+ .pipe(distinctUntilChanged(), catchError((err) => {
2048
+ this.onError(err.message);
2049
+ this.active = false;
2050
+ this.failed.emit(err);
2051
+ return throwError(() => err);
2052
+ }), finalize(() => {
2053
+ if (!this.active)
2054
+ return;
2055
+ this.active = false;
2056
+ this.completed.emit();
2057
+ }))
2058
+ .subscribe();
2059
+ }
2060
+ onError(message) {
2061
+ if (!message || !this.displayErrorMessage)
2062
+ return;
2063
+ const display = ToastDisplay.adapt({
2064
+ message,
2065
+ action: 'Ok',
2066
+ color: ToastColors.ERROR,
2067
+ icon: 'error',
2068
+ });
2069
+ this.active = false;
2070
+ this.toastMessage.toastMessage(display);
2071
+ }
2072
+ OnDestroy() {
2073
+ this.subscription.unsubscribe();
2074
+ }
2075
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2076
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FileDownloaderComponent, selector: "app-file-downloader", inputs: { delayError: "delayError", apiRequest: "apiRequest", displayErrorMessage: "displayErrorMessage", saveFileAs: "saveFileAs", labels: "labels", disabled: "disabled" }, outputs: { completed: "completed", failed: "failed" }, usesInheritance: true, ngImport: i0, template: "<app-download-file\n [disabled]=\"disabled\"\n [displayError]=\"3\"\n [event]=\"onDownloadStreaming.bind(this)\"\n [isPending]=\"(isPending$ | async) || false\"\n [progress]=\"(progress$ | async)\"\n [hasError]=\"(error$ | async)\"\n (error)=\"onError(labels.error)\"\n [active]=\"active\"\n></app-download-file>\n", styles: [".snackBarInfo{background-color:#f44336;color:#fff}.mat-simple-snackbar>span{font-weight:700}.mat-simple-snackbar-action .mat-button .mat-button-wrapper{color:#fff}.cdk-overlay-pane>.mat-snack-bar-container{width:100%}.mat-snack-bar-container{max-width:100%!important;width:100%}\n"], dependencies: [{ kind: "component", type: DownloadFileComponent, selector: "app-download-file", inputs: ["event", "displayError", "diameter", "mode", "isPending", "active", "disabled", "progress", "hasError"], outputs: ["error"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
2077
+ }
2078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderComponent, decorators: [{
2079
+ type: Component,
2080
+ args: [{ selector: 'app-file-downloader', encapsulation: ViewEncapsulation.None, template: "<app-download-file\n [disabled]=\"disabled\"\n [displayError]=\"3\"\n [event]=\"onDownloadStreaming.bind(this)\"\n [isPending]=\"(isPending$ | async) || false\"\n [progress]=\"(progress$ | async)\"\n [hasError]=\"(error$ | async)\"\n (error)=\"onError(labels.error)\"\n [active]=\"active\"\n></app-download-file>\n", styles: [".snackBarInfo{background-color:#f44336;color:#fff}.mat-simple-snackbar>span{font-weight:700}.mat-simple-snackbar-action .mat-button .mat-button-wrapper{color:#fff}.cdk-overlay-pane>.mat-snack-bar-container{width:100%}.mat-snack-bar-container{max-width:100%!important;width:100%}\n"] }]
2081
+ }], ctorParameters: function () { return []; }, propDecorators: { delayError: [{
2082
+ type: Input
2083
+ }], apiRequest: [{
2084
+ type: Input
2085
+ }], displayErrorMessage: [{
2086
+ type: Input
2087
+ }], saveFileAs: [{
2088
+ type: Input
2089
+ }], labels: [{
2090
+ type: Input
2091
+ }], completed: [{
2092
+ type: Output
2093
+ }], failed: [{
2094
+ type: Output
2095
+ }], disabled: [{
2096
+ type: Input
2097
+ }] } });
2098
+
2099
+ class RequestManagerDemoComponent {
2100
+ get retry() {
2101
+ return this.requestForm.get('retry')?.value;
2102
+ }
2103
+ get headers() {
2104
+ return this.requestForm.get('headers');
2105
+ }
2106
+ get isValid() {
2107
+ this.requestForm.markAllAsTouched();
2108
+ return this.requestForm.valid;
2109
+ }
2110
+ constructor() {
2111
+ this.displayedColumns = ['id', 'name', 'lastName', 'age'];
2112
+ this.fb = inject(FormBuilder);
2113
+ this.toastMessage = inject(ToastMessageDisplayService);
2114
+ this.httpManagerService = inject(HTTPManagerService);
2115
+ this.isPending$ = this.httpManagerService.isPending$;
2116
+ this.countdown$ = this.httpManagerService.countdown$;
2117
+ this.GET_error$ = new BehaviorSubject('');
2118
+ this.POST_error$ = new BehaviorSubject('');
2119
+ this.PUT_error$ = new BehaviorSubject('');
2120
+ this.DELETE_error$ = new BehaviorSubject('');
2121
+ this.STREAM_error$ = new BehaviorSubject('');
2122
+ this.STREAM_AI_error$ = new BehaviorSubject('');
2123
+ this.requestParams = {
2124
+ GET: ApiRequest.adapt(),
2125
+ POST: ApiRequest.adapt(),
2126
+ PUT: ApiRequest.adapt(),
2127
+ DELETE: ApiRequest.adapt(),
2128
+ STREAM: ApiRequest.adapt(),
2129
+ };
2130
+ this.questionControl = this.fb.control("", [Validators.required]);
2131
+ this.downloadRequest = ApiRequest.adapt({
2132
+ server: 'assets/images',
2133
+ path: ['me.jpg'],
2134
+ // saveAs: 'john.jpg' // Optional
2135
+ });
2136
+ // downloadRequest = ApiRequest.adapt({
2137
+ // server: 'oidc/ai/file'
2138
+ // })
2139
+ this.sampleClientData = {
2140
+ id: 0,
2141
+ name: "Old School Dates",
2142
+ domain: "osd.com",
2143
+ service: "osd",
2144
+ spiffe: "osd.com/osd",
2145
+ secret: "SMOPECXP-OS4P-USOG-X2II-3XMD1FQDR3IJX",
2146
+ created: 1693003138,
2147
+ modified: 1693003138,
2148
+ icon: "",
2149
+ imageFile: "",
2150
+ email: "wavecoders@gmail.com"
2151
+ };
2152
+ this.requestForm = this.fb.group({
2153
+ path: this.fb.control("ai/"),
2154
+ headers: this.fb.array([]),
2155
+ adapter: [null],
2156
+ mapper: [null],
2157
+ retry: this.fb.group({
2158
+ times: [3],
2159
+ delay: [3],
2160
+ }),
2161
+ polling: [3],
2162
+ });
2163
+ this.AIType = 0;
2164
+ this.sampleAdaptors = [
2165
+ { label: "ClientInfo Basic", value: ClientInfo.adapt },
2166
+ { label: "AI Prompt", value: AIPrompt.adapt },
2167
+ ];
2168
+ this.sampleMappers = [
2169
+ { label: "Mapper Basic", value: ClientInfoMapper.adapt },
2170
+ { label: "AI Prompt", value: AIPrompt.adapt },
2171
+ ];
2172
+ this.hasId = (arr) => {
2173
+ if (arr.length === 0)
2174
+ return false;
2175
+ return !isNaN(arr[arr.length - 1]);
2176
+ };
2177
+ this.props = (adapter) => {
2178
+ return (adapter) ? adapter() : null;
2179
+ };
2180
+ // server = `http://sample-endpoint/as/authorization.oauth2`
2181
+ this.arrayObjectsToObjects = (arr) => {
2182
+ return Array.isArray(arr) ? arr.reduce((obj, item) => Object.assign(obj, { [item.key]: item.value }), {}) : {};
2183
+ };
2184
+ }
2185
+ ngOnInit() {
2186
+ // const reqGet2 = ApiRequest.adapt({
2187
+ // server,
2188
+ // path: ['clients'],
2189
+ // headers: { authentication: "Bearer <KEY>" },
2190
+ // adapter: ClientInfo,
2191
+ // dataType: DataType.OBJECT,
2192
+ // // concurrent: false,
2193
+ // // polling: 3, //seconds
2194
+ // })
2195
+ // const req2 = [1024,1025,1026].map(item => {
2196
+ // return this.httpManagerService.getRequest<ClientInfo[]>(reqGet2, [item])
2197
+ // .pipe(
2198
+ // catchError(error => {
2199
+ // return throwError(() => new Error(error.error.message))
2200
+ // })
2201
+ // )
2202
+ // })
2203
+ // forkJoin(req2)
2204
+ // .subscribe(res => console.log(res))
2205
+ }
2206
+ addHeader() {
2207
+ const header = this.fb.group({
2208
+ key: ['', Validators.required],
2209
+ value: ['']
2210
+ });
2211
+ this.headers.push(header);
2212
+ }
2213
+ removeHeader(index) {
2214
+ this.headers.removeAt(index);
2215
+ }
2216
+ compileRequest() {
2217
+ const requestParams = this.requestForm.value;
2218
+ requestParams.headers = this.arrayObjectsToObjects(requestParams.headers || []);
2219
+ const pathReq = (requestParams.path === "") ? [] : (requestParams.path || "").split("/");
2220
+ if (!this.pollingState.checked)
2221
+ requestParams.polling = 0;
2222
+ if (!this.failedState.checked) {
2223
+ requestParams.retry = { times: 0, delay: 0 };
2224
+ }
2225
+ const apiOptions = ApiRequest.adapt(requestParams);
2226
+ apiOptions.path = [];
2227
+ return { apiOptions: apiOptions, path: pathReq };
2228
+ }
2229
+ onGetRequest() {
2230
+ if (!this.isValid)
2231
+ return;
2232
+ const reqParams = this.compileRequest();
2233
+ this.requestParams.GET = reqParams.apiOptions;
2234
+ this.GET$ = EMPTY; //Cancels Previous
2235
+ this.GET_error$.next('');
2236
+ this.GET$ = this.httpManagerService.getRequest(reqParams.apiOptions, reqParams.path)
2237
+ .pipe(
2238
+ // tap((data) => console.log("API GET response", data)),
2239
+ catchError(error => {
2240
+ return throwError(() => this.errorHandling(error, 'GET'));
2241
+ }));
2242
+ }
2243
+ onCreateRequest() {
2244
+ if (!this.isValid)
2245
+ return;
2246
+ const reqParams = this.compileRequest();
2247
+ this.requestParams.POST = reqParams.apiOptions;
2248
+ this.POST$ = EMPTY; //Cancels Previous
2249
+ this.POST_error$.next('');
2250
+ console.log("POST", this.sampleClientData);
2251
+ console.log("POST", reqParams.apiOptions);
2252
+ console.log("POST", reqParams.path);
2253
+ this.POST$ = this.httpManagerService.postRequest(this.sampleClientData, reqParams.apiOptions, reqParams.path)
2254
+ .pipe(
2255
+ // tap((data) => console.log("API POST response", data)),
2256
+ catchError(error => {
2257
+ return throwError(() => this.errorHandling(error, 'POST'));
2258
+ }));
2259
+ }
2260
+ onUpdateRequest() {
2261
+ if (!this.isValid)
2262
+ return;
2263
+ const reqParams = this.compileRequest();
2264
+ if (!this.hasId(reqParams.path)) {
2265
+ console.log("Missing ID");
2266
+ return;
2267
+ }
2268
+ this.sampleClientData.id = parseInt(reqParams.path[reqParams.path.length - 1]);
2269
+ this.requestParams.PUT = reqParams.apiOptions;
2270
+ this.PUT$ = EMPTY; //Cancels Previous
2271
+ this.PUT_error$.next('');
2272
+ this.PUT$ = this.httpManagerService.putRequest(this.sampleClientData, reqParams.apiOptions, reqParams.path)
2273
+ .pipe(
2274
+ // tap((data) => console.log("API PUT response", data)),
2275
+ catchError(error => {
2276
+ return throwError(() => this.errorHandling(error, 'PUT'));
2277
+ }));
2278
+ }
2279
+ onDeleteRequest() {
2280
+ if (!this.isValid)
2281
+ return;
2282
+ const reqParams = this.compileRequest();
2283
+ this.requestParams.DELETE = reqParams.apiOptions;
2284
+ if (!this.hasId(reqParams.path)) {
2285
+ console.log("Missing ID");
2286
+ return;
2287
+ }
2288
+ this.sampleClientData.id = parseInt(reqParams.path[reqParams.path.length - 1]);
2289
+ this.requestParams.DELETE = reqParams.apiOptions;
2290
+ this.DELETE$ = EMPTY; //Cancels Previous
2291
+ this.DELETE_error$.next('');
2292
+ this.DELETE$ = this.httpManagerService.deleteRequest(reqParams.apiOptions, reqParams.path)
2293
+ .pipe(
2294
+ // tap((data) => console.log("API DELETE response", data)),
2295
+ catchError(error => {
2296
+ return throwError(() => this.errorHandling(error, 'DELETE'));
2297
+ }));
2298
+ }
2299
+ onStreamPostRequest() {
2300
+ if (!this.isValid)
2301
+ return;
2302
+ const reqParams = this.compileRequest();
2303
+ let payload = {};
2304
+ let apiPath = reqParams.path;
2305
+ let apiOptions = reqParams.apiOptions;
2306
+ let responseMapper = (items) => items.response;
2307
+ if (this.AIType === 0) {
2308
+ // API request
2309
+ payload = { prompt: this.questionControl.value };
2310
+ }
2311
+ else {
2312
+ // Local Ollama request
2313
+ apiOptions.server = "api";
2314
+ apiPath = ["generate"];
2315
+ apiOptions.stream = true;
2316
+ payload = {
2317
+ model: "phi3:latest",
2318
+ prompt: this.questionControl.value,
2319
+ stream: true,
2320
+ };
2321
+ responseMapper = (items) => items.map((word) => word.response).flat().join('');
2322
+ }
2323
+ this.requestParams.STREAM = apiOptions;
2324
+ this.STREAM_AI$ = EMPTY;
2325
+ this.STREAM_AI_error$.next('');
2326
+ this.STREAM_AI$ = this.httpManagerService.postRequest(payload, apiOptions, apiPath).pipe(map(responseMapper), tap(() => this.questionControl.reset()), catchError(error => throwError(() => this.errorHandling(error, 'STREAM'))));
2327
+ }
2328
+ onStreamRequest() {
2329
+ if (!this.isValid)
2330
+ return;
2331
+ const reqParams = this.compileRequest();
2332
+ reqParams.apiOptions.stream = true;
2333
+ this.requestParams.GET = reqParams.apiOptions;
2334
+ this.STREAM$ = this.httpManagerService.getRequest(reqParams.apiOptions, reqParams.path)
2335
+ .pipe(
2336
+ // tap((data) => console.log("API STREAM response", data)),
2337
+ catchError(error => {
2338
+ return throwError(() => this.errorHandling(error, 'STREAM'));
2339
+ }));
2340
+ }
2341
+ onDownloadCompleted() {
2342
+ const message = "Download Completed";
2343
+ const display = ToastDisplay.adapt({
2344
+ message,
2345
+ action: 'Ok',
2346
+ color: ToastColors.SUCCESS,
2347
+ icon: 'sentiment_satisfied_alt',
2348
+ });
2349
+ this.toastMessage.toastMessage(display);
2350
+ }
2351
+ onDownloadFailed(err) {
2352
+ const message = "Download Failed";
2353
+ const display = ToastDisplay.adapt({
2354
+ message,
2355
+ action: 'Ok',
2356
+ color: ToastColors.ERROR,
2357
+ icon: 'warning',
2358
+ });
2359
+ this.toastMessage.toastMessage(display);
2360
+ }
2361
+ errorHandling(err, type) {
2362
+ if (type === 'GET')
2363
+ this.GET_error$.next(err.message);
2364
+ if (type === 'POST')
2365
+ this.POST_error$.next(err.message);
2366
+ if (type === 'PUT')
2367
+ this.PUT_error$.next(err.message);
2368
+ if (type === 'DELETE')
2369
+ this.DELETE_error$.next(err.message);
2370
+ if (type === 'STREAM')
2371
+ this.STREAM_error$.next(err.message);
2372
+ }
2373
+ onSelectAIType(type) {
2374
+ this.AIType = type;
2375
+ }
2376
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestManagerDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2377
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RequestManagerDemoComponent, selector: "app-request-manager-demo", viewQueries: [{ propertyName: "failedState", first: true, predicate: ["failedState"], descendants: true, static: true }, { propertyName: "pollingState", first: true, predicate: ["pollingState"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <h2>\n HTTP Request Manager\n </h2>\n\n <div [formGroup]=\"requestForm\" style=\"margin-top: 2rem;\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Adapter (Model)</mat-label>\n <mat-select formControlName=\"adapter\" #adapterSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let adapter of sampleAdaptors\" [value]=\"adapter.value\">\n {{adapter.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mapper (Model)</mat-label>\n <mat-select formControlName=\"mapper\" #mapperSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let mapper of sampleMappers\" [value]=\"mapper.value\">\n {{mapper.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"display: flex; margin-bottom: 2rem;\" *ngIf=\"adapterSelect.value || mapperSelect.value\">\n <div style=\"flex:1\" class=\"box\">\n <h3>Adapter (Incoming)</h3>\n <div *ngIf=\"adapterSelect.value; else NO_ADAPTER\">\n {{ props(adapterSelect.value) | json }}\n </div>\n <ng-template #NO_ADAPTER>No Transformation</ng-template>\n </div>\n <div style=\"flex:1\" class=\"box\">\n <h3>Mapper (Outgoing)</h3>\n <div *ngIf=\"mapperSelect.value; else NO_MAPPER\">\n {{ props(mapperSelect.value) | json }}\n </div>\n <ng-template #NO_MAPPER>No Transformation</ng-template>\n </div>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>RestPath (/ delimited)</mat-label>\n <input matInput placeholder=\"clients/list\" formControlName=\"path\">\n </mat-form-field>\n </div>\n <div>\n <div formArrayName=\"headers\">\n <div *ngFor=\"let task of headers.controls; let i = index\" [formGroupName]=\"i\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Key</mat-label>\n <input matInput placeholder=\"authentication\" formControlName=\"key\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Value</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"value\">\n </mat-form-field>\n <div style=\"margin-top: .5rem;\">\n <button mat-icon-button (click)=\"removeHeader(i)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <button mat-stroked-button (click)=\"addHeader()\" class=\"btn\">Add Header</button>\n </div>\n <div style=\"margin-top: 2rem; display: flex; flex-direction:column; gap: 1rem;\">\n <div>\n <mat-slide-toggle #failedState>Retry on Failed</mat-slide-toggle>\n <div *ngIf=\"failedState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem;\" formGroupName=\"retry\">\n <mat-form-field appearance=\"outline\">\n <mat-label>#of Times</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"times\" value=\"3\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Delay Until Next</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"delay\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #pollingState>Polling</mat-slide-toggle>\n <div *ngIf=\"pollingState.checked\">\n <mat-form-field appearance=\"outline\" style=\"margin-top: 1rem\">\n <mat-label>#of Seconds</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"polling\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n\n <div style=\"margin-bottom: 1rem; margin-top: 2rem;\">\n <mat-progress-bar mode=\"indeterminate\"\n *ngIf=\"(isPending$ | async)\"\n ></mat-progress-bar>\n <mat-progress-bar mode=\"determinate\"\n *ngIf=\"pollingState.checked && !(isPending$ | async)\"\n [value]=\"(this.countdown$ | async)\"\n ></mat-progress-bar>\n </div>\n\n <div style=\"margin-top: 1rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onGetRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(GET_error$ | async) as get_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ get_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(GET$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(GET$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">POST Request</h2>\n <div>\n <button mat-raised-button (click)=\"onCreateRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(POST_error$ | async) as post_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ post_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(POST$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(POST$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">PUT Request</h2>\n <div>\n <button mat-raised-button (click)=\"onUpdateRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(PUT_error$ | async) as put_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ put_error }}</mat-error>\n </div>\n\n <h3>Include Record ID in the RestPath</h3>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(PUT$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(PUT$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">DELETE Request</h2>\n <div>\n <button mat-raised-button (click)=\"onDeleteRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <h3>Include Record ID in the RestPath</h3>\n\n <div *ngIf=\"(DELETE_error$ | async) as delete_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ delete_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(DELETE$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(DELETE$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">Streaming GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onStreamRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <!-- <div *ngIf=\"(STREAM_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div> -->\n\n <div style=\"margin-top: 1rem;\">\n <div *ngIf=\"(STREAM$ | async) as data\" class=\"container\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef> Last Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastName}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef> Age </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.age}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1; padding-top: .5rem;\">AI -<span *ngIf=\"AIType === 1\">STREAMING</span> POST Request</h2>\n <div style=\"display: flex; gap: 1rem;\">\n <button mat-raised-button [matMenuTriggerFor]=\"menu\" style=\"min-width: 120px;\">\n <mat-icon>lan</mat-icon>\n <span *ngIf=\"AIType === 0; else LOCAL\">Server</span>\n <ng-template #LOCAL>\n Local\n </ng-template>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"onSelectAIType(0)\">Server</button>\n <button mat-menu-item (click)=\"onSelectAIType(1)\">Local</button>\n </mat-menu>\n <div>\n <button mat-raised-button (click)=\"onStreamPostRequest()\" class=\"btn\">Ask Me</button>\n </div>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Ask me a Question</mat-label>\n <textarea matInput placeholder=\"Why is the sky blue?\" [formControl]=\"questionControl\"></textarea>\n </mat-form-field>\n </div>\n\n <div *ngIf=\"(STREAM_AI_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div>\n\n <div *ngIf=\"AIType === 1; else ALTERNATIVE\" style=\"color: red;\">\n You must have Ollama active and the 'phi3:latest' model to use this feature.\n </div>\n <ng-template #ALTERNATIVE>\n <span style=\"color: gray;\">\n Define the RestPath to the API endpoint that will handle the AI request.\n Use: 'ai/chat' for server\n </span>\n </ng-template>\n\n <div>\n <div *ngIf=\"(STREAM_AI$ | async) as data\" style=\"margin-top: 1rem; font-size: 1.2rem; border-radius: 1rem; border: black 1px solid; padding: 2rem;\">\n <p style=\"margin-bottom: .5rem; white-space:pre-wrap; line-height: 1.6rem;\">{{data}}</p>\n </div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 1.5rem; margin-bottom: 1rem; line-height: 1.5rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div>\n <div style=\"display: flex;\">\n <h2 style=\"flex:1; margin-bottom: 0; padding-top: .5rem; display: flex;\">\n <div>\n Download File\n </div>\n <div style=\"flex:1; margin-left: 1rem;\">\n <mat-slide-toggle #disable>\n <span *ngIf=\"disable.checked; else DISABLE\">\n Enable\n </span>\n <ng-template #DISABLE>Disable</ng-template>\n </mat-slide-toggle>\n </div>\n </h2>\n <div>\n <app-file-downloader\n [disabled]=\"disable.checked\"\n [delayError]=\"3\"\n [apiRequest]=\"downloadRequest\"\n (completed)=\"onDownloadCompleted()\"\n (failed)=\"onDownloadFailed($event)\"\n ></app-file-downloader>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".btn{min-width:120px}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor;background-color:#f5f5f5}.container{height:400px;overflow:auto}.box{padding:10px;border:1px solid #ccc}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i10.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i11.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: FileDownloaderComponent, selector: "app-file-downloader", inputs: ["delayError", "apiRequest", "displayErrorMessage", "saveFileAs", "labels", "disabled"], outputs: ["completed", "failed"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] }); }
2378
+ }
2379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestManagerDemoComponent, decorators: [{
2380
+ type: Component,
2381
+ args: [{ selector: 'app-request-manager-demo', template: "<div style=\"margin: 2rem;\">\n\n <h2>\n HTTP Request Manager\n </h2>\n\n <div [formGroup]=\"requestForm\" style=\"margin-top: 2rem;\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Adapter (Model)</mat-label>\n <mat-select formControlName=\"adapter\" #adapterSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let adapter of sampleAdaptors\" [value]=\"adapter.value\">\n {{adapter.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mapper (Model)</mat-label>\n <mat-select formControlName=\"mapper\" #mapperSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let mapper of sampleMappers\" [value]=\"mapper.value\">\n {{mapper.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"display: flex; margin-bottom: 2rem;\" *ngIf=\"adapterSelect.value || mapperSelect.value\">\n <div style=\"flex:1\" class=\"box\">\n <h3>Adapter (Incoming)</h3>\n <div *ngIf=\"adapterSelect.value; else NO_ADAPTER\">\n {{ props(adapterSelect.value) | json }}\n </div>\n <ng-template #NO_ADAPTER>No Transformation</ng-template>\n </div>\n <div style=\"flex:1\" class=\"box\">\n <h3>Mapper (Outgoing)</h3>\n <div *ngIf=\"mapperSelect.value; else NO_MAPPER\">\n {{ props(mapperSelect.value) | json }}\n </div>\n <ng-template #NO_MAPPER>No Transformation</ng-template>\n </div>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>RestPath (/ delimited)</mat-label>\n <input matInput placeholder=\"clients/list\" formControlName=\"path\">\n </mat-form-field>\n </div>\n <div>\n <div formArrayName=\"headers\">\n <div *ngFor=\"let task of headers.controls; let i = index\" [formGroupName]=\"i\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Key</mat-label>\n <input matInput placeholder=\"authentication\" formControlName=\"key\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Value</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"value\">\n </mat-form-field>\n <div style=\"margin-top: .5rem;\">\n <button mat-icon-button (click)=\"removeHeader(i)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <button mat-stroked-button (click)=\"addHeader()\" class=\"btn\">Add Header</button>\n </div>\n <div style=\"margin-top: 2rem; display: flex; flex-direction:column; gap: 1rem;\">\n <div>\n <mat-slide-toggle #failedState>Retry on Failed</mat-slide-toggle>\n <div *ngIf=\"failedState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem;\" formGroupName=\"retry\">\n <mat-form-field appearance=\"outline\">\n <mat-label>#of Times</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"times\" value=\"3\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Delay Until Next</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"delay\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #pollingState>Polling</mat-slide-toggle>\n <div *ngIf=\"pollingState.checked\">\n <mat-form-field appearance=\"outline\" style=\"margin-top: 1rem\">\n <mat-label>#of Seconds</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"polling\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n </div>\n </div>\n\n <div style=\"margin-bottom: 1rem; margin-top: 2rem;\">\n <mat-progress-bar mode=\"indeterminate\"\n *ngIf=\"(isPending$ | async)\"\n ></mat-progress-bar>\n <mat-progress-bar mode=\"determinate\"\n *ngIf=\"pollingState.checked && !(isPending$ | async)\"\n [value]=\"(this.countdown$ | async)\"\n ></mat-progress-bar>\n </div>\n\n <div style=\"margin-top: 1rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onGetRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(GET_error$ | async) as get_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ get_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(GET$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(GET$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">POST Request</h2>\n <div>\n <button mat-raised-button (click)=\"onCreateRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(POST_error$ | async) as post_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ post_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(POST$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(POST$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">PUT Request</h2>\n <div>\n <button mat-raised-button (click)=\"onUpdateRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(PUT_error$ | async) as put_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ put_error }}</mat-error>\n </div>\n\n <h3>Include Record ID in the RestPath</h3>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(PUT$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(PUT$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">DELETE Request</h2>\n <div>\n <button mat-raised-button (click)=\"onDeleteRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <h3>Include Record ID in the RestPath</h3>\n\n <div *ngIf=\"(DELETE_error$ | async) as delete_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ delete_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\" *ngIf=\"(DELETE$ | async) as dataRecord\">\n <!-- <div [innerHTML]=\"(DELETE$ | async) | jsonv\"></div> -->\n {{ dataRecord | json }}\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">Streaming GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onStreamRequest()\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <!-- <div *ngIf=\"(STREAM_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div> -->\n\n <div style=\"margin-top: 1rem;\">\n <div *ngIf=\"(STREAM$ | async) as data\" class=\"container\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef> Last Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastName}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef> Age </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.age}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1; padding-top: .5rem;\">AI -<span *ngIf=\"AIType === 1\">STREAMING</span> POST Request</h2>\n <div style=\"display: flex; gap: 1rem;\">\n <button mat-raised-button [matMenuTriggerFor]=\"menu\" style=\"min-width: 120px;\">\n <mat-icon>lan</mat-icon>\n <span *ngIf=\"AIType === 0; else LOCAL\">Server</span>\n <ng-template #LOCAL>\n Local\n </ng-template>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"onSelectAIType(0)\">Server</button>\n <button mat-menu-item (click)=\"onSelectAIType(1)\">Local</button>\n </mat-menu>\n <div>\n <button mat-raised-button (click)=\"onStreamPostRequest()\" class=\"btn\">Ask Me</button>\n </div>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Ask me a Question</mat-label>\n <textarea matInput placeholder=\"Why is the sky blue?\" [formControl]=\"questionControl\"></textarea>\n </mat-form-field>\n </div>\n\n <div *ngIf=\"(STREAM_AI_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div>\n\n <div *ngIf=\"AIType === 1; else ALTERNATIVE\" style=\"color: red;\">\n You must have Ollama active and the 'phi3:latest' model to use this feature.\n </div>\n <ng-template #ALTERNATIVE>\n <span style=\"color: gray;\">\n Define the RestPath to the API endpoint that will handle the AI request.\n Use: 'ai/chat' for server\n </span>\n </ng-template>\n\n <div>\n <div *ngIf=\"(STREAM_AI$ | async) as data\" style=\"margin-top: 1rem; font-size: 1.2rem; border-radius: 1rem; border: black 1px solid; padding: 2rem;\">\n <p style=\"margin-bottom: .5rem; white-space:pre-wrap; line-height: 1.6rem;\">{{data}}</p>\n </div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 1.5rem; margin-bottom: 1rem; line-height: 1.5rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div>\n <div style=\"display: flex;\">\n <h2 style=\"flex:1; margin-bottom: 0; padding-top: .5rem; display: flex;\">\n <div>\n Download File\n </div>\n <div style=\"flex:1; margin-left: 1rem;\">\n <mat-slide-toggle #disable>\n <span *ngIf=\"disable.checked; else DISABLE\">\n Enable\n </span>\n <ng-template #DISABLE>Disable</ng-template>\n </mat-slide-toggle>\n </div>\n </h2>\n <div>\n <app-file-downloader\n [disabled]=\"disable.checked\"\n [delayError]=\"3\"\n [apiRequest]=\"downloadRequest\"\n (completed)=\"onDownloadCompleted()\"\n (failed)=\"onDownloadFailed($event)\"\n ></app-file-downloader>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".btn{min-width:120px}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor;background-color:#f5f5f5}.container{height:400px;overflow:auto}.box{padding:10px;border:1px solid #ccc}\n"] }]
2382
+ }], ctorParameters: function () { return []; }, propDecorators: { failedState: [{
2383
+ type: ViewChild,
2384
+ args: ["failedState", { static: true }]
2385
+ }], pollingState: [{
2386
+ type: ViewChild,
2387
+ args: ["pollingState", { static: true }]
2388
+ }] } });
2389
+
2390
+ class StateManagerDemoService extends HTTPManagerStateService {
2391
+ constructor() {
2392
+ super(ApiRequest.adapt({
2393
+ server: "",
2394
+ path: [],
2395
+ headers: {},
2396
+ adapter: ClientInfo.adapt,
2397
+ mapper: ClientInfoMapper.adapt,
2398
+ stream: false,
2399
+ }), DataType.ARRAY, DatabaseStorage.adapt());
2400
+ }
2401
+ setAPIOptions(apiOptions, dataType, database) {
2402
+ this.setApiRequestOptions(apiOptions, dataType, database);
2403
+ }
2404
+ getClients() {
2405
+ // const headers = {
2406
+ // auth: "sample-auth-token"
2407
+ // }
2408
+ // const sampleOptions = RequestOptions.adapt({ path: ["id", 12], headers, sample: true })
2409
+ this.fetchRecords();
2410
+ }
2411
+ createClient(data) {
2412
+ // const headers = {
2413
+ // auth: "sample-auth-token"
2414
+ // }
2415
+ // const sampleOptions = RequestOptions.adapt({ path: ["id", 12], headers, sample: true })
2416
+ this.createRecord(data);
2417
+ }
2418
+ updateClient(data) {
2419
+ // const headers = {
2420
+ // auth: "sample-auth-token"
2421
+ // }
2422
+ data.id = 1031;
2423
+ const sampleOptions = RequestOptions.adapt({ path: [data.id] });
2424
+ this.updateRecord(data, sampleOptions);
2425
+ }
2426
+ deleteClient(data) {
2427
+ // const headers = {
2428
+ // auth: "sample-auth-token"
2429
+ // }
2430
+ data.id = 1031;
2431
+ const sampleOptions = RequestOptions.adapt({ path: [data.id] });
2432
+ this.deleteRecord(sampleOptions);
2433
+ }
2434
+ streamRequest() {
2435
+ const headers = {
2436
+ auth: "sample-auth-token"
2437
+ };
2438
+ // const sampleOptions = RequestOptions.adapt({ path: [1], headers })
2439
+ this.fetchStream();
2440
+ }
2441
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StateManagerDemoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2442
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StateManagerDemoService, providedIn: 'root' }); }
2443
+ }
2444
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: StateManagerDemoService, decorators: [{
2445
+ type: Injectable,
2446
+ args: [{
2447
+ providedIn: 'root'
2448
+ }]
2449
+ }], ctorParameters: function () { return []; } });
2450
+
2451
+ class RequestManagerStateDemoComponent {
2452
+ get dataObservable$() {
2453
+ switch (this.requestType) {
2454
+ case 'GET':
2455
+ return this.GET$;
2456
+ case 'PUT':
2457
+ return this.PUT$;
2458
+ case 'POST':
2459
+ return this.POST$;
2460
+ case 'DELETE':
2461
+ return this.DELETE$;
2462
+ case 'STREAM':
2463
+ return this.STREAM;
2464
+ case 'STREAM_AI':
2465
+ return this.STREAM_AI;
2466
+ default:
2467
+ return this.GET$;
2468
+ break;
2469
+ }
2470
+ }
2471
+ get hasChanged() {
2472
+ return this.requestForm.dirty || this.requestForm.untouched;
2473
+ }
2474
+ get dataType() {
2475
+ return this.requestForm.get("datatype")?.value;
2476
+ }
2477
+ get database() {
2478
+ return this.requestForm.get("database")?.value;
2479
+ }
2480
+ get retry() {
2481
+ return this.requestForm.get("retry")?.value;
2482
+ }
2483
+ get headers() {
2484
+ return this.requestForm.get('headers');
2485
+ }
2486
+ get isValid() {
2487
+ this.requestForm.markAllAsTouched();
2488
+ return this.requestForm.valid;
2489
+ }
2490
+ constructor() {
2491
+ this.stateManagerDemoService = inject(StateManagerDemoService);
2492
+ this.displayedColumns = ['id', 'name', 'lastName', 'age'];
2493
+ this.fb = inject(FormBuilder);
2494
+ this.httpManagerService = inject(HTTPManagerService);
2495
+ this.isPending$ = this.stateManagerDemoService.isPending$;
2496
+ this.error$ = this.stateManagerDemoService.error$;
2497
+ this.countdown$ = this.httpManagerService.countdown$;
2498
+ this.GET_error$ = new BehaviorSubject('');
2499
+ this.POST_error$ = new BehaviorSubject('');
2500
+ this.PUT_error$ = new BehaviorSubject('');
2501
+ this.DELETE_error$ = new BehaviorSubject('');
2502
+ this.STREAM_error$ = new BehaviorSubject('');
2503
+ this.STREAM_AI_error$ = new BehaviorSubject('');
2504
+ this.GET$ = new BehaviorSubject(null);
2505
+ this.POST$ = new BehaviorSubject(null);
2506
+ this.PUT$ = new BehaviorSubject(null);
2507
+ this.DELETE$ = new BehaviorSubject(null);
2508
+ this.STREAM = new BehaviorSubject(null);
2509
+ this.STREAM$ = this.STREAM.asObservable();
2510
+ this.STREAM_AI = new BehaviorSubject([]);
2511
+ this.STREAM_AI$ = this.STREAM_AI.asObservable()
2512
+ .pipe(map$1((items) => (items) ? items.map((item) => item.response) : []), map$1((items) => items.join('\n').trim()));
2513
+ this.questionControl = this.fb.control("", [Validators.required]);
2514
+ this.requestType = '';
2515
+ this.prompts = [];
2516
+ this.AIType = 0;
2517
+ this.sampleClientData = {
2518
+ id: 0,
2519
+ name: "Old School Dates",
2520
+ domain: "osd.com",
2521
+ service: "osd",
2522
+ spiffe: "osd.com/osd",
2523
+ secret: "SMOPECXP-OS4P-USOG-X2II-3XMD1FQDR3IJX",
2524
+ created: 1693003138,
2525
+ modified: 1693003138,
2526
+ icon: "",
2527
+ imageFile: "",
2528
+ };
2529
+ this.selectedRecord = this.fb.control(null);
2530
+ this.requestForm = this.fb.group({
2531
+ datatype: this.fb.control('ARRAY'),
2532
+ path: this.fb.control("ai/"),
2533
+ headers: this.fb.array([]),
2534
+ adapter: [null],
2535
+ mapper: [null],
2536
+ retry: this.fb.group({
2537
+ times: [3],
2538
+ delay: [3],
2539
+ }),
2540
+ polling: [3],
2541
+ database: this.fb.group({
2542
+ table: [''],
2543
+ expiresIn: ['1m'],
2544
+ })
2545
+ });
2546
+ this.sampleAdaptors = [
2547
+ { label: "ClientInfo Basic", value: ClientInfo.adapt },
2548
+ { label: "AI Prompt", value: AIPrompt.adapt },
2549
+ ];
2550
+ this.sampleMappers = [
2551
+ { label: "Mapper Basic", value: ClientInfoMapper.adapt },
2552
+ { label: "AI Prompt", value: AIPrompt.adapt },
2553
+ ];
2554
+ // server = `http://sample-endpoint/as/authorization.oauth2`
2555
+ this.arrayObjectsToObjects = (arr) => {
2556
+ return Array.isArray(arr) ? arr.reduce((obj, item) => Object.assign(obj, { [item.key]: item.value }), {}) : {};
2557
+ };
2558
+ this.props = (adapter) => {
2559
+ return (adapter) ? adapter() : null;
2560
+ };
2561
+ }
2562
+ ngOnInit() {
2563
+ this.stateManagerDemoService.data$.pipe(tap$1((data) => console.log("API STREAM_AI response", data)));
2564
+ this.error$.pipe(tap$1((data) => {
2565
+ debugger;
2566
+ console.log("API STREAM response", data);
2567
+ }), catchError$1(error => {
2568
+ return throwError(() => this.errorHandling(error, 'STREAM'));
2569
+ }));
2570
+ this.selectedRecord.valueChanges
2571
+ .subscribe((data) => {
2572
+ this.selectedRecord$ = (data) ? this.stateManagerDemoService.selectRecord$(data.id) : EMPTY;
2573
+ });
2574
+ this.stateManagerDemoService.data$
2575
+ .pipe(tap$1((data) => {
2576
+ switch (this.requestType) {
2577
+ case 'GET':
2578
+ this.GET$.next(data);
2579
+ break;
2580
+ case 'PUT':
2581
+ this.PUT$.next(data);
2582
+ break;
2583
+ case 'POST':
2584
+ this.POST$.next(data);
2585
+ break;
2586
+ case 'DELETE':
2587
+ this.DELETE$.next(data);
2588
+ break;
2589
+ case 'STREAM':
2590
+ this.STREAM.next(data);
2591
+ break;
2592
+ case 'STREAM_AI':
2593
+ this.STREAM_AI.next(data);
2594
+ break;
2595
+ default:
2596
+ break;
2597
+ }
2598
+ })).subscribe();
2599
+ }
2600
+ addHeader() {
2601
+ const header = this.fb.group({
2602
+ key: ['', Validators.required],
2603
+ value: ['']
2604
+ });
2605
+ this.headers.push(header);
2606
+ }
2607
+ removeHeader(index) {
2608
+ this.headers.removeAt(index);
2609
+ }
2610
+ compileRequest() {
2611
+ const requestParams = this.requestForm.value;
2612
+ requestParams.headers = this.arrayObjectsToObjects(requestParams.headers || []);
2613
+ const pathReq = (requestParams.path === "") ? [] : (requestParams.path || "").split("/");
2614
+ if (!this.pollingState.checked)
2615
+ requestParams.polling = 0;
2616
+ if (!this.failedState.checked) {
2617
+ requestParams.retry = { times: 0, delay: 0 };
2618
+ }
2619
+ const currentOptions = ApiRequest.adapt(requestParams);
2620
+ currentOptions.path = [];
2621
+ const apiOptions = ApiRequest.adapt({ ...currentOptions, path: pathReq });
2622
+ return { apiOptions: apiOptions, path: pathReq };
2623
+ }
2624
+ onSetStateOptions() {
2625
+ if (!this.isValid)
2626
+ return;
2627
+ const reqParams = this.compileRequest();
2628
+ const db = DatabaseStorage.adapt(this.database);
2629
+ const type = this.dataType === "ARRAY" ? DataType.ARRAY : DataType.OBJECT;
2630
+ this.stateManagerDemoService.setAPIOptions(reqParams.apiOptions, type, db);
2631
+ this.requestForm.markAsPristine();
2632
+ }
2633
+ onClearRecords() {
2634
+ this.stateManagerDemoService.clearRecords();
2635
+ }
2636
+ onRefreshRecords() {
2637
+ this.stateManagerDemoService.refreshData();
2638
+ }
2639
+ onGetRequest() {
2640
+ this.requestType = 'GET';
2641
+ this.stateManagerDemoService.getClients();
2642
+ }
2643
+ onCreateRequest() {
2644
+ this.requestType = 'POST';
2645
+ this.stateManagerDemoService.createClient(this.sampleClientData);
2646
+ }
2647
+ onUpdateRequest() {
2648
+ this.requestType = 'PUT';
2649
+ this.stateManagerDemoService.updateClient(this.sampleClientData);
2650
+ }
2651
+ onDeleteRequest() {
2652
+ this.requestType = 'DELETE';
2653
+ this.stateManagerDemoService.deleteClient(this.sampleClientData);
2654
+ }
2655
+ onStreamRequest() {
2656
+ if (!this.isValid)
2657
+ return;
2658
+ const reqParams = this.compileRequest();
2659
+ reqParams.apiOptions.stream = true;
2660
+ this.requestType = 'STREAM';
2661
+ this.stateManagerDemoService.streamRequest();
2662
+ }
2663
+ errorHandling(err, type) {
2664
+ console.log(err, type);
2665
+ if (type === 'GET')
2666
+ this.GET_error$.next(err.message);
2667
+ if (type === 'POST')
2668
+ this.POST_error$.next(err.message);
2669
+ if (type === 'PUT')
2670
+ this.PUT_error$.next(err.message);
2671
+ if (type === 'DELETE')
2672
+ this.DELETE_error$.next(err.message);
2673
+ if (type === 'STREAM')
2674
+ this.STREAM_error$.next(err.message);
2675
+ if (type === 'STREAM_AI')
2676
+ this.STREAM_AI_error$.next(err.message);
2677
+ }
2678
+ onSelectAIType(type) {
2679
+ this.AIType = type;
2680
+ }
2681
+ onClearHistory() {
2682
+ this.prompts = [];
2683
+ }
2684
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestManagerStateDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2685
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RequestManagerStateDemoComponent, selector: "app-request-manager-state-demo", viewQueries: [{ propertyName: "failedState", first: true, predicate: ["failedState"], descendants: true, static: true }, { propertyName: "pollingState", first: true, predicate: ["pollingState"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <h2>\n HTTP Request State Manager\n </h2>\n\n <div [formGroup]=\"requestForm\" style=\"margin-top: 2rem;\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>State Data Type</mat-label>\n <mat-select formControlName=\"datatype\">\n <mat-option value=\"ARRAY\">Array</mat-option>\n <mat-option value=\"OBJECT\">Object</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Adapter (Model)</mat-label>\n <mat-select formControlName=\"adapter\" #adapterSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let adapter of sampleAdaptors\" [value]=\"adapter.value\">\n {{adapter.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mapper (Model)</mat-label>\n <mat-select formControlName=\"mapper\" #mapperSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let mapper of sampleMappers\" [value]=\"mapper.value\">\n {{mapper.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <div style=\"display: flex; margin-bottom: 2rem;\" *ngIf=\"adapterSelect.value || mapperSelect.value\">\n <div style=\"flex:1\" class=\"box\">\n <h3>Adapter (Incoming)</h3>\n <div *ngIf=\"adapterSelect.value; else NO_ADAPTER\">\n {{ props(adapterSelect.value) | json }}\n </div>\n <ng-template #NO_ADAPTER>No Transformation</ng-template>\n </div>\n <div style=\"flex:1\" class=\"box\">\n <h3>Mapper (Outgoing)</h3>\n <div *ngIf=\"mapperSelect.value; else NO_MAPPER\">\n {{ props(mapperSelect.value) | json }}\n </div>\n <ng-template #NO_MAPPER>No Transformation</ng-template>\n </div>\n </div>\n\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>RestPath (/ delimited)</mat-label>\n <input matInput placeholder=\"clients/list\" formControlName=\"path\">\n </mat-form-field>\n </div>\n <div>\n <div formArrayName=\"headers\">\n <div *ngFor=\"let task of headers.controls; let i = index\" [formGroupName]=\"i\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Key</mat-label>\n <input matInput placeholder=\"authentication\" formControlName=\"key\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Value</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"value\">\n </mat-form-field>\n <div style=\"margin-top: .5rem;\">\n <button mat-icon-button (click)=\"removeHeader(i)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <button mat-stroked-button (click)=\"addHeader()\">Add Header</button>\n </div>\n <div style=\"margin-top: 2rem; display: flex; flex-direction:column; gap: 1rem;\">\n <div>\n <mat-slide-toggle #failedState>Retry on Failed</mat-slide-toggle>\n <div *ngIf=\"failedState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem;\" formGroupName=\"retry\">\n <mat-form-field appearance=\"outline\">\n <mat-label>#of Times</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"times\" value=\"3\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Delay Until Next</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"delay\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #pollingState>Polling</mat-slide-toggle>\n <div *ngIf=\"pollingState.checked\">\n <mat-form-field appearance=\"outline\" style=\"margin-top: 1rem\">\n <mat-label>#of Seconds</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"polling\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #DBState>Database Storage</mat-slide-toggle>\n <div *ngIf=\"DBState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem\" formGroupName=\"database\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Table Name</mat-label>\n <input matInput placeholder=\"table\" formControlName=\"table\" value=\"\">\n </mat-form-field>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"1m\">One Minute</mat-option>\n <mat-option value=\"1h\">One Hour</mat-option>\n <mat-option value=\"1d\">One Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n <div style=\"margin-top: 1rem; display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onSetStateOptions()\" [disabled]=\"!hasChanged\">\n Set API Request Options\n </button>\n </div>\n <div>\n <mat-error *ngIf=\"(error$ | async) as error\">\n {{ error }}\n </mat-error>\n </div>\n </div>\n </div>\n\n <div style=\"margin-bottom: 1rem; margin-top: 2rem;\">\n <mat-progress-bar mode=\"indeterminate\"\n *ngIf=\"(isPending$ | async)\"\n ></mat-progress-bar>\n <div *ngIf=\"pollingState.checked\">\n <mat-progress-bar mode=\"determinate\"\n *ngIf=\"!(isPending$ | async) && (this.countdown$ | async) || -1 > 0\"\n [value]=\"(this.countdown$ | async)\"\n ></mat-progress-bar>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\" *ngIf=\"(GET$ | async) as data\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1;\">CURRENT STATE ({{ dataType }})</h2>\n </div>\n <div *ngIf=\"data.length > 1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Records</mat-label>\n <mat-select [formControl]=\"selectedRecord\" [disabled]=\"data === null && data?.length === 0\">\n <mat-option [value]=\"\">None</mat-option>\n <mat-option *ngFor=\"let item of data\" [value]=\"item\">\n {{item.name || (item.first_name) | titlecase}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div *ngIf=\"(dataObservable$ | async) as dataRecord\">\n <div *ngIf=\"(selectedRecord$ | async) as record; else NO_RECORD\">\n {{ record | json }}\n </div>\n <ng-template #NO_RECORD>No Record Selected from State</ng-template>\n\n </div>\n <div style=\"margin-top: 1rem;\">\n <span *ngIf=\"data !== null && data?.length > 0; else NO_DATA\">\n State contains a Total of {{ data.length }} Records\n </span>\n <ng-template #NO_DATA>No Records</ng-template>\n <div style=\"display: flex; gap: .5rem; text-align: end; justify-content: flex-end;\">\n <button class=\"btn\" mat-stroked-button (click)=\"onClearRecords()\">Clear</button>\n <button class=\"btn\" mat-stroked-button (click)=\"onRefreshRecords()\" [disabled]=\"hasChanged\">Refresh</button>\n </div>\n </div>\n </div>\n\n\n\n\n <div style=\"margin-top: 1rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">GET Request ({{ dataType }})</h2>\n <div>\n <button mat-raised-button (click)=\"onGetRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(GET_error$ | async) as get_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ get_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(GET$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(GET$ | async) as getData\">{{ getData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">POST Request</h2>\n <div>\n <button mat-raised-button (click)=\"onCreateRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(POST_error$ | async) as post_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ post_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(POST$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(POST$ | async) as postData\">{{ postData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">PUT Request</h2>\n <div>\n <button mat-raised-button (click)=\"onUpdateRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(PUT_error$ | async) as put_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ put_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(PUT$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(PUT$ | async) as putData\">{{ putData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">DELETE Request</h2>\n <div>\n <button mat-raised-button (click)=\"onDeleteRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(DELETE_error$ | async) as delete_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ delete_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(DELETE$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(DELETE$ | async) as deleteData\">{{ deleteData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">Streaming GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onStreamRequest()\" class=\"btn\" [disabled]=\"hasChanged\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(STREAM_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <div *ngIf=\"(STREAM$ | async) as data\" class=\"container\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef> Last Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastName}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef> Age </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.age}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </div>\n\n </div>\n\n</div>\n", styles: [".btn{min-width:120px}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor;background-color:#f5f5f5}.container{height:400px;overflow:auto}.box{padding:10px;border:1px solid #ccc}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i10.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i11.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i1$1.TitleCasePipe, name: "titlecase" }] }); }
2686
+ }
2687
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RequestManagerStateDemoComponent, decorators: [{
2688
+ type: Component,
2689
+ args: [{ selector: 'app-request-manager-state-demo', template: "<div style=\"margin: 2rem;\">\n\n <h2>\n HTTP Request State Manager\n </h2>\n\n <div [formGroup]=\"requestForm\" style=\"margin-top: 2rem;\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>State Data Type</mat-label>\n <mat-select formControlName=\"datatype\">\n <mat-option value=\"ARRAY\">Array</mat-option>\n <mat-option value=\"OBJECT\">Object</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Adapter (Model)</mat-label>\n <mat-select formControlName=\"adapter\" #adapterSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let adapter of sampleAdaptors\" [value]=\"adapter.value\">\n {{adapter.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Mapper (Model)</mat-label>\n <mat-select formControlName=\"mapper\" #mapperSelect>\n <mat-option>None</mat-option>\n <mat-option *ngFor=\"let mapper of sampleMappers\" [value]=\"mapper.value\">\n {{mapper.label}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <div style=\"display: flex; margin-bottom: 2rem;\" *ngIf=\"adapterSelect.value || mapperSelect.value\">\n <div style=\"flex:1\" class=\"box\">\n <h3>Adapter (Incoming)</h3>\n <div *ngIf=\"adapterSelect.value; else NO_ADAPTER\">\n {{ props(adapterSelect.value) | json }}\n </div>\n <ng-template #NO_ADAPTER>No Transformation</ng-template>\n </div>\n <div style=\"flex:1\" class=\"box\">\n <h3>Mapper (Outgoing)</h3>\n <div *ngIf=\"mapperSelect.value; else NO_MAPPER\">\n {{ props(mapperSelect.value) | json }}\n </div>\n <ng-template #NO_MAPPER>No Transformation</ng-template>\n </div>\n </div>\n\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>RestPath (/ delimited)</mat-label>\n <input matInput placeholder=\"clients/list\" formControlName=\"path\">\n </mat-form-field>\n </div>\n <div>\n <div formArrayName=\"headers\">\n <div *ngFor=\"let task of headers.controls; let i = index\" [formGroupName]=\"i\">\n <div style=\"display: flex; gap: .5rem\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Key</mat-label>\n <input matInput placeholder=\"authentication\" formControlName=\"key\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"flex:1\">\n <mat-label>Value</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"value\">\n </mat-form-field>\n <div style=\"margin-top: .5rem;\">\n <button mat-icon-button (click)=\"removeHeader(i)\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <button mat-stroked-button (click)=\"addHeader()\">Add Header</button>\n </div>\n <div style=\"margin-top: 2rem; display: flex; flex-direction:column; gap: 1rem;\">\n <div>\n <mat-slide-toggle #failedState>Retry on Failed</mat-slide-toggle>\n <div *ngIf=\"failedState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem;\" formGroupName=\"retry\">\n <mat-form-field appearance=\"outline\">\n <mat-label>#of Times</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"times\" value=\"3\">\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Delay Until Next</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"delay\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #pollingState>Polling</mat-slide-toggle>\n <div *ngIf=\"pollingState.checked\">\n <mat-form-field appearance=\"outline\" style=\"margin-top: 1rem\">\n <mat-label>#of Seconds</mat-label>\n <input matInput placeholder=\"3\" formControlName=\"polling\" value=\"3\">\n </mat-form-field>\n </div>\n </div>\n <div>\n <mat-slide-toggle #DBState>Database Storage</mat-slide-toggle>\n <div *ngIf=\"DBState.checked\" style=\"display: flex; gap: .5rem; margin-top: 1rem\" formGroupName=\"database\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Table Name</mat-label>\n <input matInput placeholder=\"table\" formControlName=\"table\" value=\"\">\n </mat-form-field>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"1m\">One Minute</mat-option>\n <mat-option value=\"1h\">One Hour</mat-option>\n <mat-option value=\"1d\">One Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n <div style=\"margin-top: 1rem; display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onSetStateOptions()\" [disabled]=\"!hasChanged\">\n Set API Request Options\n </button>\n </div>\n <div>\n <mat-error *ngIf=\"(error$ | async) as error\">\n {{ error }}\n </mat-error>\n </div>\n </div>\n </div>\n\n <div style=\"margin-bottom: 1rem; margin-top: 2rem;\">\n <mat-progress-bar mode=\"indeterminate\"\n *ngIf=\"(isPending$ | async)\"\n ></mat-progress-bar>\n <div *ngIf=\"pollingState.checked\">\n <mat-progress-bar mode=\"determinate\"\n *ngIf=\"!(isPending$ | async) && (this.countdown$ | async) || -1 > 0\"\n [value]=\"(this.countdown$ | async)\"\n ></mat-progress-bar>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\" *ngIf=\"(GET$ | async) as data\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1;\">CURRENT STATE ({{ dataType }})</h2>\n </div>\n <div *ngIf=\"data.length > 1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Records</mat-label>\n <mat-select [formControl]=\"selectedRecord\" [disabled]=\"data === null && data?.length === 0\">\n <mat-option [value]=\"\">None</mat-option>\n <mat-option *ngFor=\"let item of data\" [value]=\"item\">\n {{item.name || (item.first_name) | titlecase}}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div *ngIf=\"(dataObservable$ | async) as dataRecord\">\n <div *ngIf=\"(selectedRecord$ | async) as record; else NO_RECORD\">\n {{ record | json }}\n </div>\n <ng-template #NO_RECORD>No Record Selected from State</ng-template>\n\n </div>\n <div style=\"margin-top: 1rem;\">\n <span *ngIf=\"data !== null && data?.length > 0; else NO_DATA\">\n State contains a Total of {{ data.length }} Records\n </span>\n <ng-template #NO_DATA>No Records</ng-template>\n <div style=\"display: flex; gap: .5rem; text-align: end; justify-content: flex-end;\">\n <button class=\"btn\" mat-stroked-button (click)=\"onClearRecords()\">Clear</button>\n <button class=\"btn\" mat-stroked-button (click)=\"onRefreshRecords()\" [disabled]=\"hasChanged\">Refresh</button>\n </div>\n </div>\n </div>\n\n\n\n\n <div style=\"margin-top: 1rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">GET Request ({{ dataType }})</h2>\n <div>\n <button mat-raised-button (click)=\"onGetRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(GET_error$ | async) as get_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ get_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(GET$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(GET$ | async) as getData\">{{ getData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">POST Request</h2>\n <div>\n <button mat-raised-button (click)=\"onCreateRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(POST_error$ | async) as post_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ post_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(POST$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(POST$ | async) as postData\">{{ postData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">PUT Request</h2>\n <div>\n <button mat-raised-button (click)=\"onUpdateRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(PUT_error$ | async) as put_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ put_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(PUT$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(PUT$ | async) as putData\">{{ putData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">DELETE Request</h2>\n <div>\n <button mat-raised-button (click)=\"onDeleteRequest()\" [disabled]=\"hasChanged\" class=\"btn\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(DELETE_error$ | async) as delete_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ delete_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <!-- <div [innerHTML]=\"(DELETE$ | async) | jsonv\"></div> -->\n <div *ngIf=\"(DELETE$ | async) as deleteData\">{{ deleteData | json }}</div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 2rem\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 2rem\">\n <div style=\"display: flex;\">\n <h2 style=\"flex:1\">Streaming GET Request</h2>\n <div>\n <button mat-raised-button (click)=\"onStreamRequest()\" class=\"btn\" [disabled]=\"hasChanged\">Request</button>\n </div>\n </div>\n\n <div *ngIf=\"(STREAM_error$ | async) as stream_error\" style=\"margin-top: .5rem;\">\n <mat-error>{{ stream_error }}</mat-error>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <div *ngIf=\"(STREAM$ | async) as data\" class=\"container\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef> Last Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.lastName}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef> Age </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.age}} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n </div>\n\n </div>\n\n</div>\n", styles: [".btn{min-width:120px}.mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor;background-color:#f5f5f5}.container{height:400px;overflow:auto}.box{padding:10px;border:1px solid #ccc}\n"] }]
2690
+ }], ctorParameters: function () { return []; }, propDecorators: { failedState: [{
2691
+ type: ViewChild,
2692
+ args: ["failedState", { static: true }]
2693
+ }], pollingState: [{
2694
+ type: ViewChild,
2695
+ args: ["pollingState", { static: true }]
2696
+ }] } });
2697
+
2698
+ class LocalStorageDemoComponent {
2699
+ get type() {
2700
+ return (this.typeControl.value) ? +this.typeControl.value : 0;
2701
+ }
2702
+ get isValid() {
2703
+ return this.newStoreForm.valid;
2704
+ }
2705
+ get isValidData() {
2706
+ return this.storageForm.valid;
2707
+ }
2708
+ constructor(configOptions) {
2709
+ this.configOptions = configOptions;
2710
+ this.fb = inject(FormBuilder);
2711
+ this.utils = inject(UtilsService);
2712
+ this.type$ = new BehaviorSubject(StorageType.GLOBAL);
2713
+ this.typeControl = this.fb.control(StorageType.GLOBAL.toString());
2714
+ this.localStorageManagerService = inject(LocalStorageManagerService);
2715
+ this.settings$ = this.localStorageManagerService.settings$;
2716
+ this.setting$ = (store) => this.localStorageManagerService.setting$(store);
2717
+ this.storageForm = this.fb.group({
2718
+ store: this.fb.control(null),
2719
+ type: 'local',
2720
+ settingType: 'local',
2721
+ encrypted: false,
2722
+ data: this.fb.control('', Validators.required),
2723
+ });
2724
+ this.newStoreForm = this.fb.group({
2725
+ name: this.fb.control(null, Validators.required),
2726
+ storage: 'local',
2727
+ encrypted: false,
2728
+ data: this.fb.control('', Validators.required),
2729
+ expiresIn: this.fb.control('0')
2730
+ });
2731
+ this.storeData$ = this.storageForm.get('store')?.valueChanges
2732
+ .pipe(switchMap((data) => {
2733
+ return data
2734
+ ? this.localStorageManagerService.store$(data.name)
2735
+ : of('');
2736
+ }), tap(data => {
2737
+ this.storageForm.get('data')?.patchValue(data, { emitEvent: false });
2738
+ }));
2739
+ this.expiresIn = (epoch) => this.utils.expiresIn(epoch);
2740
+ this.isValidJSON = (str) => {
2741
+ try {
2742
+ JSON.parse(str);
2743
+ return true;
2744
+ }
2745
+ catch (e) {
2746
+ return false;
2747
+ }
2748
+ };
2749
+ this.displayedColumns = ['name', 'id', 'encrypted', 'expires', "option"];
2750
+ this.filterData = (values) => {
2751
+ if (!values)
2752
+ return [];
2753
+ return values.filter((item) => item.options.storage === +this.type);
2754
+ };
2755
+ this.create = false;
2756
+ }
2757
+ ngOnInit() {
2758
+ this.storeProps = this.configOptions?.LocalStorageOptions;
2759
+ this.options = this.storeProps?.options;
2760
+ if (this.options?.storage) {
2761
+ this.typeControl.patchValue(this.options.storage.toString());
2762
+ this.typeControl.disable();
2763
+ }
2764
+ else {
2765
+ this.typeControl.enable();
2766
+ }
2767
+ if (this.options?.expiresIn) {
2768
+ this.newStoreForm.get('expiresIn')?.patchValue(this.options.expiresIn);
2769
+ this.newStoreForm.get('expiresIn')?.disable();
2770
+ }
2771
+ else {
2772
+ this.newStoreForm.get('expiresIn')?.enable();
2773
+ }
2774
+ if (this.options?.encrypted) {
2775
+ this.newStoreForm.get('encrypted')?.patchValue(this.options.encrypted);
2776
+ this.newStoreForm.get('encrypted')?.disable();
2777
+ }
2778
+ else {
2779
+ this.newStoreForm.get('encrypted')?.enable();
2780
+ }
2781
+ }
2782
+ onCreateStore() {
2783
+ if (!this.isValid)
2784
+ return;
2785
+ const store = this.newStoreForm.value;
2786
+ if (!store.name || store.name === '')
2787
+ return;
2788
+ const options = { storage: this.type, encrypted: store.encrypted, expiresIn: store.expiresIn };
2789
+ this.localStorageManagerService.createStore({
2790
+ name: store.name,
2791
+ data: store.data,
2792
+ options: SettingOptions.adapt(options)
2793
+ });
2794
+ this.newStoreForm.reset();
2795
+ this.create = false;
2796
+ }
2797
+ onUpdateStore(store) {
2798
+ if (!this.storageForm.valid)
2799
+ return;
2800
+ const storeData = this.storageForm.value;
2801
+ const data = JSON.parse(storeData.data || '');
2802
+ const type = (storeData.type === 'local') ? StorageType.GLOBAL : StorageType.SESSION;
2803
+ this.localStorageManagerService.updateStore({
2804
+ name: store.name,
2805
+ data
2806
+ });
2807
+ }
2808
+ onSelectedRow(store) {
2809
+ this.store = store;
2810
+ this.data$ = this.localStorageManagerService.store$(store.name).pipe(map(item => JSON.stringify(item)));
2811
+ this.create = false;
2812
+ }
2813
+ onCreate() {
2814
+ this.onCancel();
2815
+ this.create = true;
2816
+ }
2817
+ onDelete(store) {
2818
+ this.localStorageManagerService.deleteStore({
2819
+ name: store.name,
2820
+ });
2821
+ this.onCancel();
2822
+ }
2823
+ onCancel() {
2824
+ this.data$ = EMPTY;
2825
+ this.store = null;
2826
+ this.create = false;
2827
+ }
2828
+ onUpdate(store, data) {
2829
+ this.localStorageManagerService.updateStore({
2830
+ name: store.name,
2831
+ data: JSON.parse(data)
2832
+ });
2833
+ this.onCancel();
2834
+ }
2835
+ onReset() {
2836
+ this.localStorageManagerService.resetStore();
2837
+ }
2838
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageDemoComponent, deps: [{ token: CONFIG_SETTINGS_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
2839
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: LocalStorageDemoComponent, selector: "app-local-storage-demo", ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n <h2 style=\"padding-top: .5rem; display: flex;\">\n <div style=\"padding-top: .5rem;\">Local Storage Manager</div>\n <div>\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>info</mat-icon>\n </button>\n </div>\n </h2>\n <span style=\"flex:1\"></span>\n <div style=\"padding-top: .25rem;\">\n <mat-button-toggle-group name=\"storage\" [formControl]=\"typeControl\" (change)=\"onCancel()\">\n <mat-button-toggle value=\"0\">Local Storage</mat-button-toggle>\n <mat-button-toggle value=\"1\">Session Storage</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"margin-top: .25rem;\">\n <button mat-icon-button (click)=\"onCreate()\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"storeProps?.storageName || storeProps?.storageSettingsName\">\n <div style=\"display: flex; gap: .5rem; flex-direction: column; border: gray solid thin; background-color: whitesmoke; padding: 1rem;\"\n >\n <div style=\"display: flex;\">\n <div *ngIf=\"storeProps?.storageSettingsName\" style=\"flex:1\">\n Database: <b>{{ storeProps?.storageSettingsName }}</b>\n </div>\n <div *ngIf=\"storeProps?.storageName\" style=\"flex:1\">\n Data: <b>{{ storeProps?.storageName }}</b>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div style=\"margin-top: 2rem;\" [formGroup]=\"newStoreForm\" *ngIf=\"create; else LIST\">\n\n <h2>Create Store</h2>\n\n <div style=\"display: flex; gap: 1rem;\">\n <div style=\"flex:1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Store Name</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"name\">\n </mat-form-field>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In...</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"0\">None</mat-option>\n <mat-option value=\"30s\">30 Seconds</mat-option>\n <mat-option value=\"1mn\">1 Minute</mat-option>\n <mat-option value=\"1hr\">1 Hour</mat-option>\n <mat-option value=\"1d\">1 Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"margin-top: 1rem;\">\n <mat-slide-toggle formControlName=\"encrypted\">Encrypted</mat-slide-toggle>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" formControlName=\"data\" #json></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCreateStore()\" [disabled]=\"!(isValid && isValidJSON(json.value))\">\n Save Store\n </button>\n </div>\n\n </div>\n\n <ng-template #LIST>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n{{ settings$ | async | json }}\n <div *ngIf=\"filterData(settings$ | async) as data\">\n <ng-container *ngIf=\"data.length > 0; else NO_DATA\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Store </th>\n <td mat-cell *matCellDef=\"let element\" style=\"font-weight: bold; text-transform: uppercase;\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"encrypted\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Encrypted </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.encrypted; else NO\">YES</ng-container>\n <ng-template #NO><span style=\"color:gray\">NO</span></ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Expires </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.expires !== 0; else NO_DATA\">\n {{expiresIn(element.options.expires)}}\n </ng-container>\n <ng-template #NO_DATA>\n \u221E\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"option\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let element\" style=\"padding-right: 0;\">\n <div style=\"display: flex;justify-content: flex-end;\">\n <button mat-icon-button color=\"warn\" (click)=\"onDelete(element); $event.stopPropagation()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"onSelectedRow(row)\"></tr>\n </table>\n </ng-container>\n\n <ng-template #NO_DATA>\n <h3 style=\"margin-top: 1rem;\">No Data</h3>\n </ng-template>\n\n <div *ngIf=\"(data$ | async) as data\" style=\"margin-top: 2rem;\">\n <div style=\"margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h3>STORE: <span style=\"font-weight: bold;\">{{ store.name | uppercase }}</span></h3>\n <h3>SETTINGS: {{ setting$(store.name) | async | json }}</h3>\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" #json [value]=\"data\"></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex; gap: .5rem;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCancel()\">Cancel</button>\n <button mat-stroked-button (click)=\"onUpdate(store, json.value)\" [disabled]=\"!(isValidJSON(json.value))\">Update</button>\n </div>\n </div>\n </div>\n\n </ng-template>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <button mat-stroked-button (click)=\"onReset()\">Delete All Stores</button>\n </div>\n\n</div>\n\n\n<mat-menu #menu=\"matMenu\">\n <div style=\"padding: 1rem;\">\n <p>Please note that the LocalStorage (encryption) and management of data is dependant on initializing the APP_ID</p>\n <p>Must provide a value for <b>APP_ID</b> in AppModule->Providers</p>\n <mat-divider></mat-divider>\n <div style=\"font-size: smaller; margin-top: .5rem;\">\n <p>Example: UUID (self.crypto.randomUUID() to generate)</p>\n <div style=\"background-color: whitesmoke; padding: 1rem;\">\n &#123;<br>\n provide: APP_ID,<br>\n useValue: \"056991ac-3537-43ab-b5b9-83edf6554eff\",<br>\n &#125;\n </div>\n </div>\n </div>\n</mat-menu>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.demo-row-is-clicked{font-weight:700}.mat-mdc-menu-panel.mat-mdc-menu-panel{max-width:280px!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i10$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i10$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: i11.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }], encapsulation: i0.ViewEncapsulation.None }); }
2840
+ }
2841
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageDemoComponent, decorators: [{
2842
+ type: Component,
2843
+ args: [{ selector: 'app-local-storage-demo', encapsulation: ViewEncapsulation.None, template: "<div style=\"margin: 2rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n <h2 style=\"padding-top: .5rem; display: flex;\">\n <div style=\"padding-top: .5rem;\">Local Storage Manager</div>\n <div>\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>info</mat-icon>\n </button>\n </div>\n </h2>\n <span style=\"flex:1\"></span>\n <div style=\"padding-top: .25rem;\">\n <mat-button-toggle-group name=\"storage\" [formControl]=\"typeControl\" (change)=\"onCancel()\">\n <mat-button-toggle value=\"0\">Local Storage</mat-button-toggle>\n <mat-button-toggle value=\"1\">Session Storage</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"margin-top: .25rem;\">\n <button mat-icon-button (click)=\"onCreate()\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"storeProps?.storageName || storeProps?.storageSettingsName\">\n <div style=\"display: flex; gap: .5rem; flex-direction: column; border: gray solid thin; background-color: whitesmoke; padding: 1rem;\"\n >\n <div style=\"display: flex;\">\n <div *ngIf=\"storeProps?.storageSettingsName\" style=\"flex:1\">\n Database: <b>{{ storeProps?.storageSettingsName }}</b>\n </div>\n <div *ngIf=\"storeProps?.storageName\" style=\"flex:1\">\n Data: <b>{{ storeProps?.storageName }}</b>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div style=\"margin-top: 2rem;\" [formGroup]=\"newStoreForm\" *ngIf=\"create; else LIST\">\n\n <h2>Create Store</h2>\n\n <div style=\"display: flex; gap: 1rem;\">\n <div style=\"flex:1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Store Name</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"name\">\n </mat-form-field>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In...</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"0\">None</mat-option>\n <mat-option value=\"30s\">30 Seconds</mat-option>\n <mat-option value=\"1mn\">1 Minute</mat-option>\n <mat-option value=\"1hr\">1 Hour</mat-option>\n <mat-option value=\"1d\">1 Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"margin-top: 1rem;\">\n <mat-slide-toggle formControlName=\"encrypted\">Encrypted</mat-slide-toggle>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" formControlName=\"data\" #json></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCreateStore()\" [disabled]=\"!(isValid && isValidJSON(json.value))\">\n Save Store\n </button>\n </div>\n\n </div>\n\n <ng-template #LIST>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n{{ settings$ | async | json }}\n <div *ngIf=\"filterData(settings$ | async) as data\">\n <ng-container *ngIf=\"data.length > 0; else NO_DATA\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Store </th>\n <td mat-cell *matCellDef=\"let element\" style=\"font-weight: bold; text-transform: uppercase;\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"encrypted\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Encrypted </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.encrypted; else NO\">YES</ng-container>\n <ng-template #NO><span style=\"color:gray\">NO</span></ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Expires </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.expires !== 0; else NO_DATA\">\n {{expiresIn(element.options.expires)}}\n </ng-container>\n <ng-template #NO_DATA>\n \u221E\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"option\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let element\" style=\"padding-right: 0;\">\n <div style=\"display: flex;justify-content: flex-end;\">\n <button mat-icon-button color=\"warn\" (click)=\"onDelete(element); $event.stopPropagation()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"onSelectedRow(row)\"></tr>\n </table>\n </ng-container>\n\n <ng-template #NO_DATA>\n <h3 style=\"margin-top: 1rem;\">No Data</h3>\n </ng-template>\n\n <div *ngIf=\"(data$ | async) as data\" style=\"margin-top: 2rem;\">\n <div style=\"margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h3>STORE: <span style=\"font-weight: bold;\">{{ store.name | uppercase }}</span></h3>\n <h3>SETTINGS: {{ setting$(store.name) | async | json }}</h3>\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" #json [value]=\"data\"></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex; gap: .5rem;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCancel()\">Cancel</button>\n <button mat-stroked-button (click)=\"onUpdate(store, json.value)\" [disabled]=\"!(isValidJSON(json.value))\">Update</button>\n </div>\n </div>\n </div>\n\n </ng-template>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <button mat-stroked-button (click)=\"onReset()\">Delete All Stores</button>\n </div>\n\n</div>\n\n\n<mat-menu #menu=\"matMenu\">\n <div style=\"padding: 1rem;\">\n <p>Please note that the LocalStorage (encryption) and management of data is dependant on initializing the APP_ID</p>\n <p>Must provide a value for <b>APP_ID</b> in AppModule->Providers</p>\n <mat-divider></mat-divider>\n <div style=\"font-size: smaller; margin-top: .5rem;\">\n <p>Example: UUID (self.crypto.randomUUID() to generate)</p>\n <div style=\"background-color: whitesmoke; padding: 1rem;\">\n &#123;<br>\n provide: APP_ID,<br>\n useValue: \"056991ac-3537-43ab-b5b9-83edf6554eff\",<br>\n &#125;\n </div>\n </div>\n </div>\n</mat-menu>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.demo-row-is-clicked{font-weight:700}.mat-mdc-menu-panel.mat-mdc-menu-panel{max-width:280px!important}\n"] }]
2844
+ }], ctorParameters: function () { return [{ type: ConfigOptions, decorators: [{
2845
+ type: Inject,
2846
+ args: [CONFIG_SETTINGS_TOKEN]
2847
+ }] }]; } });
2848
+
2849
+ const PROXY_CONFIG = new InjectionToken('PROXY_CONFIG');
2850
+ class ProxyDebuggerInterceptor {
2851
+ constructor(proxyConfig) {
2852
+ this.proxyConfig = proxyConfig;
2853
+ }
2854
+ intercept(req, next) {
2855
+ if (!this.proxyConfig) {
2856
+ return next.handle(req);
2857
+ }
2858
+ const headers = req.headers.keys().reduce((acc, key) => {
2859
+ acc[key] = req.headers.get(key) || '';
2860
+ return acc;
2861
+ }, {});
2862
+ for (const proxyPath in this.proxyConfig) {
2863
+ if (this.proxyConfig.hasOwnProperty(proxyPath)) {
2864
+ const proxyDetails = this.proxyConfig[proxyPath];
2865
+ const regex = new RegExp('^' + proxyPath.replace('/', '').replace('*', '(.*)'));
2866
+ if (regex.test(req.url)) {
2867
+ const target = proxyDetails.target;
2868
+ const endpoint = req.url.replace(regex, '$1');
2869
+ const actualPath = target + '/' + endpoint;
2870
+ console.log('Request Proxied:', {
2871
+ requestUrl: req.url,
2872
+ requestPayload: req.body,
2873
+ headers: headers,
2874
+ proxyPath: proxyPath,
2875
+ actualPath: actualPath,
2876
+ });
2877
+ }
2878
+ }
2879
+ }
2880
+ return next.handle(req);
2881
+ }
2882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ProxyDebuggerInterceptor, deps: [{ token: PROXY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
2883
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ProxyDebuggerInterceptor }); }
2884
+ }
2885
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ProxyDebuggerInterceptor, decorators: [{
2886
+ type: Injectable
2887
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
2888
+ type: Optional
2889
+ }, {
2890
+ type: Inject,
2891
+ args: [PROXY_CONFIG]
2892
+ }] }]; } });
2893
+
2894
+ class HttpRequestServicesDemoComponent {
2895
+ constructor(configOptions) {
2896
+ this.configOptions = configOptions;
2897
+ this.requestTypes = [
2898
+ { name: "Http Service", value: 'http_service' },
2899
+ { name: "Http State Service", value: 'http_state_service' },
2900
+ { name: "Database Service", value: 'database_service', divider: true, disabled: true },
2901
+ { name: "Local Storage Service", value: 'local_storage_service' },
2902
+ ];
2903
+ this.selectedService = this.requestTypes[0].value;
2904
+ }
2905
+ ngOnInit() {
2906
+ if (this.configOptions)
2907
+ this.injectionOptions = this.configOptions;
2908
+ }
2909
+ onSelected(type) {
2910
+ this.selectedService = this.requestTypes[type].value;
2911
+ }
2912
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestServicesDemoComponent, deps: [{ token: CONFIG_SETTINGS_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
2913
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HttpRequestServicesDemoComponent, selector: "app-http-request-services-demo", ngImport: i0, template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n <ng-container *ngFor=\"let type of requestTypes; index as i\">\n <div\n *ngIf=\"type?.divider\"\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n </ng-container>\n\n </mat-menu>\n</mat-toolbar>\n\n<span [ngSwitch]=\"selectedService\">\n <p *ngSwitchCase=\"'http_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo></app-request-manager-demo>\n </p>\n <p *ngSwitchCase=\"'http_state_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo></app-request-manager-state-demo>\n </p>\n <p *ngSwitchCase=\"'database_service'\">\n <!-- <app-database-data-demo></app-database-data-demo> -->\n </p>\n <p *ngSwitchCase=\"'local_storage_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n <p *ngSwitchDefault>\n Other\n </p>\n</span>\n\n<ng-template #HTTP_OPTIONS>\n <ng-container *ngIf=\"injectionOptions?.httpRequestOptions\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n <ng-container class=\"box\" *ngIf=\"injectionOptions?.LocalStorageOptions\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i5$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: RequestManagerStateDemoComponent, selector: "app-request-manager-state-demo" }, { kind: "component", type: RequestManagerDemoComponent, selector: "app-request-manager-demo" }, { kind: "component", type: LocalStorageDemoComponent, selector: "app-local-storage-demo" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] }); }
2914
+ }
2915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestServicesDemoComponent, decorators: [{
2916
+ type: Component,
2917
+ args: [{ selector: 'app-http-request-services-demo', template: "<mat-toolbar style=\"display:flex\">\n <div>Http Request Manager Services</div>\n <div style=\"flex:1\"></div>\n <button mat-stroked-button [matMenuTriggerFor]=\"menu\">Services</button>\n <mat-menu #menu=\"matMenu\">\n <ng-container *ngFor=\"let type of requestTypes; index as i\">\n <div\n *ngIf=\"type?.divider\"\n style=\"margin-top: .5rem; margin-bottom: .5rem;\"\n >\n <mat-divider></mat-divider>\n </div>\n <button\n mat-menu-item\n (click)=\"onSelected(i)\"\n [disabled]=\"type.disabled\"\n >\n {{ type.name }}\n </button>\n </ng-container>\n\n </mat-menu>\n</mat-toolbar>\n\n<span [ngSwitch]=\"selectedService\">\n <p *ngSwitchCase=\"'http_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-demo></app-request-manager-demo>\n </p>\n <p *ngSwitchCase=\"'http_state_service'\">\n <ng-container *ngTemplateOutlet=\"HTTP_OPTIONS\"></ng-container>\n <app-request-manager-state-demo></app-request-manager-state-demo>\n </p>\n <p *ngSwitchCase=\"'database_service'\">\n <!-- <app-database-data-demo></app-database-data-demo> -->\n </p>\n <p *ngSwitchCase=\"'local_storage_service'\">\n <ng-container *ngTemplateOutlet=\"LOCAL_OPTIONS\"></ng-container>\n <app-local-storage-demo></app-local-storage-demo>\n </p>\n <p *ngSwitchDefault>\n Other\n </p>\n</span>\n\n<ng-template #HTTP_OPTIONS>\n <ng-container *ngIf=\"injectionOptions?.httpRequestOptions\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - HTTP Options</h3>\n {{ injectionOptions?.httpRequestOptions| json }}\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #LOCAL_OPTIONS>\n <ng-container class=\"box\" *ngIf=\"injectionOptions?.LocalStorageOptions\">\n <div class=\"box\">\n <h3 style=\"font-weight: bold;\">Injection Token Detected - LocalStorage Options</h3>\n {{ injectionOptions?.LocalStorageOptions| json }}\n </div>\n </ng-container>\n</ng-template>\n\n\n", styles: [".box{padding:1rem;background-color:#f5f5f5;border:thin gray solid;margin-top:1rem}\n"] }]
2918
+ }], ctorParameters: function () { return [{ type: ConfigOptions, decorators: [{
2919
+ type: Inject,
2920
+ args: [CONFIG_SETTINGS_TOKEN]
2921
+ }] }]; } });
2922
+
2923
+ class SpinnerComponent {
2924
+ constructor() {
2925
+ this.value = 0;
2926
+ }
2927
+ ngOnInit() {
2928
+ }
2929
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2930
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpinnerComponent, selector: "app-spinner", inputs: { color: "color", diameter: "diameter", display: "display", mode: "mode", strokeWidth: "strokeWidth", value: "value" }, ngImport: i0, template: "<div class=\"spinner-background\">{{display}}</div>\n<mat-progress-spinner\n [color]=\"color\"\n [diameter]=\"diameter\"\n [mode]=\"mode || 'indeterminate'\"\n [strokeWidth]=\"strokeWidth\"\n [value]=\"value\">\n</mat-progress-spinner>\n", styles: [".example-h2{margin:24px 0}:not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:80px;height:80px;line-height:80px;text-align:center;overflow:hidden;border-color:#673ab71f;border-radius:50%;border-style:solid;border-width:10px}\n"], dependencies: [{ kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
2931
+ }
2932
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpinnerComponent, decorators: [{
2933
+ type: Component,
2934
+ args: [{ selector: 'app-spinner', template: "<div class=\"spinner-background\">{{display}}</div>\n<mat-progress-spinner\n [color]=\"color\"\n [diameter]=\"diameter\"\n [mode]=\"mode || 'indeterminate'\"\n [strokeWidth]=\"strokeWidth\"\n [value]=\"value\">\n</mat-progress-spinner>\n", styles: [".example-h2{margin:24px 0}:not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:80px;height:80px;line-height:80px;text-align:center;overflow:hidden;border-color:#673ab71f;border-radius:50%;border-style:solid;border-width:10px}\n"] }]
2935
+ }], ctorParameters: function () { return []; }, propDecorators: { color: [{
2936
+ type: Input
2937
+ }], diameter: [{
2938
+ type: Input
2939
+ }], display: [{
2940
+ type: Input
2941
+ }], mode: [{
2942
+ type: Input
2943
+ }], strokeWidth: [{
2944
+ type: Input
2945
+ }], value: [{
2946
+ type: Input
2947
+ }] } });
2948
+
2949
+ class FileDownloaderModule {
2950
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2951
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, declarations: [SpinnerComponent,
2952
+ DownloadFileComponent,
2953
+ FileDownloaderComponent], imports: [CommonModule,
2954
+ MatIconModule,
2955
+ MatProgressSpinnerModule,
2956
+ MatButtonModule], exports: [FileDownloaderComponent] }); }
2957
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, imports: [CommonModule,
2958
+ MatIconModule,
2959
+ MatProgressSpinnerModule,
2960
+ MatButtonModule] }); }
2961
+ }
2962
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, decorators: [{
2963
+ type: NgModule,
2964
+ args: [{
2965
+ imports: [
2966
+ CommonModule,
2967
+ MatIconModule,
2968
+ MatProgressSpinnerModule,
2969
+ MatButtonModule,
2970
+ ],
2971
+ declarations: [
2972
+ SpinnerComponent,
2973
+ DownloadFileComponent,
2974
+ FileDownloaderComponent,
2975
+ ],
2976
+ exports: [
2977
+ FileDownloaderComponent
2978
+ ]
2979
+ }]
2980
+ }] });
2981
+
2982
+ class HttpRequestManagerModule {
2983
+ static forRoot(config = ConfigOptions.adapt()) {
2984
+ return {
2985
+ ngModule: HttpRequestManagerModule,
2986
+ providers: [
2987
+ { provide: CONFIG_SETTINGS_TOKEN, useValue: ConfigOptions.adapt(config) },
2988
+ HTTPManagerService, LocalStorageManagerService //all services that need access to config
2989
+ ],
2990
+ };
2991
+ }
2992
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestManagerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2993
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestManagerModule, declarations: [HttpRequestServicesDemoComponent,
2994
+ RequestManagerStateDemoComponent,
2995
+ RequestManagerDemoComponent,
2996
+ LocalStorageDemoComponent
2997
+ // DatabaseDataDemoComponent,
2998
+ ], imports: [CommonModule,
2999
+ ToastMessageDisplayModule,
3000
+ FormsModule,
3001
+ ReactiveFormsModule,
3002
+ MatButtonModule,
3003
+ MatSelectModule,
3004
+ MatChipsModule,
3005
+ MatMenuModule,
3006
+ MatIconModule,
3007
+ MatTableModule,
3008
+ MatButtonToggleModule,
3009
+ MatAutocompleteModule,
3010
+ MatProgressBarModule,
3011
+ MatSlideToggleModule,
3012
+ MatDividerModule,
3013
+ MatFormFieldModule,
3014
+ MatInputModule,
3015
+ MatToolbarModule,
3016
+ MatSlideToggleModule, i1.TranslateModule, MatSidenavModule,
3017
+ FileDownloaderModule], exports: [HttpRequestServicesDemoComponent] }); }
3018
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestManagerModule, providers: [
3019
+ { provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
3020
+ { provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
3021
+ { provide: HTTP_INTERCEPTORS, useClass: ProxyDebuggerInterceptor, multi: true },
3022
+ { provide: CONFIG_SETTINGS_TOKEN, useValue: ConfigOptions.adapt() },
3023
+ HTTPManagerService, LocalStorageManagerService
3024
+ ], imports: [CommonModule,
3025
+ ToastMessageDisplayModule,
3026
+ FormsModule,
3027
+ ReactiveFormsModule,
3028
+ MatButtonModule,
3029
+ MatSelectModule,
3030
+ MatChipsModule,
3031
+ MatMenuModule,
3032
+ MatIconModule,
3033
+ MatTableModule,
3034
+ MatButtonToggleModule,
3035
+ MatAutocompleteModule,
3036
+ MatProgressBarModule,
3037
+ MatSlideToggleModule,
3038
+ MatDividerModule,
3039
+ MatFormFieldModule,
3040
+ MatInputModule,
3041
+ MatToolbarModule,
3042
+ MatSlideToggleModule,
3043
+ TranslateModule.forRoot(),
3044
+ MatSidenavModule,
3045
+ FileDownloaderModule] }); }
3046
+ }
3047
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HttpRequestManagerModule, decorators: [{
3048
+ type: NgModule,
3049
+ args: [{
3050
+ imports: [
3051
+ CommonModule,
3052
+ ToastMessageDisplayModule,
3053
+ FormsModule,
3054
+ ReactiveFormsModule,
3055
+ MatButtonModule,
3056
+ MatSelectModule,
3057
+ MatChipsModule,
3058
+ MatMenuModule,
3059
+ MatIconModule,
3060
+ MatTableModule,
3061
+ MatButtonToggleModule,
3062
+ MatAutocompleteModule,
3063
+ MatProgressBarModule,
3064
+ MatSlideToggleModule,
3065
+ MatDividerModule,
3066
+ MatFormFieldModule,
3067
+ MatInputModule,
3068
+ MatToolbarModule,
3069
+ MatSlideToggleModule,
3070
+ TranslateModule.forRoot(),
3071
+ MatSidenavModule,
3072
+ FileDownloaderModule,
3073
+ ],
3074
+ declarations: [
3075
+ HttpRequestServicesDemoComponent,
3076
+ RequestManagerStateDemoComponent,
3077
+ RequestManagerDemoComponent,
3078
+ LocalStorageDemoComponent
3079
+ // DatabaseDataDemoComponent,
3080
+ ],
3081
+ exports: [
3082
+ HttpRequestServicesDemoComponent,
3083
+ ],
3084
+ providers: [
3085
+ { provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
3086
+ { provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
3087
+ { provide: HTTP_INTERCEPTORS, useClass: ProxyDebuggerInterceptor, multi: true },
3088
+ { provide: CONFIG_SETTINGS_TOKEN, useValue: ConfigOptions.adapt() },
3089
+ HTTPManagerService, LocalStorageManagerService
3090
+ ],
3091
+ }]
3092
+ }] });
3093
+
3094
+ class TableSchemaDef {
3095
+ constructor(table = 'unknown', schema = '') {
3096
+ this.table = table;
3097
+ this.schema = schema;
3098
+ }
3099
+ static adapt(item) {
3100
+ const schemaArray = (item?.schema && Array.isArray(item.schema)) ? item.schema : item.schema.split(',');
3101
+ const schema = schemaArray.map((item) => this.cleanString(item)).join();
3102
+ return new TableSchemaDef((item?.table) ? this.cleanString(item.table) : 'unknown', schema);
3103
+ }
3104
+ static cleanString(str) {
3105
+ const camelCaseSplit = str.replace(/([a-z])([A-Z])/g, '$1 $2');
3106
+ const cleanStr = camelCaseSplit
3107
+ .replace(/[^a-zA-Z0-9\s]/g, '') // Remove non-alphanumeric characters except spaces
3108
+ .toLowerCase() // Convert to lowercase
3109
+ .trim(); // Trim any leading or trailing spaces
3110
+ return cleanStr;
3111
+ }
3112
+ }
3113
+
3114
+ class DbService extends Dexie {
3115
+ get vr() {
3116
+ return (this.db.verno === 0) ? 1 : this.db.verno + 1;
3117
+ }
3118
+ get nextVr() {
3119
+ return this.vr + 1;
3120
+ }
3121
+ get getTables() {
3122
+ return this.db.tables.map(item => item.name);
3123
+ }
3124
+ async hasDatabase() {
3125
+ return await Dexie.exists(this.storageDB).then((res) => {
3126
+ this.createNewDatabase();
3127
+ return res;
3128
+ });
3129
+ }
3130
+ constructor() {
3131
+ super("global_storage_db");
3132
+ this.storageDB = "global_storage_db";
3133
+ this.db = new Dexie(this.storageDB);
3134
+ this.getTable = (table) => {
3135
+ return this.db.tables.find(item => item.name === table);
3136
+ };
3137
+ this.tableExists = (table) => {
3138
+ return (this.getTables.find(item => item === table)) ? true : false;
3139
+ };
3140
+ this.db = this;
3141
+ this.open().then(data => {
3142
+ }).catch(err => {
3143
+ this.createNewDatabase();
3144
+ });
3145
+ }
3146
+ async updateTable(table, find, data) {
3147
+ const tableSource = this.getTable(table);
3148
+ if (!tableSource || !find || !(find.key || find.value))
3149
+ return false;
3150
+ await tableSource?.where(find.key).equals(find.value).first()
3151
+ .then(async (rec) => {
3152
+ const newRec = this.updateObjectKeys(rec, data);
3153
+ await tableSource?.update(rec.id, newRec);
3154
+ });
3155
+ return true;
3156
+ }
3157
+ async createNewDatabase() {
3158
+ const db = new Dexie('global_storage_db');
3159
+ if (!await Dexie.exists(db.name)) {
3160
+ db.version(1).stores({});
3161
+ }
3162
+ await db.open();
3163
+ }
3164
+ // async createTable(table: string, schema: string) {
3165
+ async createTable(table, schema) {
3166
+ // console.log('createTable:', table, schema)
3167
+ this.hasDatabase().then(async (res) => {
3168
+ const tableDef = this.normalizeString(table);
3169
+ const schemaDef = this.normalizeString(schema);
3170
+ table = tableDef || '';
3171
+ schema = schemaDef || '';
3172
+ if (table === '' || schema === '')
3173
+ return;
3174
+ if (!this.db.isOpen()) {
3175
+ await this.db.open()
3176
+ .then(async () => {
3177
+ this.create(table, schema);
3178
+ // console.log('OPENED', table)
3179
+ })
3180
+ .catch(() => {
3181
+ // console.log('FAILED', table)
3182
+ });
3183
+ }
3184
+ else {
3185
+ this.create(table, schema);
3186
+ }
3187
+ const hasTable = this.getTable(table);
3188
+ if (!hasTable) {
3189
+ setTimeout(() => {
3190
+ this.createTable.bind(this, table, schema);
3191
+ this.create(table, schema);
3192
+ }, 300);
3193
+ }
3194
+ // console.log('DB HAS', table, hasTable)
3195
+ });
3196
+ }
3197
+ async create(table, schema) {
3198
+ // console.log('OPEN', this.db.name, this.vr, this.db.verno, 'OPEN',this.db.isOpen())
3199
+ if (!this.tableExists(table)) {
3200
+ if (this.db.isOpen())
3201
+ await this.db.close();
3202
+ const newSchema = { [table]: schema };
3203
+ await this.db.version(this.nextVr).stores(newSchema);
3204
+ // console.log('Created New Table: ', table, schema)
3205
+ if (!this.db.isOpen())
3206
+ await this.db.open();
3207
+ }
3208
+ }
3209
+ updateObjectKeys(obj1, obj2) {
3210
+ return Object.keys(obj1).reduce((updatedObj, key) => {
3211
+ updatedObj[key] = obj2.hasOwnProperty(key) ? obj2[key] : obj1[key];
3212
+ return updatedObj;
3213
+ }, {});
3214
+ }
3215
+ async DBOpened() {
3216
+ if (!this.db.isOpen()) {
3217
+ await this.db.open()
3218
+ .then(async () => {
3219
+ // console.log('OPENED')
3220
+ })
3221
+ .catch(async (err) => {
3222
+ // console.log('OPENED ERR')
3223
+ return false;
3224
+ });
3225
+ }
3226
+ else {
3227
+ // console.log('OPENED')
3228
+ }
3229
+ return true;
3230
+ }
3231
+ normalizeString(item) {
3232
+ if (!item)
3233
+ return;
3234
+ return Array.isArray(item) ?
3235
+ item.map((item) => this.cleanString(item)).join()
3236
+ : item.split(',').map((item) => this.cleanString(item)).join();
3237
+ }
3238
+ cleanString(str) {
3239
+ const cleanStr = str
3240
+ .replace(/[^a-zA-Z0-9\s]/g, '')
3241
+ .replace(/\s+/g, '_');
3242
+ return cleanStr.trim().toLowerCase();
3243
+ }
3244
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3245
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, providedIn: 'root' }); }
3246
+ }
3247
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, decorators: [{
3248
+ type: Injectable,
3249
+ args: [{
3250
+ providedIn: 'root',
3251
+ }]
3252
+ }], ctorParameters: function () { return []; } });
3253
+
3254
+ class DatabaseManagerService extends DbService {
3255
+ constructor() {
3256
+ super();
3257
+ this.createNewDatabase();
3258
+ }
3259
+ getDatabaseTables() {
3260
+ return from(this.DBOpened()).pipe(map(() => this.db.tables.map(item => item.name)));
3261
+ }
3262
+ hasDatabaseTable(table) {
3263
+ return from(this.DBOpened()).pipe(map(() => {
3264
+ return this.tableExists(this.clean(table));
3265
+ }));
3266
+ }
3267
+ getDatabaseTable(table) {
3268
+ return from(this.DBOpened()).pipe(map((res) => {
3269
+ this.hasDatabase().then((res) => {
3270
+ const tables = this.db.tables;
3271
+ const found = tables.find(item => item.name === this.clean(table)) || null;
3272
+ if (!found) {
3273
+ console.warn('No Such Table:', this.clean(table));
3274
+ return;
3275
+ }
3276
+ else {
3277
+ return found;
3278
+ }
3279
+ });
3280
+ }));
3281
+ }
3282
+ getDatabaseTableSchema(table) {
3283
+ return from(this.DBOpened()).pipe(mergeMap((res) => this.getDatabaseTable(table)), map((dbTable) => {
3284
+ if (!dbTable)
3285
+ return [];
3286
+ const cols = dbTable.schema.indexes.map((col) => col.name);
3287
+ const pri = dbTable.schema.primKey.name;
3288
+ return [pri, ...cols];
3289
+ }));
3290
+ }
3291
+ createDatabaseTable(tableDef) {
3292
+ this.createTable(tableDef.table, tableDef.schema);
3293
+ return from(this.DBOpened());
3294
+ }
3295
+ updateDatabaseTableSchema(tableDef) {
3296
+ }
3297
+ // CRUD
3298
+ findTableRecords(table, column, value) {
3299
+ }
3300
+ findTableRecord(table, column, value) {
3301
+ }
3302
+ getTableRecords(table) {
3303
+ }
3304
+ getTableRecord(table, id) {
3305
+ }
3306
+ createTableRecord(table, record) {
3307
+ return this.createTableRecords(table, [record])
3308
+ .pipe(map((item) => item ? item[0] : null));
3309
+ }
3310
+ createTableRecords(table, records) {
3311
+ return this.getDatabaseTable(table).pipe(switchMap((tableData) => {
3312
+ if (!tableData)
3313
+ return EMPTY;
3314
+ return this.getDatabaseTableSchema(table).pipe(map((schema) => {
3315
+ const insertRecords = records.map((record) => {
3316
+ const objectFromSchema = {};
3317
+ schema.forEach((field) => {
3318
+ const data = record[field] ?? null;
3319
+ objectFromSchema[field] = data;
3320
+ });
3321
+ return objectFromSchema;
3322
+ });
3323
+ tableData.bulkPut(insertRecords);
3324
+ return insertRecords;
3325
+ }));
3326
+ }));
3327
+ }
3328
+ updateTableRecord(table, record) {
3329
+ return this.updateTableRecords(table, [record])
3330
+ .pipe(map(item => item.length > 0 ? item[0] : null));
3331
+ }
3332
+ updateTableRecords(table, records) {
3333
+ return this.getDatabaseTable(table).pipe(switchMap((tableData) => {
3334
+ return this.getDatabaseTableSchema(table).pipe(map((schema) => {
3335
+ const insertRecords = records.map((record) => {
3336
+ const objectFromSchema = {};
3337
+ schema.forEach((field) => {
3338
+ const data = record[field] ?? null;
3339
+ objectFromSchema[field] = data;
3340
+ });
3341
+ return objectFromSchema;
3342
+ });
3343
+ tableData.bulkPut(insertRecords).then(() => console.log('Updated DB'));
3344
+ return insertRecords;
3345
+ }));
3346
+ }));
3347
+ }
3348
+ deleteTableRecord(table, id) {
3349
+ }
3350
+ clean(str) {
3351
+ const cleanStr = str
3352
+ .replace(/[^a-zA-Z0-9\s]/g, '_') // Replace non-alphanumeric characters except spaces with underscores
3353
+ .replace(/\s+/g, '_') // Replace spaces with underscores
3354
+ .toLowerCase() // Convert to lowercase
3355
+ .trim(); // Trim leading or trailing spaces
3356
+ return cleanStr;
3357
+ }
3358
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatabaseManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3359
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatabaseManagerService, providedIn: 'root' }); }
3360
+ }
3361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatabaseManagerService, decorators: [{
3362
+ type: Injectable,
3363
+ args: [{
3364
+ providedIn: 'root'
3365
+ }]
3366
+ }], ctorParameters: function () { return []; } });
3367
+
3368
+ class DatabaseDataDemoComponent {
3369
+ constructor() {
3370
+ this.db = inject(DatabaseManagerService);
3371
+ }
3372
+ ngOnInit() {
3373
+ const tableDef = TableSchemaDef.adapt({ table: 'Sample Table', schema: ['id', 'lastName', 'age'] });
3374
+ console.log(tableDef);
3375
+ this.createTable(tableDef).subscribe(() => {
3376
+ // hasTable
3377
+ this.db.hasDatabaseTable('Sample Table').subscribe(data => console.log(data));
3378
+ // Tables
3379
+ this.db.getDatabaseTables().subscribe(data => console.log(data));
3380
+ // getTable
3381
+ this.db.getDatabaseTable('Sample Table').subscribe(data => console.log(data));
3382
+ // Table Schema
3383
+ this.db.getDatabaseTableSchema('Sample Table').subscribe(data => console.log(data));
3384
+ // Update Table Schema
3385
+ // const newTableDef = TableSchemaDef.adapt({table: 'sample', schema: ['id', 'name', 'age', 'amount']})
3386
+ // this.db.updateDatabaseTableSchema(newTableDef)
3387
+ // Insert Table Record
3388
+ const record = { id: 12, age: 45, last_name: 'Bonifacio', amount: 1200 };
3389
+ this.db.createTableRecord('Sample Table', record).subscribe(data => console.log(data));
3390
+ // Insert Table Records
3391
+ const records = [
3392
+ { id: 12, age: 12, last_name: 'Bonifacio', amount: 80 },
3393
+ { id: 10, age: 15, last_name: 'Johns', amount: 700 },
3394
+ { id: 1, age: 22, last_name: 'Kims', amount: 234 },
3395
+ { id: 2, age: 45, last_name: 'Harrys', amount: 1200 },
3396
+ ];
3397
+ this.db.createTableRecords('Sample Table', records).subscribe(data => console.log(data));
3398
+ // Update Table Record
3399
+ const recordUpdate = { id: 12, age: 45, last_name: 'Bonifacio', amount: 5000 };
3400
+ this.db.createTableRecord('Sample Table', record).subscribe(data => console.log(data));
3401
+ // Update Table Records
3402
+ // const recordsUpdate = [
3403
+ // { id: 12, age: 12, last_name: 'Bonifacio', amount: 5000 },
3404
+ // { id: 10, age: 15, last_name: 'Johns', amount: 5000 },
3405
+ // ]
3406
+ // this.db.updateTableRecords('sample_table', records).subscribe(data => console.log(data))
3407
+ });
3408
+ }
3409
+ createTable(tableDef) {
3410
+ return this.db.createDatabaseTable(tableDef);
3411
+ }
3412
+ // CRUD
3413
+ findTableRecords(table, column, value) {
3414
+ }
3415
+ findTableRecord(table, column, value) {
3416
+ }
3417
+ getTableRecords(table) {
3418
+ }
3419
+ getTableRecord(table, id) {
3420
+ }
3421
+ createTableRecord(table, record) {
3422
+ }
3423
+ updateTableRecord(table, record) {
3424
+ }
3425
+ deleteTableRecord(table, id) {
3426
+ }
3427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatabaseDataDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DatabaseDataDemoComponent, selector: "app-database-data-demo", ngImport: i0, template: "<p>\n database-data-demo works!\n</p>\n", styles: [""] }); }
3429
+ }
3430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatabaseDataDemoComponent, decorators: [{
3431
+ type: Component,
3432
+ args: [{ selector: 'app-database-data-demo', template: "<p>\n database-data-demo works!\n</p>\n" }]
3433
+ }], ctorParameters: function () { return []; } });
3434
+
3435
+ /*
3436
+ * Public API Surface of http-request-manager
3437
+ */
3438
+
3439
+ /**
3440
+ * Generated bundle index. Do not edit.
3441
+ */
3442
+
3443
+ export { ApiRequest, AppService, AsymmetricalEncryptionService, ConfigHTTPOptions, ConfigOptions, DataType, DatabaseDataDemoComponent, DatabaseStorage, ErrorDisplaySettings, GlobalStoreOptions, HTTPManagerService, HTTPManagerStateService, HeadersService, HttpRequestManagerModule, HttpRequestServicesDemoComponent, LocalStorageDemoComponent, LocalStorageManagerService, LocalStorageOptions, PathQueryService, Random, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomSignature, RandomStr, RequestErrorInterceptor, RequestHeadersInterceptor, RequestManagerDemoComponent, RequestManagerStateDemoComponent, RequestOptions, RetryOptions, SettingOptions, StorageData, StorageOption, StorageType, SymmetricalEncryptionService, UUID, UtilsService, WithCredentialsInterceptor, countdown, delayedRetry, requestPolling, requestStreaming };
3444
+ //# sourceMappingURL=http-request-manager.mjs.map