angular-toolbox 0.0.8 → 0.9.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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +14 -10
  3. package/{esm2020 → esm2022}/angular-toolbox.mjs +4 -4
  4. package/esm2022/lib/angular-toolbox.module.mjs +21 -0
  5. package/esm2022/lib/core/bridge/app-bridge.mjs +76 -0
  6. package/esm2022/lib/core/error/app-bridge-error.mjs +24 -0
  7. package/esm2022/lib/core/error/http-mock-service-error.mjs +26 -0
  8. package/esm2022/lib/core/error/index.mjs +5 -0
  9. package/esm2022/lib/core/error/integrity-error.mjs +26 -0
  10. package/esm2022/lib/core/error/subscription-error.mjs +26 -0
  11. package/esm2022/lib/core/impl/index.mjs +2 -0
  12. package/esm2022/lib/core/impl/lang/identifiable-component.mjs +31 -0
  13. package/esm2022/lib/core/impl/lang/index.mjs +2 -0
  14. package/esm2022/lib/core/impl/version/version.impl.mjs +34 -0
  15. package/esm2022/lib/core/index.mjs +3 -0
  16. package/esm2022/lib/directive/anchor-link.directive.mjs +62 -0
  17. package/esm2022/lib/directive/button-role.directive.mjs +102 -0
  18. package/esm2022/lib/directive/content-renderer.directive.mjs +61 -0
  19. package/esm2022/lib/directive/index.mjs +5 -0
  20. package/esm2022/lib/directive/navigate-to-url.directive.mjs +51 -0
  21. package/esm2022/lib/directive/navigation-directive-base.mjs +23 -0
  22. package/esm2022/lib/framework/index.mjs +2 -0
  23. package/esm2022/lib/framework/mock/http/config/http-mock-parameters.mjs +9 -0
  24. package/esm2022/lib/framework/mock/http/config/http-mock.decorator.mjs +48 -0
  25. package/esm2022/lib/framework/mock/http/config/index.mjs +3 -0
  26. package/esm2022/lib/framework/mock/http/config/route-mock-config.mjs +9 -0
  27. package/esm2022/lib/framework/mock/http/core/data-storage.mjs +9 -0
  28. package/esm2022/lib/framework/mock/http/event/event-target.impl.mjs +122 -0
  29. package/esm2022/lib/framework/mock/http/event/progress-event-mock.mjs +48 -0
  30. package/esm2022/lib/framework/mock/http/index.mjs +4 -0
  31. package/esm2022/lib/framework/mock/http/path-to-regexp/constants.mjs +111 -0
  32. package/esm2022/lib/framework/mock/http/path-to-regexp/escape-to-regexp-string.mjs +34 -0
  33. package/esm2022/lib/framework/mock/http/path-to-regexp/get-flags.mjs +28 -0
  34. package/esm2022/lib/framework/mock/http/path-to-regexp/iter.mjs +76 -0
  35. package/esm2022/lib/framework/mock/http/path-to-regexp/lexer.mjs +96 -0
  36. package/esm2022/lib/framework/mock/http/path-to-regexp/loose-replacer.mjs +28 -0
  37. package/esm2022/lib/framework/mock/http/path-to-regexp/model/decode-key-to-string.mjs +17 -0
  38. package/esm2022/lib/framework/mock/http/path-to-regexp/model/encode.mjs +17 -0
  39. package/esm2022/lib/framework/mock/http/path-to-regexp/model/key.mjs +17 -0
  40. package/esm2022/lib/framework/mock/http/path-to-regexp/model/lex-token.mjs +17 -0
  41. package/esm2022/lib/framework/mock/http/path-to-regexp/model/lexer-type.mjs +17 -0
  42. package/esm2022/lib/framework/mock/http/path-to-regexp/model/loose-replacer-provider.mjs +17 -0
  43. package/esm2022/lib/framework/mock/http/path-to-regexp/model/non-delimiter-encoder-provider.mjs +17 -0
  44. package/esm2022/lib/framework/mock/http/path-to-regexp/model/parse-options.mjs +17 -0
  45. package/esm2022/lib/framework/mock/http/path-to-regexp/model/path-to-regexp-options.mjs +17 -0
  46. package/esm2022/lib/framework/mock/http/path-to-regexp/model/route-string-tokenizer.mjs +17 -0
  47. package/esm2022/lib/framework/mock/http/path-to-regexp/model/simple-tokens.mjs +30 -0
  48. package/esm2022/lib/framework/mock/http/path-to-regexp/model/token-data-regexp-factory.mjs +17 -0
  49. package/esm2022/lib/framework/mock/http/path-to-regexp/model/token-type.mjs +17 -0
  50. package/esm2022/lib/framework/mock/http/path-to-regexp/model/token.mjs +17 -0
  51. package/esm2022/lib/framework/mock/http/path-to-regexp/string-to-token-data.mjs +87 -0
  52. package/esm2022/lib/framework/mock/http/path-to-regexp/to-key-regexp.mjs +41 -0
  53. package/esm2022/lib/framework/mock/http/path-to-regexp/to-stringify.mjs +29 -0
  54. package/esm2022/lib/framework/mock/http/path-to-regexp/token-data-to-regexp.mjs +49 -0
  55. package/esm2022/lib/framework/mock/http/path-to-regexp/token-data.mjs +33 -0
  56. package/esm2022/lib/framework/mock/http/util/data-storage.builder.mjs +35 -0
  57. package/esm2022/lib/framework/mock/http/util/http-headers-mock.builder.mjs +138 -0
  58. package/esm2022/lib/framework/mock/http/util/http-headers.util.mjs +56 -0
  59. package/esm2022/lib/framework/mock/http/util/http-method-ref.enum.mjs +60 -0
  60. package/esm2022/lib/framework/mock/http/util/http-mock-response.builder.mjs +117 -0
  61. package/esm2022/lib/framework/mock/http/util/index.mjs +3 -0
  62. package/esm2022/lib/framework/mock/http/xhr/delegate-xhr.mjs +316 -0
  63. package/esm2022/lib/framework/mock/http/xhr/http-mock-factory.impl.mjs +29 -0
  64. package/esm2022/lib/framework/mock/http/xhr/http-mock-factory.mjs +19 -0
  65. package/esm2022/lib/framework/mock/http/xhr/index.mjs +2 -0
  66. package/esm2022/lib/framework/mock/http/xhr/xhr-base.mjs +123 -0
  67. package/esm2022/lib/framework/mock/http/xhr/xhr-proxy-impl.mjs +177 -0
  68. package/esm2022/lib/model/business/index.mjs +5 -0
  69. package/esm2022/lib/model/business/lang/app-bridge-command.mjs +9 -0
  70. package/esm2022/lib/model/business/lang/destroyable.mjs +9 -0
  71. package/esm2022/lib/model/business/lang/identifiable.mjs +9 -0
  72. package/esm2022/lib/model/business/lang/index.mjs +5 -0
  73. package/esm2022/lib/model/business/lang/instantiable.mjs +9 -0
  74. package/esm2022/lib/model/business/mock/http/http-method-mock.mjs +9 -0
  75. package/esm2022/lib/model/business/mock/http/http-mock-config.mjs +9 -0
  76. package/esm2022/lib/model/business/mock/http/http-mock-endpoint.mjs +9 -0
  77. package/esm2022/lib/model/business/mock/http/http-mock-error.mjs +9 -0
  78. package/esm2022/lib/model/business/mock/http/http-mock-interceptor.mjs +9 -0
  79. package/esm2022/lib/model/business/mock/http/http-response-mock.mjs +9 -0
  80. package/esm2022/lib/model/business/mock/http/index.mjs +8 -0
  81. package/esm2022/lib/model/business/mock/http/xhr-proxy.mjs +9 -0
  82. package/esm2022/lib/model/business/ui/dark-mode-config.mjs +9 -0
  83. package/esm2022/lib/model/business/ui/dark-mode-config.provider.mjs +43 -0
  84. package/esm2022/lib/model/business/ui/dark-mode.constant.mjs +16 -0
  85. package/esm2022/lib/model/business/ui/index.mjs +5 -0
  86. package/esm2022/lib/model/business/ui/scroll-behavior.type.mjs +9 -0
  87. package/esm2022/lib/model/business/version/index.mjs +4 -0
  88. package/esm2022/lib/model/business/version/version-config.mjs +9 -0
  89. package/esm2022/lib/model/business/version/version-config.provider.mjs +40 -0
  90. package/esm2022/lib/model/business/version/version.mjs +10 -0
  91. package/esm2022/lib/model/index.mjs +3 -0
  92. package/esm2022/lib/model/service/index.mjs +5 -0
  93. package/esm2022/lib/model/service/mock/http/http-mock.service.mjs +239 -0
  94. package/esm2022/lib/model/service/subscription/subscription.service.mjs +122 -0
  95. package/esm2022/lib/model/service/ui/app-bridge.service.mjs +142 -0
  96. package/esm2022/lib/model/service/ui/dark-mode.service.mjs +183 -0
  97. package/esm2022/lib/model/service/ui/index.mjs +4 -0
  98. package/esm2022/lib/model/service/ui/scroll.service.mjs +93 -0
  99. package/esm2022/lib/model/service/version/version.service.mjs +51 -0
  100. package/{esm2020 → esm2022}/lib/pipe/index.mjs +1 -1
  101. package/esm2022/lib/pipe/safe/safe-html.pipe.mjs +34 -0
  102. package/esm2022/lib/util/aria-role.constant.mjs +16 -0
  103. package/esm2022/lib/util/default-scroll-behavior.mjs +13 -0
  104. package/esm2022/lib/util/empty-string.const.mjs +12 -0
  105. package/esm2022/lib/util/index.mjs +5 -0
  106. package/esm2022/lib/util/js-type.mjs +40 -0
  107. package/esm2022/lib/util/uuid.mjs +126 -0
  108. package/esm2022/public-api.mjs +18 -0
  109. package/fesm2022/angular-toolbox.mjs +3709 -0
  110. package/fesm2022/angular-toolbox.mjs.map +1 -0
  111. package/index.d.ts +5 -5
  112. package/lib/angular-toolbox.module.d.ts +9 -7
  113. package/lib/core/bridge/app-bridge.d.ts +59 -0
  114. package/lib/core/error/app-bridge-error.d.ts +16 -0
  115. package/lib/core/error/http-mock-service-error.d.ts +18 -0
  116. package/lib/core/error/index.d.ts +4 -0
  117. package/lib/core/error/integrity-error.d.ts +18 -0
  118. package/lib/core/error/subscription-error.d.ts +18 -0
  119. package/lib/core/impl/index.d.ts +1 -0
  120. package/lib/core/impl/lang/identifiable-component.d.ts +26 -0
  121. package/lib/core/impl/lang/index.d.ts +1 -0
  122. package/lib/core/impl/version/version.impl.d.ts +42 -0
  123. package/lib/core/index.d.ts +2 -0
  124. package/lib/directive/anchor-link.directive.d.ts +29 -0
  125. package/lib/directive/button-role.directive.d.ts +52 -0
  126. package/lib/directive/content-renderer.directive.d.ts +39 -0
  127. package/lib/directive/index.d.ts +4 -0
  128. package/lib/directive/navigate-to-url.directive.d.ts +23 -0
  129. package/lib/directive/navigation-directive-base.d.ts +19 -0
  130. package/lib/framework/index.d.ts +1 -0
  131. package/lib/framework/mock/http/config/http-mock-parameters.d.ts +13 -0
  132. package/lib/framework/mock/http/config/http-mock.decorator.d.ts +13 -0
  133. package/lib/framework/mock/http/config/index.d.ts +2 -0
  134. package/lib/framework/mock/http/config/route-mock-config.d.ts +30 -0
  135. package/lib/framework/mock/http/core/data-storage.d.ts +38 -0
  136. package/lib/framework/mock/http/event/event-target.impl.d.ts +70 -0
  137. package/lib/framework/mock/http/event/progress-event-mock.d.ts +36 -0
  138. package/lib/framework/mock/http/index.d.ts +3 -0
  139. package/lib/framework/mock/http/path-to-regexp/constants.d.ts +111 -0
  140. package/lib/framework/mock/http/path-to-regexp/escape-to-regexp-string.d.ts +24 -0
  141. package/lib/framework/mock/http/path-to-regexp/get-flags.d.ts +25 -0
  142. package/lib/framework/mock/http/path-to-regexp/iter.d.ts +50 -0
  143. package/lib/framework/mock/http/path-to-regexp/lexer.d.ts +24 -0
  144. package/lib/framework/mock/http/path-to-regexp/loose-replacer.d.ts +25 -0
  145. package/lib/framework/mock/http/path-to-regexp/model/decode-key-to-string.d.ts +21 -0
  146. package/lib/framework/mock/http/path-to-regexp/model/encode.d.ts +20 -0
  147. package/lib/framework/mock/http/path-to-regexp/model/key.d.ts +45 -0
  148. package/lib/framework/mock/http/path-to-regexp/model/lex-token.d.ts +34 -0
  149. package/lib/framework/mock/http/path-to-regexp/model/lexer-type.d.ts +21 -0
  150. package/lib/framework/mock/http/path-to-regexp/model/loose-replacer-provider.d.ts +20 -0
  151. package/lib/framework/mock/http/path-to-regexp/model/non-delimiter-encoder-provider.d.ts +21 -0
  152. package/lib/framework/mock/http/path-to-regexp/model/parse-options.d.ts +33 -0
  153. package/lib/framework/mock/http/path-to-regexp/model/path-to-regexp-options.d.ts +52 -0
  154. package/lib/framework/mock/http/path-to-regexp/model/route-string-tokenizer.d.ts +22 -0
  155. package/lib/framework/mock/http/path-to-regexp/model/simple-tokens.d.ts +21 -0
  156. package/lib/framework/mock/http/path-to-regexp/model/token-data-regexp-factory.d.ts +23 -0
  157. package/lib/framework/mock/http/path-to-regexp/model/token-type.d.ts +20 -0
  158. package/lib/framework/mock/http/path-to-regexp/model/token.d.ts +21 -0
  159. package/lib/framework/mock/http/path-to-regexp/string-to-token-data.d.ts +21 -0
  160. package/lib/framework/mock/http/path-to-regexp/to-key-regexp.d.ts +22 -0
  161. package/lib/framework/mock/http/path-to-regexp/to-stringify.d.ts +21 -0
  162. package/lib/framework/mock/http/path-to-regexp/token-data-to-regexp.d.ts +21 -0
  163. package/lib/framework/mock/http/path-to-regexp/token-data.d.ts +32 -0
  164. package/lib/framework/mock/http/util/data-storage.builder.d.ts +25 -0
  165. package/lib/framework/mock/http/util/http-headers-mock.builder.d.ts +106 -0
  166. package/lib/framework/mock/http/util/http-headers.util.d.ts +31 -0
  167. package/lib/framework/mock/http/util/http-method-ref.enum.d.ts +58 -0
  168. package/lib/framework/mock/http/util/http-mock-response.builder.d.ts +83 -0
  169. package/lib/framework/mock/http/util/index.d.ts +2 -0
  170. package/lib/framework/mock/http/xhr/delegate-xhr.d.ts +199 -0
  171. package/lib/framework/mock/http/xhr/http-mock-factory.d.ts +14 -0
  172. package/lib/framework/mock/http/xhr/http-mock-factory.impl.d.ts +24 -0
  173. package/lib/framework/mock/http/xhr/index.d.ts +1 -0
  174. package/lib/framework/mock/http/xhr/xhr-base.d.ts +123 -0
  175. package/lib/framework/mock/http/xhr/xhr-proxy-impl.d.ts +125 -0
  176. package/lib/model/business/index.d.ts +4 -0
  177. package/lib/model/business/lang/app-bridge-command.d.ts +11 -0
  178. package/lib/model/business/lang/destroyable.d.ts +16 -0
  179. package/lib/model/business/lang/identifiable.d.ts +19 -0
  180. package/lib/model/business/lang/index.d.ts +4 -0
  181. package/lib/model/business/lang/instantiable.d.ts +15 -0
  182. package/lib/model/business/mock/http/http-method-mock.d.ts +35 -0
  183. package/lib/model/business/mock/http/http-mock-config.d.ts +28 -0
  184. package/lib/model/business/mock/http/http-mock-endpoint.d.ts +41 -0
  185. package/lib/model/business/mock/http/http-mock-error.d.ts +21 -0
  186. package/lib/model/business/mock/http/http-mock-interceptor.d.ts +27 -0
  187. package/lib/model/business/mock/http/http-response-mock.d.ts +44 -0
  188. package/lib/model/business/mock/http/index.d.ts +7 -0
  189. package/lib/model/business/mock/http/xhr-proxy.d.ts +15 -0
  190. package/lib/model/business/ui/dark-mode-config.d.ts +29 -0
  191. package/lib/model/business/ui/dark-mode-config.provider.d.ts +21 -0
  192. package/lib/model/business/ui/dark-mode.constant.d.ts +15 -0
  193. package/lib/model/business/ui/index.d.ts +4 -0
  194. package/lib/model/business/ui/scroll-behavior.type.d.ts +11 -0
  195. package/lib/model/business/version/index.d.ts +3 -0
  196. package/lib/model/business/version/version-config.d.ts +28 -0
  197. package/lib/model/business/version/version-config.provider.d.ts +22 -0
  198. package/lib/model/business/version/version.d.ts +34 -0
  199. package/lib/model/index.d.ts +2 -0
  200. package/lib/model/service/index.d.ts +4 -0
  201. package/lib/model/service/mock/http/http-mock.service.d.ts +101 -0
  202. package/lib/model/service/subscription/subscription.service.d.ts +66 -0
  203. package/lib/model/service/ui/app-bridge.service.d.ts +80 -0
  204. package/lib/model/service/ui/dark-mode.service.d.ts +99 -0
  205. package/lib/model/service/ui/index.d.ts +3 -0
  206. package/lib/{service → model/service}/ui/scroll.service.d.ts +55 -52
  207. package/lib/model/service/version/version.service.d.ts +30 -0
  208. package/lib/pipe/index.d.ts +1 -1
  209. package/lib/pipe/safe/safe-html.pipe.d.ts +30 -10
  210. package/lib/util/aria-role.constant.d.ts +15 -0
  211. package/lib/util/default-scroll-behavior.d.ts +12 -0
  212. package/lib/util/empty-string.const.d.ts +11 -0
  213. package/lib/util/index.d.ts +4 -0
  214. package/lib/util/js-type.d.ts +39 -0
  215. package/lib/util/uuid.d.ts +89 -0
  216. package/package.json +10 -13
  217. package/public-api.d.ts +14 -3
  218. package/esm2020/lib/angular-toolbox.module.mjs +0 -26
  219. package/esm2020/lib/pipe/safe/safe-html.pipe.mjs +0 -18
  220. package/esm2020/lib/service/index.mjs +0 -4
  221. package/esm2020/lib/service/subscription/subscription.service.mjs +0 -60
  222. package/esm2020/lib/service/ui/dark-mode.service.mjs +0 -167
  223. package/esm2020/lib/service/ui/scroll.service.mjs +0 -79
  224. package/esm2020/public-api.mjs +0 -7
  225. package/fesm2015/angular-toolbox.mjs +0 -356
  226. package/fesm2015/angular-toolbox.mjs.map +0 -1
  227. package/fesm2020/angular-toolbox.mjs +0 -350
  228. package/fesm2020/angular-toolbox.mjs.map +0 -1
  229. package/lib/service/index.d.ts +0 -3
  230. package/lib/service/subscription/subscription.service.d.ts +0 -33
  231. package/lib/service/ui/dark-mode.service.d.ts +0 -92
@@ -0,0 +1,3709 @@
1
+ import * as i0 from '@angular/core';
2
+ import { NgModule, EventEmitter, Directive, Output, Input, HostListener, Inject, Injectable, inject, Pipe } from '@angular/core';
3
+ import * as i1 from '@angular/router';
4
+ import { RouterModule } from '@angular/router';
5
+ import { DOCUMENT, XhrFactory } from '@angular/common';
6
+ import { HttpStatusCode, HttpHeaders, HttpRequest } from '@angular/common/http';
7
+ import { Observable, of } from 'rxjs';
8
+ import * as i1$1 from '@angular/platform-browser';
9
+
10
+ /**
11
+ * @license
12
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
13
+ *
14
+ * Use of this source code is governed by an MIT-style license that can be found in
15
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
16
+ */
17
+ /**
18
+ * @private
19
+ */
20
+ class AngularToolboxModule {
21
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AngularToolboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
22
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.0.3", ngImport: i0, type: AngularToolboxModule }); }
23
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AngularToolboxModule }); }
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AngularToolboxModule, decorators: [{
26
+ type: NgModule
27
+ }] });
28
+
29
+ /**
30
+ * @license
31
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
32
+ *
33
+ * Use of this source code is governed by an MIT-style license that can be ound in
34
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
35
+ */
36
+ /**
37
+ * @private
38
+ */
39
+ const NAME$4 = "SubscriptionError";
40
+ /**
41
+ * Represents errors thrown by `SubscriptionService` instances.
42
+ */
43
+ class SubscriptionError extends Error {
44
+ /**
45
+ * Creates en new `SubscriptionService` instances.
46
+ *
47
+ * @param message A human-readable description of the error.
48
+ */
49
+ constructor(message) {
50
+ super(message);
51
+ this.name = NAME$4;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * @license
57
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
58
+ *
59
+ * Use of this source code is governed by an MIT-style license that can be ound in
60
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
61
+ */
62
+ /**
63
+ * @private
64
+ */
65
+ const NAME$3 = "IntegrityError";
66
+ /**
67
+ * Represents a data integrity violation error.
68
+ */
69
+ class IntegrityError extends Error {
70
+ /**
71
+ * Creates en new `IntegrityError` instances.
72
+ *
73
+ * @param message A human-readable description of the error.
74
+ */
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = NAME$3;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @license
83
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
84
+ *
85
+ * Use of this source code is governed by an MIT-style license that can be ound in
86
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
87
+ */
88
+ /**
89
+ * @private
90
+ */
91
+ const NAME$2 = "AppBridgeError";
92
+ /**
93
+ * Represents exceptions thrown by the `AppBridge` class.
94
+ */
95
+ class AppBridgeError extends ReferenceError {
96
+ /**
97
+ * @private
98
+ */
99
+ constructor(message) {
100
+ super(message);
101
+ this.name = NAME$2;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * @license
107
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
108
+ *
109
+ * Use of this source code is governed by an MIT-style license that can be ound in
110
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
111
+ */
112
+ /**
113
+ * @private
114
+ */
115
+ const NAME$1 = "HttpMockServiceError";
116
+ /**
117
+ * Represents errors thrown by `HttpMockService` instances.
118
+ */
119
+ class HttpMockServiceError extends Error {
120
+ /**
121
+ * Creates en new `HttpMockService` instances.
122
+ *
123
+ * @param message A human-readable description of the error.
124
+ */
125
+ constructor(message) {
126
+ super(message);
127
+ this.name = NAME$1;
128
+ }
129
+ }
130
+
131
+ /**
132
+ * @license
133
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
134
+ *
135
+ * Use of this source code is governed by an MIT-style license that can be found in
136
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
137
+ */
138
+ /**
139
+ * A reference to an immutable empty string.
140
+ */
141
+ const EMPTY_STRING = "";
142
+
143
+ /**
144
+ * @license
145
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
146
+ *
147
+ * Use of this source code is governed by an MIT-style license that can be found in
148
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
149
+ */
150
+ /**
151
+ * A reference to the `"button"` value of the `role` property.
152
+ */
153
+ const BUTTON_ROLE = 'button';
154
+ /**
155
+ * A reference to the `"link"` value of the `role` property.
156
+ */
157
+ const LINK_ROLE = 'link';
158
+
159
+ /**
160
+ * @license
161
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
162
+ *
163
+ * Use of this source code is governed by an MIT-style license that can be found in
164
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
165
+ */
166
+ /**
167
+ * @private
168
+ * The regexp used to validate UUID strings.
169
+ */
170
+ const VALIDATOR = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
171
+ /**
172
+ * A class that represents an immutable universally unique identifier (UUID).
173
+ * This class is not available in workers.
174
+ */
175
+ class Uuid {
176
+ /**
177
+ * @private
178
+ * Stores a boolean value used to lock constructor access.
179
+ */
180
+ static { this._lockConstructor = true; }
181
+ /**
182
+ * @private
183
+ * Stores a reference to all UUIDs already created.
184
+ */
185
+ static { this._hash = EMPTY_STRING; }
186
+ /**
187
+ * @private
188
+ * Created a new `Uuid` instance.
189
+ *
190
+ * @param uuid A string used that represents the UUID associated with this `Uuid` instance.
191
+ * If `null` creates a random UUID value.
192
+ * @param tracked If `true`, stores the UUID reference in the system.
193
+ */
194
+ constructor(uuid, tracked) {
195
+ if (Uuid._lockConstructor)
196
+ throw new ReferenceError("Uuid class has private constructor.");
197
+ const UUID = uuid || crypto.randomUUID();
198
+ this._uuid = UUID;
199
+ if (tracked)
200
+ Uuid._hash += `${UUID}|`;
201
+ Uuid._lockConstructor = true;
202
+ }
203
+ /**
204
+ * Returns a string that represents the UUID value associated with this `Uuid` instance.
205
+ *
206
+ * @returns The UUID string value associated with this `Uuid` instance.
207
+ */
208
+ toString() {
209
+ return this._uuid;
210
+ }
211
+ /**
212
+ * Compares the given `Uuid` instance with this `Uuid`.
213
+ *
214
+ * @param uuid The `Uuid` instance to compare with this `Uuid`.
215
+ *
216
+ * @returns `true` whether both `Uuid` instances are equal; `false` otherwise.
217
+ */
218
+ equals(uuid) {
219
+ return this._uuid === uuid.toString();
220
+ }
221
+ /**
222
+ * Creates and returns a new `Uuid` instance.
223
+ *
224
+ * @param track If `true`, stores the UUID reference in the system.
225
+ *
226
+ * @returns A new `Uuid` instance.
227
+ */
228
+ static build(track = false) {
229
+ Uuid._lockConstructor = false;
230
+ return new Uuid(null, track);
231
+ }
232
+ /**
233
+ * Creates and returns a new `Uuid` instance built from the specified `uuid` parameter.
234
+ *
235
+ * @param uuid The UUID string value used to create the new `Uuid` instance.
236
+ * @param track If `true`, performs a validation process to ensure that the UUID string does not exists in the system.
237
+ *
238
+ * @returns A new `Uuid` instance built from the specified `uuid` parameter.
239
+ */
240
+ static fromString(uuid, track = false) {
241
+ if (track) {
242
+ if (!this.isTracked(uuid))
243
+ throw new IntegrityError("Data Integrity Violation. UUID already exists: " + uuid);
244
+ }
245
+ if (!Uuid.validate(uuid))
246
+ throw new TypeError("Invalid UUID value: " + uuid);
247
+ Uuid._lockConstructor = false;
248
+ return new Uuid(uuid, track);
249
+ }
250
+ /**
251
+ * Performs validation on the specified `uuid` string parameter.
252
+ *
253
+ * @param uuid A UUID representation string to validate.
254
+ * @returns `true` whether the `uuid` string parameter is valid; `false` otherwise.
255
+ */
256
+ static validate(uuid) {
257
+ return VALIDATOR.test(uuid);
258
+ }
259
+ /**
260
+ * Performs a test to ensure that the UUID string is not tracked the system.
261
+ *
262
+ * @param uuid A UUID representation string to test.
263
+ * @returns `true` whether the `uuid` string parameter is tracked; `false` otherwise.
264
+ */
265
+ static isTracked(uuid) {
266
+ return !Uuid._hash.includes(uuid);
267
+ }
268
+ /**
269
+ * Releases the `Uuid` instance from the tracking system and makes it elligible for garbage collection.
270
+ *
271
+ * @returns `true` whether the `Uuid` instance was found and removed; `false` otherwise.
272
+ */
273
+ destroy() {
274
+ const ref = this._uuid;
275
+ if (!Uuid.isTracked(ref)) {
276
+ Uuid._hash = Uuid._hash.replace(ref, EMPTY_STRING);
277
+ return true;
278
+ }
279
+ return false;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * @license
285
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
286
+ *
287
+ * Use of this source code is governed by an MIT-style license that can be found in
288
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
289
+ */
290
+ /**
291
+ * A reference to the `"undefined"` type.
292
+ */
293
+ const UNDEFINED = "undefined";
294
+ /**
295
+ * A reference to the `"object"` type.
296
+ */
297
+ const OBJECT = "object";
298
+ /**
299
+ * A reference to the `"boolean"` type.
300
+ */
301
+ const BOOLEAN = "boolean";
302
+ /**
303
+ * A reference to the `"number"` type.
304
+ */
305
+ const NUMBER = "number";
306
+ /**
307
+ * A reference to the `"bigint"` type.
308
+ */
309
+ const BIGINT = "bigint";
310
+ /**
311
+ * A reference to the `"function"` type.
312
+ */
313
+ const FUNCTION = "function";
314
+ /**
315
+ * A reference to the `"string"` type.
316
+ */
317
+ const STRING = "string";
318
+ /**
319
+ * A reference to the `"symbol"` type.
320
+ */
321
+ const SYMBOL = "symbol";
322
+
323
+ /**
324
+ * @license
325
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
326
+ *
327
+ * Use of this source code is governed by an MIT-style license that can be ound in
328
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
329
+ */
330
+ /**
331
+ * @private
332
+ * The base class that must be extended by objects to be indentified by the
333
+ * Angular Toolbox Subscription Service.
334
+ */
335
+ class IdentifiableComponent {
336
+ constructor() {
337
+ /**
338
+ * @private
339
+ */
340
+ this._uuid = Uuid.build();
341
+ }
342
+ /**
343
+ * Returns the unique identifier for this object.
344
+ *
345
+ * @returns An instance of the `Uuid` class.
346
+ */
347
+ getID() {
348
+ return this._uuid;
349
+ }
350
+ }
351
+ ;
352
+
353
+ /**
354
+ * @license
355
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
356
+ *
357
+ * Use of this source code is governed by an MIT-style license that can be
358
+ * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
359
+ */
360
+ /**
361
+ * @private
362
+ * The base class for all directives that are responsible for navigation whithin ab Angular app.
363
+ */
364
+ class NavigationDirectiveBase {
365
+ /**
366
+ * @private
367
+ */
368
+ constructor(elmRef, role) {
369
+ this.elmRef = elmRef;
370
+ const elm = elmRef.nativeElement;
371
+ elm.role = role;
372
+ elm.tabIndex = 0;
373
+ }
374
+ }
375
+
376
+ /**
377
+ * @license
378
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
379
+ *
380
+ * Use of this source code is governed by an MIT-style license that can be
381
+ * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
382
+ */
383
+ /**
384
+ * @private
385
+ */
386
+ const ENTER_KEY = 'Enter';
387
+ /**
388
+ * @private
389
+ */
390
+ const ROUTER_LINK_REF = 'ng-reflect-router-link';
391
+ /**
392
+ * An easy-to-use directive that enables keyboard navigation and provides support for keyboard "Enter" key events.
393
+ */
394
+ class ButtonRoleDirective extends NavigationDirectiveBase {
395
+ /**
396
+ * @private
397
+ */
398
+ onKeyup(event, value) {
399
+ if (event.key !== ENTER_KEY)
400
+ return;
401
+ this.processEvent(event, value);
402
+ }
403
+ /**
404
+ * @private
405
+ */
406
+ onClick(event, value) {
407
+ if (this.delegateClick === undefined)
408
+ return;
409
+ this.processEvent(event, value);
410
+ }
411
+ /**
412
+ * @private
413
+ */
414
+ constructor(elmRef, _router) {
415
+ super(elmRef, BUTTON_ROLE);
416
+ this._router = _router;
417
+ /**
418
+ * Dispatches events when the user presses the "Enter" key.
419
+ */
420
+ this.enter = new EventEmitter();
421
+ /**
422
+ * @private
423
+ */
424
+ this._routerLinkRef = null;
425
+ }
426
+ /**
427
+ * @private
428
+ */
429
+ ngAfterViewInit() {
430
+ const elm = this.elmRef.nativeElement;
431
+ this._routerLinkRef = elm.getAttribute(ROUTER_LINK_REF);
432
+ }
433
+ /**
434
+ * @private
435
+ */
436
+ processEvent(event, value) {
437
+ event.preventDefault();
438
+ event.stopImmediatePropagation();
439
+ if (this._routerLinkRef) {
440
+ this._router.navigate([this._routerLinkRef]);
441
+ return;
442
+ }
443
+ this.elmRef.nativeElement.blur();
444
+ this.enter.emit(value);
445
+ }
446
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ButtonRoleDirective, deps: [{ token: i0.ElementRef }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Directive }); }
447
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.3", type: ButtonRoleDirective, isStandalone: true, selector: "[buttonRole]", inputs: { delegateClick: "delegateClick" }, outputs: { enter: "enter" }, host: { listeners: { "keyup": "onKeyup($event,$event.target.value)", "click": "onClick($event,$event.target.value)" } }, providers: [
448
+ RouterModule
449
+ ], usesInheritance: true, ngImport: i0 }); }
450
+ }
451
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ButtonRoleDirective, decorators: [{
452
+ type: Directive,
453
+ args: [{
454
+ selector: '[buttonRole]',
455
+ providers: [
456
+ RouterModule
457
+ ],
458
+ standalone: true
459
+ }]
460
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.Router }], propDecorators: { enter: [{
461
+ type: Output
462
+ }], delegateClick: [{
463
+ type: Input
464
+ }], onKeyup: [{
465
+ type: HostListener,
466
+ args: ['keyup', ["$event", "$event.target.value"]]
467
+ }], onClick: [{
468
+ type: HostListener,
469
+ args: ['click', ["$event", "$event.target.value"]]
470
+ }] } });
471
+
472
+ /**
473
+ * @license
474
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
475
+ *
476
+ * Use of this source code is governed by an MIT-style license that can be
477
+ * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
478
+ */
479
+ /**
480
+ * An easy-to-use directive that enables keyboard navigation and provides support for navigating to an external URL.
481
+ */
482
+ class NavigateToUrlDirective extends NavigationDirectiveBase {
483
+ /**
484
+ * @private
485
+ */
486
+ onClick() {
487
+ const HREF = this.href;
488
+ if (!HREF)
489
+ throw new ReferenceError("href attribute is not defined.");
490
+ this._document.defaultView.location.href = HREF;
491
+ }
492
+ /**
493
+ * @private
494
+ */
495
+ constructor(_document, elmRef) {
496
+ super(elmRef, LINK_ROLE);
497
+ this._document = _document;
498
+ }
499
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NavigateToUrlDirective, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
500
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.3", type: NavigateToUrlDirective, isStandalone: true, selector: "[navigateToUrl]", inputs: { href: "href" }, host: { listeners: { "click": "onClick()" } }, usesInheritance: true, ngImport: i0 }); }
501
+ }
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: NavigateToUrlDirective, decorators: [{
503
+ type: Directive,
504
+ args: [{
505
+ selector: '[navigateToUrl]',
506
+ standalone: true
507
+ }]
508
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
509
+ type: Inject,
510
+ args: [DOCUMENT]
511
+ }] }, { type: i0.ElementRef }], propDecorators: { href: [{
512
+ type: Input
513
+ }], onClick: [{
514
+ type: HostListener,
515
+ args: ['click']
516
+ }] } });
517
+
518
+ /**
519
+ * @license
520
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
521
+ *
522
+ * Use of this source code is governed by an MIT-style license that can be ound in
523
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
524
+ */
525
+ /**
526
+ * @private
527
+ * An internal convenient object that defined default `ScrollIntoViewOptions` objects.
528
+ */
529
+ const DEFAULT_SCROLL_BEHAVIOR = { behavior: "smooth", block: "start", inline: "nearest" };
530
+
531
+ /**
532
+ * @license
533
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
534
+ *
535
+ * Use of this source code is governed by an MIT-style license that can be
536
+ * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
537
+ */
538
+ /**
539
+ * Provides functionality to activate anchor navigation through the native Angular router.
540
+ */
541
+ class AnchorLinklDirective extends NavigationDirectiveBase {
542
+ /**
543
+ * @private
544
+ */
545
+ onClick(event) {
546
+ event.preventDefault();
547
+ const HREF = this.href;
548
+ this._router.navigate([], { fragment: HREF.slice(1) });
549
+ this._document.querySelector(HREF).scrollIntoView(DEFAULT_SCROLL_BEHAVIOR);
550
+ }
551
+ /**
552
+ * @private
553
+ */
554
+ constructor(_document, elmRef, _router) {
555
+ super(elmRef, LINK_ROLE);
556
+ this._document = _document;
557
+ this._router = _router;
558
+ }
559
+ /**
560
+ * @private
561
+ */
562
+ ngAfterViewInit() {
563
+ const HREF = this.href;
564
+ if (!HREF)
565
+ throw new ReferenceError("href attribute is not defined.");
566
+ }
567
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AnchorLinklDirective, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Directive }); }
568
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.3", type: AnchorLinklDirective, isStandalone: true, selector: "[anchorLink]", inputs: { href: "href" }, host: { listeners: { "click": "onClick($event)" } }, usesInheritance: true, ngImport: i0 }); }
569
+ }
570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AnchorLinklDirective, decorators: [{
571
+ type: Directive,
572
+ args: [{
573
+ selector: '[anchorLink]',
574
+ standalone: true,
575
+ }]
576
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
577
+ type: Inject,
578
+ args: [DOCUMENT]
579
+ }] }, { type: i0.ElementRef }, { type: i1.Router }], propDecorators: { href: [{
580
+ type: Input
581
+ }], onClick: [{
582
+ type: HostListener,
583
+ args: ['click', ['$event']]
584
+ }] } });
585
+
586
+ /**
587
+ * @license
588
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
589
+ *
590
+ * Use of this source code is governed by an MIT-style license that can be
591
+ * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
592
+ */
593
+ /**
594
+ * @private
595
+ */
596
+ const CHILD_LIST_TYPE = "childList";
597
+ /**
598
+ * Allows injection of any value into an HTML element container (`div`, `button`, etc...).
599
+ * A rendered event is emitted after the injected content has been rendered and is
600
+ * available for DOM manipulation.
601
+ */
602
+ class ContentRendererDirective {
603
+ /**
604
+ * @private
605
+ */
606
+ constructor(_elmRef) {
607
+ this._elmRef = _elmRef;
608
+ /**
609
+ * Dispatches events when the content of the HTML element has been rendered.
610
+ */
611
+ this.rendered = new EventEmitter();
612
+ const nativeElement = this._elmRef.nativeElement;
613
+ this._observer = new MutationObserver((mutations) => {
614
+ mutations.forEach((mutation) => {
615
+ if (mutation.type === CHILD_LIST_TYPE)
616
+ this.rendered.emit(nativeElement);
617
+ });
618
+ });
619
+ }
620
+ /**
621
+ * @private
622
+ */
623
+ ngOnDestroy() {
624
+ this._observer.disconnect();
625
+ }
626
+ /**
627
+ * @private
628
+ */
629
+ ngOnInit() {
630
+ this._observer.observe(this._elmRef.nativeElement, { attributes: false, childList: true, characterData: false });
631
+ }
632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ContentRendererDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
633
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.3", type: ContentRendererDirective, isStandalone: true, selector: "[contentRenderer]", outputs: { rendered: "rendered" }, ngImport: i0 }); }
634
+ }
635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ContentRendererDirective, decorators: [{
636
+ type: Directive,
637
+ args: [{
638
+ selector: '[contentRenderer]',
639
+ standalone: true
640
+ }]
641
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { rendered: [{
642
+ type: Output
643
+ }] } });
644
+
645
+ /**
646
+ * @license
647
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
648
+ *
649
+ * Use of this source code is governed by an MIT-style license that can be found in
650
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
651
+ */
652
+
653
+ /**
654
+ * @license
655
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
656
+ *
657
+ * Use of this source code is governed by an MIT-style license that can be found in
658
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
659
+ */
660
+ ;
661
+
662
+ /**
663
+ * @license
664
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
665
+ *
666
+ * Use of this source code is governed by an MIT-style license that can be found in
667
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
668
+ */
669
+
670
+ /**
671
+ * @license
672
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
673
+ *
674
+ * Use of this source code is governed by an MIT-style license that can be found in
675
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
676
+ */
677
+ /**
678
+ * The default provider for the `VersionService` configuration. You typically define
679
+ * the custom properties in the main `NgModule` declaration to initialize the application
680
+ * config:
681
+ *
682
+ * @NgModule({
683
+ * ...
684
+ * providers: [
685
+ * { provide: VERSION_CONFIG, useValue: { major: 1, minor: 2, patch: 12 } }
686
+ * ],
687
+ * ...
688
+ * });
689
+ */
690
+ const VERSION_CONFIG = {
691
+ /**
692
+ * Specifies the major number of this config.
693
+ */
694
+ major: 0,
695
+ /**
696
+ * Specifies the minor number of this config.
697
+ */
698
+ minor: 0,
699
+ /**
700
+ * Specifies the patch number of this config.
701
+ */
702
+ patch: 0,
703
+ /**
704
+ * Specifies the timestamp that corresponds to the build date for this `Version` object.
705
+ * Default value is `NaN`.
706
+ */
707
+ buildTimestamp: NaN
708
+ };
709
+
710
+ /**
711
+ * @license
712
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
713
+ *
714
+ * Use of this source code is governed by an MIT-style license that can be found in
715
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
716
+ */
717
+
718
+ /**
719
+ * @license
720
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
721
+ *
722
+ * Use of this source code is governed by an MIT-style license that can be found in
723
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
724
+ */
725
+ /**
726
+ * Reference to the dark mode default storage key.
727
+ */
728
+ const STORAGE_KEY = "dark-mode-key";
729
+ /**
730
+ * Reference to the dark mode default css property.
731
+ */
732
+ const CSS_PROP = "dark-mode";
733
+
734
+ /**
735
+ * @license
736
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
737
+ *
738
+ * Use of this source code is governed by an MIT-style license that can be found in
739
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
740
+ */
741
+ /**
742
+ * The default provider for the `DarkModeService` configuration. You typically define
743
+ * the custom properties in the main NgModule declaration to initialize the app dark mode:
744
+ *
745
+ * @NgModule({
746
+ * ...
747
+ * providers: [
748
+ * { provide: DARK_MODE_CONFIG, useValue: { enableDarkMode: true } }
749
+ * ],
750
+ * ...
751
+ * });
752
+ */
753
+ const DARK_MODE_CONFIG = {
754
+ /**
755
+ * Indicates whether the dark mode uses browser settings (`true`), or not (`false`).
756
+ * Default value is `false`.
757
+ */
758
+ darkModeEnabled: false,
759
+ /**
760
+ * Indicates whether the dark mode uses browser settings (`true`), or not (`false`).
761
+ * Default value is `false`.
762
+ */
763
+ detectBrowserSettings: false,
764
+ /**
765
+ * CSS property name used to set the dark mode look and feel.
766
+ * Default value is `'dark-mode'`.
767
+ */
768
+ cssProperty: CSS_PROP,
769
+ /**
770
+ * Reference to the key value used to persist the dark mode state to local storage.
771
+ * Default value is `'dark-mode-key'`.
772
+ */
773
+ storageKey: STORAGE_KEY
774
+ };
775
+
776
+ /**
777
+ * @license
778
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
779
+ *
780
+ * Use of this source code is governed by an MIT-style license that can be found in
781
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
782
+ */
783
+
784
+ /**
785
+ * @license
786
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
787
+ *
788
+ * Use of this source code is governed by an MIT-style license that can be found in
789
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
790
+ */
791
+
792
+ /**
793
+ * @license
794
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
795
+ *
796
+ * Use of this source code is governed by an MIT-style license that can be ound in
797
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
798
+ */
799
+
800
+ /**
801
+ * @license
802
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
803
+ *
804
+ * Use of this source code is governed by an MIT-style license that can be ound in
805
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
806
+ */
807
+
808
+ /**
809
+ * @license
810
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
811
+ *
812
+ * Use of this source code is governed by an MIT-style license that can be ound in
813
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
814
+ */
815
+
816
+ /**
817
+ * @license
818
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
819
+ *
820
+ * Use of this source code is governed by an MIT-style license that can be found in
821
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
822
+ */
823
+
824
+ /**
825
+ * @license
826
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
827
+ *
828
+ * Use of this source code is governed by an MIT-style license that can be found in
829
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
830
+ */
831
+
832
+ /**
833
+ * @license
834
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
835
+ *
836
+ * Use of this source code is governed by an MIT-style license that can be found in
837
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
838
+ */
839
+
840
+ /**
841
+ * @license
842
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
843
+ *
844
+ * Use of this source code is governed by an MIT-style license that can be found in
845
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
846
+ */
847
+
848
+ /**
849
+ * @license
850
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
851
+ *
852
+ * Use of this source code is governed by an MIT-style license that can be found in
853
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
854
+ */
855
+
856
+ /**
857
+ * @license
858
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
859
+ *
860
+ * Use of this source code is governed by an MIT-style license that can be found in
861
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
862
+ */
863
+
864
+ /**
865
+ * @license
866
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
867
+ *
868
+ * Use of this source code is governed by an MIT-style license that can be found in
869
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
870
+ */
871
+
872
+ /**
873
+ * @license
874
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
875
+ *
876
+ * Use of this source code is governed by an MIT-style license that can be found in
877
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
878
+ */
879
+ /**
880
+ * A lightweight service that helps to manage unregistration issues of Angular subscriptions.
881
+ */
882
+ class SubscriptionService {
883
+ constructor() {
884
+ /**
885
+ * @private
886
+ * Stores an internal reference to the last reference used with the `register()`
887
+ * method.
888
+ */
889
+ this._lastRef = null;
890
+ /**
891
+ * @private
892
+ * The internal `Subscription` instances storage.
893
+ */
894
+ this._subMap = new Map();
895
+ }
896
+ /**
897
+ * Stores a new `Subscription` instance associated with the specified reference.
898
+ *
899
+ * @param ref The reference for which to store a new `Subscription` instance.
900
+ * Can be either a string or an `Identifiable` object.
901
+ * @param subscription The `Subscription` instance to register.
902
+ *
903
+ * @returns A reference to this `SubscriptionService` instance.
904
+ */
905
+ register(ref, subscription) {
906
+ const REF = this.getRef(ref);
907
+ this._lastRef = REF;
908
+ if (!this._subMap.has(REF))
909
+ this._subMap.set(REF, []);
910
+ this._subMap.get(REF)?.push(subscription);
911
+ return this;
912
+ }
913
+ /**
914
+ * Stores a new `Subscription` instance associated with the reference specified
915
+ * by the last `register()` method invokation.
916
+ *
917
+ * @param subscription The `Subscription` instance to register.
918
+ *
919
+ * @returns A reference to this `SubscriptionService` instance.
920
+ */
921
+ append(subscription) {
922
+ if (!this._lastRef)
923
+ throw new SubscriptionError("Illegal Access Error: you must call the register() method before invoking the append() method.");
924
+ return this.register(this._lastRef, subscription);
925
+ }
926
+ /**
927
+ * Unsubscribes and removes all `Subscription` instances associated with the specified reference.
928
+ *
929
+ * @param ref The reference for which to remove all `Subscription` instances.
930
+ * Can be either a string or an `Identifiable` object.
931
+ *
932
+ * @returns `true` whether the specified reference exists; `false` otherwise.
933
+ */
934
+ clearAll(ref) {
935
+ const REF = this.getRef(ref);
936
+ let result = false;
937
+ if (this._lastRef === REF)
938
+ this._lastRef = null;
939
+ if (this._subMap.has(REF)) {
940
+ this._subMap.get(REF)?.forEach(subscription => {
941
+ if (!subscription.closed)
942
+ subscription.unsubscribe();
943
+ });
944
+ this._subMap.delete(REF);
945
+ result = true;
946
+ }
947
+ return result;
948
+ }
949
+ /**
950
+ * Returns all `Subscription` instances associated with the specified reference.
951
+ *
952
+ * @param ref The reference for which to remove get `Subscription` instances.
953
+ * Can be either a string or an `Identifiable` object.
954
+ *
955
+ * @returns All `Subscription` instances associated with the specified reference, or
956
+ * `null` whether the specified reference does not exists.
957
+ */
958
+ get(ref) {
959
+ return this._subMap.get(this.getRef(ref)) || null;
960
+ }
961
+ /**
962
+ * @private
963
+ * Returns the string reference for the regsitration process.
964
+ *
965
+ * @param ref The reference to be used the regsitration process.
966
+ * Can be either a string or an `Identifiable` object.
967
+ *
968
+ * @returns the string reference for the regsitration process.
969
+ */
970
+ getRef(ref) {
971
+ let targetRef;
972
+ if (typeof ref === "string")
973
+ targetRef = ref;
974
+ else if (ref instanceof IdentifiableComponent)
975
+ targetRef = ref.getID().toString();
976
+ else
977
+ throw new TypeError("ref must be of type of string or Identifiable");
978
+ return targetRef;
979
+ }
980
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: SubscriptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
981
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: SubscriptionService, providedIn: 'root' }); }
982
+ }
983
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: SubscriptionService, decorators: [{
984
+ type: Injectable,
985
+ args: [{
986
+ providedIn: 'root'
987
+ }]
988
+ }] });
989
+
990
+ /**
991
+ * @license
992
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
993
+ *
994
+ * Use of this source code is governed by an MIT-style license that can be ound in
995
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
996
+ */
997
+ // --> Internal constants
998
+ /**
999
+ * @private
1000
+ */
1001
+ const ADD_ACTION = "add";
1002
+ /**
1003
+ * @private
1004
+ */
1005
+ const REMOVE_ACTION = "remove";
1006
+ /**
1007
+ * @private
1008
+ */
1009
+ const TRUE = "true";
1010
+ /**
1011
+ * A lightweight service that provides Dark Mode implementation for your Angular application.
1012
+ */
1013
+ class DarkModeService {
1014
+ /**
1015
+ * @private
1016
+ * Creates a new `DarkModeService` instance.
1017
+ *
1018
+ * @param _document The reference to the `Document` singleton.
1019
+ * @param config The reference to the `DarkModeConfig` provider.
1020
+ */
1021
+ constructor(_document, config) {
1022
+ this._document = _document;
1023
+ /**
1024
+ * @private
1025
+ */
1026
+ this._darkModeEnabled = false;
1027
+ /**
1028
+ * @private
1029
+ */
1030
+ this._cssProperty = CSS_PROP;
1031
+ /**
1032
+ * @private
1033
+ */
1034
+ this._storageKey = STORAGE_KEY;
1035
+ /**
1036
+ * The callback function that is triggered when the dark mode changes.
1037
+ *
1038
+ * @typeParam `EventEmitter<boolean>` the value returned by the `darkModeEnabled()` property.
1039
+ */
1040
+ this.change = new EventEmitter(true);
1041
+ this.initDarkMode(config);
1042
+ }
1043
+ /**
1044
+ * Toogles the dark mode state.
1045
+ */
1046
+ toggleDarkMode() {
1047
+ this._darkModeEnabled ? this.disableDarkMode() : this.enableDarkMode();
1048
+ }
1049
+ /**
1050
+ * Sets the dark mode state to active.
1051
+ */
1052
+ enableDarkMode() {
1053
+ this.setDarkMode(ADD_ACTION);
1054
+ this.setStoredDarkMode();
1055
+ }
1056
+ /**
1057
+ * Sets the dark mode state to inactive.
1058
+ */
1059
+ disableDarkMode() {
1060
+ this.setDarkMode(REMOVE_ACTION);
1061
+ this.setStoredDarkMode();
1062
+ }
1063
+ /**
1064
+ * Returns a `boolean` value that indicates whether the dark mode state is active (`true`), or not (`false`).
1065
+ *
1066
+ * @returns `true` whether the dark mode state is active; `false` otherwise.
1067
+ */
1068
+ darkModeEnabled() {
1069
+ return this._darkModeEnabled;
1070
+ }
1071
+ /**
1072
+ * Returns the value of the CSS property as defined by the config provider.
1073
+ *
1074
+ * @returns The value of the CSS property.
1075
+ */
1076
+ getCssProperty() {
1077
+ return this._cssProperty;
1078
+ }
1079
+ /**
1080
+ * Returns the value of the storage key as defined by the config provider.
1081
+ *
1082
+ * @returns The value of the storage key.
1083
+ */
1084
+ getStorageKey() {
1085
+ return this._storageKey;
1086
+ }
1087
+ /**
1088
+ * Removes the dark mode information from local storage.
1089
+ */
1090
+ invalidateStorage() {
1091
+ localStorage.removeItem(this._storageKey);
1092
+ }
1093
+ /**
1094
+ * @private
1095
+ */
1096
+ initDarkMode(config) {
1097
+ this._darkModeEnabled = config.darkModeEnabled || false;
1098
+ this._cssProperty = config.cssProperty || CSS_PROP;
1099
+ this._storageKey = config.storageKey || STORAGE_KEY;
1100
+ if (this._darkModeEnabled) {
1101
+ this.enableDarkMode();
1102
+ }
1103
+ else {
1104
+ this.initStoredDarkMode();
1105
+ }
1106
+ if (config.detectBrowserSettings)
1107
+ this.initBrowserMode();
1108
+ }
1109
+ /**
1110
+ * @private
1111
+ */
1112
+ initStoredDarkMode() {
1113
+ const result = localStorage.getItem(this._storageKey);
1114
+ if (result === TRUE)
1115
+ this.enableDarkMode();
1116
+ }
1117
+ /**
1118
+ * @private
1119
+ */
1120
+ setStoredDarkMode() {
1121
+ const data = String(this._darkModeEnabled);
1122
+ localStorage.setItem(this._storageKey, data);
1123
+ }
1124
+ /**
1125
+ * @private
1126
+ */
1127
+ setDarkMode(action) {
1128
+ const classList = this._document.body.classList;
1129
+ if (action === ADD_ACTION) {
1130
+ classList.add(this._cssProperty);
1131
+ this._darkModeEnabled = true;
1132
+ }
1133
+ else if (action === REMOVE_ACTION) {
1134
+ classList.remove(this._cssProperty);
1135
+ this._darkModeEnabled = false;
1136
+ }
1137
+ this.change.emit(this._darkModeEnabled);
1138
+ }
1139
+ /**
1140
+ * @private
1141
+ */
1142
+ initBrowserMode() {
1143
+ if (this.matchDarkTheme())
1144
+ return this.enableDarkMode();
1145
+ this.disableDarkMode();
1146
+ }
1147
+ /**
1148
+ * @private
1149
+ */
1150
+ matchDarkTheme() {
1151
+ return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
1152
+ }
1153
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: DarkModeService, deps: [{ token: DOCUMENT }, { token: DARK_MODE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
1154
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: DarkModeService, providedIn: 'root' }); }
1155
+ }
1156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: DarkModeService, decorators: [{
1157
+ type: Injectable,
1158
+ args: [{
1159
+ providedIn: 'root'
1160
+ }]
1161
+ }], ctorParameters: () => [{ type: Document, decorators: [{
1162
+ type: Inject,
1163
+ args: [DOCUMENT]
1164
+ }] }, { type: undefined, decorators: [{
1165
+ type: Inject,
1166
+ args: [DARK_MODE_CONFIG]
1167
+ }] }] });
1168
+
1169
+ /**
1170
+ * @license
1171
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1172
+ *
1173
+ * Use of this source code is governed by an MIT-style license that can be found in
1174
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1175
+ */
1176
+ /**
1177
+ * A lightweight service that provides scrolling capabilities to your Angular application.
1178
+ */
1179
+ class ScrollService {
1180
+ /**
1181
+ * @private
1182
+ * Creates a new `ScrollService` instance.
1183
+ *
1184
+ * @param _document The reference to the `Document` singleton.
1185
+ */
1186
+ constructor(_document) {
1187
+ this._document = _document;
1188
+ /**
1189
+ * The callback function that is triggered when a scroll operation is performed.
1190
+ *
1191
+ * @typeParam `EventEmitter<Event>` The reference to the original scroll event.
1192
+ */
1193
+ this.onScroll = new EventEmitter();
1194
+ window.addEventListener("scroll", (e) => {
1195
+ this.onScroll.next(e);
1196
+ });
1197
+ }
1198
+ /**
1199
+ * Scrolls the ancestor containers of the element with the specified selector such that
1200
+ * this element is visible to the user.
1201
+ *
1202
+ * @param selector The selector of the target element.
1203
+ * @param arg A `boolean` value:
1204
+ * If `true`, the top of the element will be aligned to the top of the visible area of the
1205
+ * scrollable ancestor.
1206
+ * If `false`, the bottom of the element will be aligned to the bottom of the visible area
1207
+ * of the scrollable ancestor.
1208
+ * @param arg A dictionary containing the scroll parameters.
1209
+ */
1210
+ scrollIntoView(selector, arg) {
1211
+ const elm = this._document.querySelector(selector);
1212
+ if (elm)
1213
+ elm.scrollIntoView(arg);
1214
+ }
1215
+ /**
1216
+ * Scrolls the app viewport to the top of the browser window.
1217
+ *
1218
+ * @param behavior Specifies whether the scrolling should animate smoothly (`smooth`),
1219
+ * happen instantly in a single jump (`instant`), or let the browser
1220
+ * choose (`auto`, `default`).
1221
+ */
1222
+ gotoTop(behavior = 'smooth') {
1223
+ const options = {
1224
+ top: 0,
1225
+ behavior: behavior
1226
+ };
1227
+ this.scroll(options);
1228
+ }
1229
+ /**
1230
+ * Scrolls the app viewport according to the specified options, into the browser window.
1231
+ *
1232
+ * @param options A dictionary containing the scroll parameters.
1233
+ */
1234
+ scroll(options) {
1235
+ window.scroll(options);
1236
+ }
1237
+ /**
1238
+ * Scrolls the app viewport by the specified `x/y` coordinates, into the browser window.
1239
+ *
1240
+ * @param x The horizontal pixel value that you want to scroll by.
1241
+ * @param y The vertical pixel value that you want to scroll by.
1242
+ */
1243
+ scrollBy(x, y) {
1244
+ window.scrollBy(x, y);
1245
+ }
1246
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ScrollService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1247
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ScrollService, providedIn: 'root' }); }
1248
+ }
1249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: ScrollService, decorators: [{
1250
+ type: Injectable,
1251
+ args: [{
1252
+ providedIn: 'root'
1253
+ }]
1254
+ }], ctorParameters: () => [{ type: Document, decorators: [{
1255
+ type: Inject,
1256
+ args: [DOCUMENT]
1257
+ }] }] });
1258
+
1259
+ /**
1260
+ * @license
1261
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1262
+ *
1263
+ * Use of this source code is governed by an MIT-style license that can be ound in
1264
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1265
+ */
1266
+ /**
1267
+ * @private
1268
+ * The `AppBridge` class is an internal invoker utility that executes commans declared
1269
+ * by the `AppBridgeService` instance.
1270
+ */
1271
+ class AppBridge {
1272
+ constructor() {
1273
+ /**
1274
+ * @private
1275
+ * Stores all commands registered by the `AppBridgeService` instance.
1276
+ */
1277
+ this._commandMap = new Map();
1278
+ }
1279
+ /**
1280
+ * Executes the command with the specified `name` parameter.
1281
+ *
1282
+ * @param name The reference to the command to execute.
1283
+ * @param args The list of parmeters so be sent to the command.
1284
+ */
1285
+ execute(name, ...args) {
1286
+ const command = this._commandMap.get(name);
1287
+ if (command)
1288
+ command.apply(null, args);
1289
+ else
1290
+ throw new AppBridgeError(`Invalid AppBridge command: method width name '${name}' does not exist.`);
1291
+ }
1292
+ /**
1293
+ * Registers a command.
1294
+ *
1295
+ * @param name The name of the command to register.
1296
+ * @param command The command to register.
1297
+ */
1298
+ addCommand(name, command) {
1299
+ this._commandMap.set(name, command);
1300
+ }
1301
+ /**
1302
+ * Unregisters a command.
1303
+ *
1304
+ * @param name The name of the command to unregister.
1305
+ *
1306
+ * @returns `true` whether the command existed and has been removed; `false` otherwise.
1307
+ */
1308
+ removeCommand(name) {
1309
+ return this._commandMap.delete(name);
1310
+ }
1311
+ /**
1312
+ * Returns the command with the specified name.
1313
+ *
1314
+ * @param name The name of the command to retrieve.
1315
+ *
1316
+ * @returns Returns the command associated with the specified name.
1317
+ * If no command is associated with the specified name, `undefined` is returned.
1318
+ */
1319
+ getCommand(name) {
1320
+ return this._commandMap.get(name);
1321
+ }
1322
+ /**
1323
+ * Returns a boolean indicating whether a command with the specified name exists or not.
1324
+ *
1325
+ * @param name The name of the command to retrieve.
1326
+ *
1327
+ * @returns Returns `true` whether the command exists; `false` otherwise.
1328
+ */
1329
+ hasCommand(name) {
1330
+ return this._commandMap.has(name);
1331
+ }
1332
+ }
1333
+
1334
+ /**
1335
+ * @license
1336
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1337
+ *
1338
+ * Use of this source code is governed by an MIT-style license that can be ound in
1339
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1340
+ */
1341
+ /**
1342
+ * @private
1343
+ */
1344
+ const APP_PRIDGE_REF = "appBridge";
1345
+ /**
1346
+ * @private
1347
+ */
1348
+ const HREF = "href";
1349
+ /**
1350
+ * @private
1351
+ */
1352
+ const NATIVE_COMMANDS = "navigate|goToAnchor|declareCommand|deleteCommand|getCommand";
1353
+ /**
1354
+ * A utility service that allows dynamically injected HTML fragments, to interact with the Angular application.
1355
+ */
1356
+ class AppBrigeService {
1357
+ /**
1358
+ * @private
1359
+ */
1360
+ constructor(_router, _zone, _document) {
1361
+ this._router = _router;
1362
+ this._zone = _zone;
1363
+ this._document = _document;
1364
+ this._defaultView = _document.defaultView;
1365
+ this._appBridge = new AppBridge();
1366
+ if (!this._defaultView[APP_PRIDGE_REF])
1367
+ this._defaultView[APP_PRIDGE_REF] = this;
1368
+ }
1369
+ /**
1370
+ * Provides the ability to invoke the `navigate()` method of the Angular app router.
1371
+ *
1372
+ * @param commands The commands array as specified by the Angular router `navigate()` method.
1373
+ * @param extras The navigation options as specified by the Angular router `navigate()` method.
1374
+ * @return `Promise` that resolves to `true` when navigation succeeds, or `false` when navigation fails.
1375
+ *
1376
+ * @see https://angular.dev/api/router/Router#navigate
1377
+ */
1378
+ navigate(commands, extras) {
1379
+ return this._zone.run(() => {
1380
+ return this._router.navigate(commands, extras);
1381
+ });
1382
+ }
1383
+ /**
1384
+ * Allows to scroll to the fragment specified by the `href` attribute when the user element interact with the associated element.
1385
+ *
1386
+ * @example
1387
+ * <a href="#myAnchor" onclick="appBridge.goToAnchor(event)">My Section</a></code>
1388
+ *
1389
+ * @param event The event that triggers the anchor navigation.
1390
+ * @return `Promise` that resolves to `true` when navigation succeeds, or `false` when navigation fails.
1391
+ *
1392
+ * @see https://angular.dev/api/router/Router#navigate
1393
+ */
1394
+ goToAnchor(event) {
1395
+ event.preventDefault();
1396
+ const anchor = event.target.getAttribute(HREF);
1397
+ if (!anchor)
1398
+ throw new ReferenceError("href attribute is not defined.");
1399
+ const elm = this._document.querySelector(anchor);
1400
+ if (!elm)
1401
+ return new Promise((resolve) => resolve(false));
1402
+ elm.scrollIntoView(DEFAULT_SCROLL_BEHAVIOR);
1403
+ return this._zone.run(() => {
1404
+ return this._router.navigate([], { fragment: anchor.slice(1) });
1405
+ });
1406
+ }
1407
+ /**
1408
+ * Declares a new JavaScript command to be used with dynamically loaded documents.
1409
+ *
1410
+ * @param name The name of the command to declare.
1411
+ * @param command The reference to a JavaScript command to be used with dynamically loaded documents.
1412
+ */
1413
+ declareCommand(name, command) {
1414
+ this.checkCommandName(name);
1415
+ if (!this._appBridge.hasCommand(name)) {
1416
+ this._appBridge.addCommand(name, command);
1417
+ Object.defineProperty(this, name, {
1418
+ configurable: true,
1419
+ get: function () {
1420
+ return this._appBridge.getCommand(name);
1421
+ }
1422
+ });
1423
+ }
1424
+ }
1425
+ /**
1426
+ * Unregisters a JavaScript command previously referenced with the `declareCommand()` method.
1427
+ *
1428
+ * @param name The name of the command to remove.
1429
+ *
1430
+ * @returns `true` whether the command existed and has been removed; `false` otherwise.
1431
+ */
1432
+ deleteCommand(name) {
1433
+ this.checkCommandName(name);
1434
+ if (!this._appBridge.removeCommand(name))
1435
+ return false;
1436
+ delete this._defaultView[APP_PRIDGE_REF][name];
1437
+ return true;
1438
+ }
1439
+ /**
1440
+ * Returns the JavaScript command previously referenced with the `declareCommand()` method.
1441
+ *
1442
+ * @param name The name of the command to retrieve.
1443
+ * @returns The JavaScript command previously referenced with the specified `name` parameter.
1444
+ * If no command is found, returns `undefined`.
1445
+ */
1446
+ getCommand(name) {
1447
+ return this._appBridge.getCommand(name);
1448
+ }
1449
+ /**
1450
+ * @private
1451
+ */
1452
+ checkCommandName(name) {
1453
+ if (NATIVE_COMMANDS.includes(name))
1454
+ throw new AppBridgeError("Command name cannot be the reference to a native command: " + name);
1455
+ }
1456
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AppBrigeService, deps: [{ token: i1.Router }, { token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1457
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AppBrigeService, providedIn: 'root' }); }
1458
+ }
1459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: AppBrigeService, decorators: [{
1460
+ type: Injectable,
1461
+ args: [{
1462
+ providedIn: 'root'
1463
+ }]
1464
+ }], ctorParameters: () => [{ type: i1.Router }, { type: i0.NgZone }, { type: undefined, decorators: [{
1465
+ type: Inject,
1466
+ args: [DOCUMENT]
1467
+ }] }] });
1468
+
1469
+ /**
1470
+ * @license
1471
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1472
+ *
1473
+ * Use of this source code is governed by an MIT-style license that can be ound in
1474
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1475
+ */
1476
+ /**
1477
+ * @private
1478
+ * Specifies the semantic versioning of an API.
1479
+ */
1480
+ class VersionImpl {
1481
+ /**
1482
+ * @private
1483
+ */
1484
+ constructor(major, minor, patch, buildTimeStamp) {
1485
+ this.major = major;
1486
+ this.minor = minor;
1487
+ this.patch = patch;
1488
+ this.buildTimeStamp = buildTimeStamp;
1489
+ }
1490
+ /**
1491
+ * Returns a string representation of this `Version` object in the form `M.m.p`, where
1492
+ * `M` represents the major number, `m` represents the minor number and `p` represents
1493
+ * the patch number of this `VersionImpl` instance.
1494
+ *
1495
+ * @returns A string representation of this `VersionImpl` instance.
1496
+ */
1497
+ toString() {
1498
+ return `${this.major}.${this.minor}.${this.patch}`;
1499
+ }
1500
+ }
1501
+ ;
1502
+
1503
+ /**
1504
+ * @license
1505
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1506
+ *
1507
+ * Use of this source code is governed by an MIT-style license that can be found in
1508
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1509
+ */
1510
+ /**
1511
+ * A lightweight service that provides Semantic Versioning implementation for your Angular projects.
1512
+ */
1513
+ class VersionService {
1514
+ /**
1515
+ * Creates a new VersionService instance.
1516
+ * @param config the reference to the VersionConfig provider.
1517
+ */
1518
+ constructor(config) {
1519
+ this._version = new VersionImpl(config.major, config.minor, config.patch, config.buildTimestamp);
1520
+ }
1521
+ /**
1522
+ * Returns the version of the associated Angular project.
1523
+ *
1524
+ * @return the version of the associated Angular project.
1525
+ */
1526
+ getVersion() {
1527
+ return this._version;
1528
+ }
1529
+ /**
1530
+ * Returns the build timestamp of the associated Angular project.
1531
+ *
1532
+ * @return the build timestamp of the associated Angular project.
1533
+ */
1534
+ getBuildTimestamp() {
1535
+ return this._version.buildTimeStamp;
1536
+ }
1537
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: VersionService, deps: [{ token: VERSION_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
1538
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: VersionService, providedIn: 'root' }); }
1539
+ }
1540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: VersionService, decorators: [{
1541
+ type: Injectable,
1542
+ args: [{
1543
+ providedIn: 'root'
1544
+ }]
1545
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1546
+ type: Inject,
1547
+ args: [VERSION_CONFIG]
1548
+ }] }] });
1549
+
1550
+ /**
1551
+ * @license
1552
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1553
+ *
1554
+ * Use of this source code is governed by an MIT-style license that can be found in
1555
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1556
+ */
1557
+ /**
1558
+ * @private
1559
+ * Provides the list of HTTP verbs.
1560
+ */
1561
+ var HTTPMethodRef;
1562
+ (function (HTTPMethodRef) {
1563
+ /**
1564
+ * @private
1565
+ * A reference to the `connect` route associated with the `CONNECT` HTTP verb.
1566
+ */
1567
+ HTTPMethodRef["CONNECT"] = "connect";
1568
+ /**
1569
+ * @private
1570
+ * A reference to the `delete` route associated with the `DELETE` HTTP verb.
1571
+ */
1572
+ HTTPMethodRef["DELETE"] = "delete";
1573
+ /**
1574
+ * @private
1575
+ * A reference to the `get` route associated with the `GET` HTTP verb.
1576
+ */
1577
+ HTTPMethodRef["GET"] = "get";
1578
+ /**
1579
+ * @private
1580
+ * A reference to the `head` route associated with the `HEAD` HTTP verb.
1581
+ */
1582
+ HTTPMethodRef["HEAD"] = "head";
1583
+ /**
1584
+ * @private
1585
+ * A reference to the `options` route associated with the `OPTIONS` HTTP verb.
1586
+ */
1587
+ HTTPMethodRef["OPTIONS"] = "options";
1588
+ /**
1589
+ * @private
1590
+ * A reference to the `patch` route associated with the `PATCH` HTTP verb.
1591
+ */
1592
+ HTTPMethodRef["PATCH"] = "patch";
1593
+ /**
1594
+ * @private
1595
+ * A reference to the `post` route associated with the `POST` HTTP verb.
1596
+ */
1597
+ HTTPMethodRef["POST"] = "post";
1598
+ /**
1599
+ * @private
1600
+ * A reference to the `put` route associated with the `PUT` HTTP verb.
1601
+ */
1602
+ HTTPMethodRef["PUT"] = "put";
1603
+ /**
1604
+ * @private
1605
+ * A reference to the `trace` route associated with the `TRACE` HTTP verb.
1606
+ */
1607
+ HTTPMethodRef["TRACE"] = "trace";
1608
+ })(HTTPMethodRef || (HTTPMethodRef = {}));
1609
+
1610
+ /**
1611
+ * @license
1612
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1613
+ *
1614
+ * Use of this source code is governed by an MIT-style license that can be found in
1615
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1616
+ */
1617
+ /**
1618
+ * @private
1619
+ * The reference to the default delimiter.
1620
+ * Value is `"/"`.
1621
+ */
1622
+ const DEFAULT_DELIMITER = "/";
1623
+ /**
1624
+ * @private
1625
+ * The reference to the case insensitive flag.
1626
+ * Value is `"i"`.
1627
+ */
1628
+ const I_FLAG = "i";
1629
+ /**
1630
+ * @private
1631
+ * The reference to the global flag.
1632
+ * Value is `"g"`.
1633
+ */
1634
+ const G_FLAG = "g";
1635
+ /**
1636
+ * @private
1637
+ * The reference to the `{` `TokenType`.
1638
+ */
1639
+ const LEFT_CURLY_BRACE = "{";
1640
+ /**
1641
+ * @private
1642
+ * The reference to the `}` `TokenType`.
1643
+ */
1644
+ const RIGHT_CURLY_BRACE = "}";
1645
+ /**
1646
+ * @private
1647
+ * The reference to the `*` `TokenType`.
1648
+ */
1649
+ const ASTERISK = "*";
1650
+ /**
1651
+ * @private
1652
+ * The reference to the `+` `TokenType`.
1653
+ */
1654
+ const PLUS = "+";
1655
+ /**
1656
+ * @private
1657
+ * The reference to the `?` `TokenType`.
1658
+ */
1659
+ const QUESTION_MARK = "?";
1660
+ /**
1661
+ * @private
1662
+ * The reference to the `NAME` `TokenType`.
1663
+ */
1664
+ const NAME = "NAME";
1665
+ /**
1666
+ * @private
1667
+ * The reference to the `PATTERN` `TokenType`.
1668
+ */
1669
+ const PATTERN = "PATTERN";
1670
+ /**
1671
+ * @private
1672
+ * The reference to the `CHAR` `TokenType`.
1673
+ */
1674
+ const CHAR = "CHAR";
1675
+ /**
1676
+ * @private
1677
+ * The reference to the `ESCAPED` `TokenType`.
1678
+ */
1679
+ const ESCAPED = "ESCAPED";
1680
+ /**
1681
+ * @private
1682
+ * The reference to the `END` `TokenType`.
1683
+ */
1684
+ const END = "END";
1685
+ /**
1686
+ * @private
1687
+ * The reference to the semi colon (`;`) character.
1688
+ */
1689
+ const SEMI_COLON = ";";
1690
+ /**
1691
+ * @private
1692
+ * The reference to the colon (`:`) character.
1693
+ */
1694
+ const COLON = ":";
1695
+ /**
1696
+ * @private
1697
+ * The reference to the left parenthesis (`(`) character.
1698
+ */
1699
+ const LEFT_PARENTHESIS = "(";
1700
+ /**
1701
+ * @private
1702
+ * The reference to the right parenthesis (`)`) character.
1703
+ */
1704
+ const RIGHT_PARENTHESIS = ")";
1705
+ /**
1706
+ * @private
1707
+ * The reference to the escaped back slash (`\\`) character.
1708
+ */
1709
+ const ESC_BACK_SLASH = "\\";
1710
+ /**
1711
+ * @private
1712
+ * The reference to the carret (`^`) character.
1713
+ */
1714
+ const CARRET = "^";
1715
+ /**
1716
+ * @private
1717
+ * The reference to the carret (`$`) character.
1718
+ */
1719
+ const DOLLAR = "$";
1720
+
1721
+ /**
1722
+ * @license
1723
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1724
+ *
1725
+ * Use of this source code is governed by an MIT-style license that can be ound in
1726
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1727
+ *
1728
+ * This source code is derived from the following original source code:
1729
+ * - https://github.com/pillarjs/path-to-regexp
1730
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1731
+ *
1732
+ * Use of the original source code is governed by an MIT-style license
1733
+ * that can be found in the LICENSE file at
1734
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1735
+ */
1736
+ /**
1737
+ * @private
1738
+ */
1739
+ const ESCAPE_REGEXP = /([.+*?=^!:${}()[\]|/\\])/g;
1740
+ /**
1741
+ * @private
1742
+ */
1743
+ const ESCAPE_VALUE = "\\$1";
1744
+ /**
1745
+ * @private
1746
+ * Escape a regular expression string.
1747
+ *
1748
+ * @param str The regular expression string to escape.
1749
+ * @returns An escaped a regular expression string.
1750
+ */
1751
+ const escapeRegexpString = (str) => {
1752
+ return str.replace(ESCAPE_REGEXP, ESCAPE_VALUE);
1753
+ };
1754
+
1755
+ /**
1756
+ * @license
1757
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1758
+ *
1759
+ * Use of this source code is governed by an MIT-style license that can be found in
1760
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1761
+ *
1762
+ * This source code is derived from the following original source code:
1763
+ * - https://github.com/pillarjs/path-to-regexp
1764
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1765
+ *
1766
+ * Use of the original source code is governed by an MIT-style license
1767
+ * that can be found in the LICENSE file at
1768
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1769
+ */
1770
+ /**
1771
+ * @private
1772
+ * Get the flags for a regexp from the spcified options.
1773
+ *
1774
+ * @param options The options used to determine the flags for a regexp.
1775
+ * @returns The flags for a regexp depending on the spcified options.
1776
+ */
1777
+ const getFlags = (options) => {
1778
+ return options.sensitive ? EMPTY_STRING : I_FLAG;
1779
+ };
1780
+
1781
+ /**
1782
+ * @license
1783
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1784
+ *
1785
+ * Use of this source code is governed by an MIT-style license that can be found in
1786
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1787
+ *
1788
+ * This source code is derived from the following original source code:
1789
+ * - https://github.com/pillarjs/path-to-regexp
1790
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1791
+ *
1792
+ * Use of the original source code is governed by an MIT-style license
1793
+ * that can be found in the LICENSE file at
1794
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1795
+ */
1796
+ /**
1797
+ * @private
1798
+ * Returns a function that converts a token into a regexp string.
1799
+ */
1800
+ const toKeyRegexp = (stringify, delimiter) => {
1801
+ const segmentPattern = `[^${escapeRegexpString(delimiter)}]+?`;
1802
+ return (key) => {
1803
+ const prefix = key.prefix ? stringify(key.prefix) : EMPTY_STRING;
1804
+ const suffix = key.suffix ? stringify(key.suffix) : EMPTY_STRING;
1805
+ const modifier = key.modifier || EMPTY_STRING;
1806
+ if (key.name) {
1807
+ const pattern = key.pattern || segmentPattern;
1808
+ if (key.modifier === PLUS || key.modifier === ASTERISK) {
1809
+ const mod = key.modifier === ASTERISK ? QUESTION_MARK : EMPTY_STRING;
1810
+ const split = key.separator ? stringify(key.separator) : EMPTY_STRING;
1811
+ return `(?:${prefix}((?:${pattern})(?:${split}(?:${pattern}))*)${suffix})${mod}`;
1812
+ }
1813
+ return `(?:${prefix}(${pattern})${suffix})${modifier}`;
1814
+ }
1815
+ return `(?:${prefix}${suffix})${modifier}`;
1816
+ };
1817
+ };
1818
+
1819
+ /**
1820
+ * @license
1821
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1822
+ *
1823
+ * Use of this source code is governed by an MIT-style license that can be found in
1824
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1825
+ *
1826
+ * This source code is derived from the following original source code:
1827
+ * - https://github.com/pillarjs/path-to-regexp
1828
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1829
+ *
1830
+ * Use of the original source code is governed by an MIT-style license
1831
+ * that can be found in the LICENSE file at
1832
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1833
+ */
1834
+ /**
1835
+ * @private
1836
+ * Escape and repeat loose characters for regular expressions.
1837
+ *
1838
+ * @param value The string expression to escape.
1839
+ * @param loose
1840
+ * @returns The escaped string transfromed from the original string expression.
1841
+ */
1842
+ const looseReplacer = (value, loose) => {
1843
+ return loose ? `${escapeRegexpString(value)}+` : escapeRegexpString(value);
1844
+ };
1845
+
1846
+ /**
1847
+ * @license
1848
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1849
+ *
1850
+ * Use of this source code is governed by an MIT-style license that can be found in
1851
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1852
+ *
1853
+ * This source code is derived from the following original source code:
1854
+ * - https://github.com/pillarjs/path-to-regexp
1855
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1856
+ *
1857
+ * Use of the original source code is governed by an MIT-style license
1858
+ * that can be found in the LICENSE file at
1859
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1860
+ */
1861
+ /**
1862
+ * @private
1863
+ * Encode all non-delimiter characters using the encode function.
1864
+ */
1865
+ const toStringify = (loose, delimiter) => {
1866
+ if (!loose)
1867
+ return escapeRegexpString;
1868
+ const re = new RegExp(`[^${escapeRegexpString(delimiter)}]+|(.)`, G_FLAG);
1869
+ return (value) => value.replace(re, looseReplacer);
1870
+ };
1871
+
1872
+ /**
1873
+ * @license
1874
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1875
+ *
1876
+ * Use of this source code is governed by an MIT-style license that can be found in
1877
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1878
+ *
1879
+ * This source code is derived from the following original source code:
1880
+ * - https://github.com/pillarjs/path-to-regexp
1881
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1882
+ *
1883
+ * Use of the original source code is governed by an MIT-style license
1884
+ * that can be found in the LICENSE file at
1885
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1886
+ */
1887
+ /**
1888
+ * @Private
1889
+ * Expose a function for taking tokens and returning a RegExp.
1890
+ */
1891
+ const tokenDataToRegexp = (data, keys, options) => {
1892
+ const { trailing = true, start = true, end = true, loose = true, } = options;
1893
+ const stringify = toStringify(loose, data.delimiter);
1894
+ const keyToRegexp = toKeyRegexp(stringify, data.delimiter);
1895
+ let pattern = start ? CARRET : EMPTY_STRING;
1896
+ for (const token of data.tokens) {
1897
+ if (typeof token === STRING) {
1898
+ pattern += stringify(token);
1899
+ }
1900
+ else {
1901
+ if (token.name)
1902
+ keys.push(token);
1903
+ pattern += keyToRegexp(token);
1904
+ }
1905
+ }
1906
+ if (trailing)
1907
+ pattern += `(?:${stringify(data.delimiter)})?`;
1908
+ pattern += end ? DOLLAR : `(?=${escapeRegexpString(data.delimiter)}|$)`;
1909
+ // URLs in general are case-sensitive (with the exception of machine names).
1910
+ // See https://www.w3.org/TR/WD-html40-970708/htmlweb.html
1911
+ // Note that default modifier is "i".
1912
+ return new RegExp(pattern, getFlags(options));
1913
+ };
1914
+
1915
+ /**
1916
+ * @license
1917
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1918
+ *
1919
+ * Use of this source code is governed by an MIT-style license that can be found in
1920
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1921
+ *
1922
+ * This source code is derived from the following original source code:
1923
+ * - https://github.com/pillarjs/path-to-regexp
1924
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1925
+ *
1926
+ * Use of the original source code is governed by an MIT-style license
1927
+ * that can be found in the LICENSE file at
1928
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1929
+ */
1930
+ /**
1931
+ * @private
1932
+ * Tokenized path instance.
1933
+ */
1934
+ class TokenData {
1935
+ /**
1936
+ * @private
1937
+ * Creates a new `TokenData` instance.
1938
+ *
1939
+ * @param tokens A list of `Token` objects.
1940
+ * @param delimiter the string delimiter for this `TokenData` instance.
1941
+ */
1942
+ constructor(tokens, delimiter) {
1943
+ this.tokens = tokens;
1944
+ this.delimiter = delimiter;
1945
+ }
1946
+ }
1947
+
1948
+ /**
1949
+ * @license
1950
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
1951
+ *
1952
+ * Use of this source code is governed by an MIT-style license that can be found in
1953
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
1954
+ *
1955
+ * This source code is derived from the following original source code:
1956
+ * - https://github.com/pillarjs/path-to-regexp
1957
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
1958
+ *
1959
+ * Use of the original source code is governed by an MIT-style license
1960
+ * that can be found in the LICENSE file at
1961
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
1962
+ */
1963
+ /**
1964
+ * @private
1965
+ */
1966
+ class Iter {
1967
+ /**
1968
+ * @private
1969
+ */
1970
+ constructor(_tokens) {
1971
+ this._tokens = _tokens;
1972
+ /**
1973
+ * @private
1974
+ */
1975
+ this._index = 0;
1976
+ }
1977
+ /**
1978
+ * @private
1979
+ */
1980
+ tryConsume(type) {
1981
+ const token = this.peek();
1982
+ if (token.type !== type)
1983
+ return;
1984
+ this._index++;
1985
+ return token.value;
1986
+ }
1987
+ /**
1988
+ * @private
1989
+ */
1990
+ consume(type) {
1991
+ const value = this.tryConsume(type);
1992
+ if (value !== undefined)
1993
+ return value;
1994
+ const { type: nextType, index } = this.peek();
1995
+ throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: https://git.new/pathToRegexpError`);
1996
+ }
1997
+ /**
1998
+ * @private
1999
+ */
2000
+ text() {
2001
+ let result = EMPTY_STRING;
2002
+ let value;
2003
+ while ((value = this.tryConsume(CHAR) || this.tryConsume(ESCAPED))) {
2004
+ result += value;
2005
+ }
2006
+ return result;
2007
+ }
2008
+ /**
2009
+ * @private
2010
+ */
2011
+ modifier() {
2012
+ return this.tryConsume(QUESTION_MARK) || this.tryConsume(ASTERISK) || this.tryConsume(PLUS) || EMPTY_STRING;
2013
+ }
2014
+ /**
2015
+ * @private
2016
+ */
2017
+ peek() {
2018
+ return this._tokens[this._index];
2019
+ }
2020
+ }
2021
+
2022
+ /**
2023
+ * @license
2024
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2025
+ *
2026
+ * Use of this source code is governed by an MIT-style license that can be found in
2027
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2028
+ *
2029
+ * This source code is derived from the following original source code:
2030
+ * - https://github.com/pillarjs/path-to-regexp
2031
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
2032
+ *
2033
+ * Use of the original source code is governed by an MIT-style license
2034
+ * that can be found in the LICENSE file at
2035
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
2036
+ */
2037
+ /**
2038
+ * @private
2039
+ * A markup interface for token types consumed by `Lexer` objects.
2040
+ */
2041
+ const SIMPLE_TOKENS = {
2042
+ "!": "!",
2043
+ "@": "@",
2044
+ ";": ";",
2045
+ "*": "*",
2046
+ "+": "+",
2047
+ "?": "?",
2048
+ "{": "{",
2049
+ "}": "}",
2050
+ };
2051
+
2052
+ /**
2053
+ * @license
2054
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2055
+ *
2056
+ * Use of this source code is governed by an MIT-style license that can be found in
2057
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2058
+ *
2059
+ * This source code is derived from the following original source code:
2060
+ * - https://github.com/pillarjs/path-to-regexp
2061
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
2062
+ *
2063
+ * Use of the original source code is governed by an MIT-style license
2064
+ * that can be found in the LICENSE file at
2065
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
2066
+ */
2067
+ /**
2068
+ * @private
2069
+ */
2070
+ const ID_CHAR = /^\p{XID_Continue}$/u;
2071
+ /**
2072
+ * @private
2073
+ * A lexer method that tokenizes input string.
2074
+ *
2075
+ * @param str The string expression to analyse.
2076
+ * @returns A new `Iter`object instance built from the specified input string.
2077
+ */
2078
+ const lexer = (str) => {
2079
+ const chars = [...str];
2080
+ const tokens = [];
2081
+ let i = 0;
2082
+ while (i < chars.length) {
2083
+ const value = chars[i];
2084
+ const type = SIMPLE_TOKENS[value];
2085
+ if (type) {
2086
+ tokens.push({ type, index: i++, value });
2087
+ continue;
2088
+ }
2089
+ if (value === ESC_BACK_SLASH) {
2090
+ tokens.push({ type: ESCAPED, index: i++, value: chars[i++] });
2091
+ continue;
2092
+ }
2093
+ if (value === COLON) {
2094
+ let name = EMPTY_STRING;
2095
+ while (ID_CHAR.test(chars[++i])) {
2096
+ name += chars[i];
2097
+ }
2098
+ if (!name) {
2099
+ throw new TypeError(`Missing parameter name at ${i}`);
2100
+ }
2101
+ tokens.push({ type: NAME, index: i, value: name });
2102
+ continue;
2103
+ }
2104
+ if (value === LEFT_PARENTHESIS) {
2105
+ const pos = i++;
2106
+ let count = 1;
2107
+ let pattern = EMPTY_STRING;
2108
+ if (chars[i] === QUESTION_MARK) {
2109
+ throw new TypeError(`Pattern cannot start with "?" at ${i}`);
2110
+ }
2111
+ while (i < chars.length) {
2112
+ if (chars[i] === ESC_BACK_SLASH) {
2113
+ pattern += chars[i++] + chars[i++];
2114
+ continue;
2115
+ }
2116
+ if (chars[i] === RIGHT_PARENTHESIS) {
2117
+ count--;
2118
+ if (count === 0) {
2119
+ i++;
2120
+ break;
2121
+ }
2122
+ }
2123
+ else if (chars[i] === LEFT_PARENTHESIS) {
2124
+ count++;
2125
+ if (chars[i + 1] !== QUESTION_MARK) {
2126
+ throw new TypeError(`Capturing groups are not allowed at ${i}`);
2127
+ }
2128
+ }
2129
+ pattern += chars[i++];
2130
+ }
2131
+ if (count)
2132
+ throw new TypeError(`Unbalanced pattern at ${pos}`);
2133
+ if (!pattern)
2134
+ throw new TypeError(`Missing pattern at ${pos}`);
2135
+ tokens.push({ type: PATTERN, index: i, value: pattern });
2136
+ continue;
2137
+ }
2138
+ tokens.push({ type: CHAR, index: i, value: chars[i++] });
2139
+ }
2140
+ tokens.push({ type: END, index: i, value: EMPTY_STRING });
2141
+ return new Iter(tokens);
2142
+ };
2143
+
2144
+ /**
2145
+ * @license
2146
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2147
+ *
2148
+ * Use of this source code is governed by an MIT-style license that can be found in
2149
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2150
+ *
2151
+ * This source code is derived from the following original source code:
2152
+ * - https://github.com/pillarjs/path-to-regexp
2153
+ * - Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
2154
+ *
2155
+ * Use of the original source code is governed by an MIT-style license
2156
+ * that can be found in the LICENSE file at
2157
+ * https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE
2158
+ */
2159
+ /**
2160
+ * @private
2161
+ * A NOOP `Endoder` function.
2162
+ * @param value The input string value.
2163
+ * @returns The input string value.
2164
+ */
2165
+ const NOOP_VALUE = (value) => value;
2166
+ /**
2167
+ * @private
2168
+ * Parse a string for the raw tokens.
2169
+ */
2170
+ const stringToTokenData = (str, options = {}) => {
2171
+ const { delimiter = DEFAULT_DELIMITER, encodePath = NOOP_VALUE, } = options;
2172
+ const tokens = [];
2173
+ const it = lexer(str);
2174
+ let keyIndex = 0;
2175
+ do {
2176
+ const path = it.text();
2177
+ if (path)
2178
+ tokens.push(encodePath(path));
2179
+ const name = it.tryConsume(NAME);
2180
+ const pattern = it.tryConsume(PATTERN);
2181
+ if (name || pattern) {
2182
+ tokens.push({
2183
+ name: name || String(keyIndex++),
2184
+ pattern,
2185
+ });
2186
+ const next = it.peek();
2187
+ if (next.type === ASTERISK) {
2188
+ throw new TypeError(`Unexpected * at ${next.index}, you probably want \`/*\` or \`{/:foo}*\`: https://git.new/pathToRegexpError`);
2189
+ }
2190
+ continue;
2191
+ }
2192
+ const asterisk = it.tryConsume(ASTERISK);
2193
+ if (asterisk) {
2194
+ tokens.push({
2195
+ name: String(keyIndex++),
2196
+ pattern: `[^${escape(delimiter)}]*`,
2197
+ modifier: ASTERISK,
2198
+ separator: delimiter,
2199
+ });
2200
+ continue;
2201
+ }
2202
+ const open = it.tryConsume(LEFT_CURLY_BRACE);
2203
+ if (open) {
2204
+ const prefix = it.text();
2205
+ const name = it.tryConsume(NAME);
2206
+ const pattern = it.tryConsume(PATTERN);
2207
+ const suffix = it.text();
2208
+ const separator = it.tryConsume(SEMI_COLON) ? it.text() : prefix + suffix;
2209
+ it.consume(RIGHT_CURLY_BRACE);
2210
+ const modifier = it.modifier();
2211
+ tokens.push({
2212
+ name: name || (pattern ? String(keyIndex++) : EMPTY_STRING),
2213
+ prefix: encodePath(prefix),
2214
+ suffix: encodePath(suffix),
2215
+ pattern,
2216
+ modifier,
2217
+ separator,
2218
+ });
2219
+ continue;
2220
+ }
2221
+ it.consume(END);
2222
+ break;
2223
+ } while (true);
2224
+ return new TokenData(tokens, delimiter);
2225
+ };
2226
+
2227
+ /**
2228
+ * @license
2229
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2230
+ *
2231
+ * Use of this source code is governed by an MIT-style license that can be found in
2232
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2233
+ */
2234
+ /**
2235
+ * @private
2236
+ * Reference to the original type for this class.
2237
+ */
2238
+ const HTTP_MOCK_SERVICE = "HttpMockService";
2239
+ /**
2240
+ * The `HttpMockService` class provides the API for managing HTTP mock configuration objects.
2241
+ */
2242
+ class HttpMockService {
2243
+ constructor() {
2244
+ /**
2245
+ * @private
2246
+ * Ensures that class type is still accessible after TypeScript compilation.
2247
+ */
2248
+ this.type = HTTP_MOCK_SERVICE;
2249
+ /**
2250
+ * @private
2251
+ * The list of IDs associated with each config object.
2252
+ */
2253
+ this._configIdList = [];
2254
+ /**
2255
+ * @private
2256
+ * Stores the complete collection of mocking behaviors for each registered config.
2257
+ */
2258
+ this._configList = new Map();
2259
+ /**
2260
+ * @private
2261
+ * The reference to the current app URL origin.
2262
+ */
2263
+ this.APP_ORIGIN = window.location.origin;
2264
+ }
2265
+ /**
2266
+ * Adds the specified `HttpMockConfig` object to this `HttpMockService` instance.
2267
+ *
2268
+ * @param config The `HttpMockConfig` object to add to this `HttpMockService` instance.
2269
+ * @Returns The `Uuid` instance associated with the added `HttpMockConfig` object.
2270
+ */
2271
+ addConfig(config) {
2272
+ const origin = config.origin || this.APP_ORIGIN;
2273
+ this.checkOrigin(origin);
2274
+ let id = config.id;
2275
+ if (!id) {
2276
+ id = Uuid.build();
2277
+ config.id = id;
2278
+ }
2279
+ else {
2280
+ if (this.hasRegisteredConfig(id))
2281
+ throw new HttpMockServiceError(`A config object has already been registered with the id: ["${id.toString()}"].`);
2282
+ }
2283
+ this._configIdList.push(id);
2284
+ const uuid = id.toString();
2285
+ config.interceptors.forEach((interceptor) => this.extractConfig(interceptor, origin, uuid));
2286
+ return id;
2287
+ }
2288
+ /**
2289
+ * Returns the current app URL origin.
2290
+ *
2291
+ * @returns A string that represents the current app URL origin.
2292
+ */
2293
+ getAppOrigin() {
2294
+ return this.APP_ORIGIN;
2295
+ }
2296
+ /**
2297
+ * Removes the configuration registered with the specified `uuid` from this `HttpMockService` instance.
2298
+ *
2299
+ * @param uuid The UUID of the configuration to remove.
2300
+ */
2301
+ removeConfig(uuid) {
2302
+ if (!this.hasRegisteredConfig(uuid))
2303
+ return;
2304
+ const configId = uuid.toString();
2305
+ this._configList.forEach((value, key) => {
2306
+ this.deleteConfigById(value, configId);
2307
+ if (value.size === 0)
2308
+ this._configList.delete(key);
2309
+ });
2310
+ this._configIdList.splice(this._configIdList.indexOf(uuid), 1);
2311
+ }
2312
+ /**
2313
+ * Removes all registred configurations from this `HttpMockService` instance.
2314
+ */
2315
+ clearConfigs() {
2316
+ this._configList.clear();
2317
+ this._configIdList.length = 0;
2318
+ }
2319
+ /**
2320
+ * Returns a boolean value that indicates whether a config with the specified UUID has been registered
2321
+ * (`true`), or not (`false`).
2322
+ *
2323
+ * @param uuid The UUID of the config to check.
2324
+ * @returns `true` whether a config with the specified UUID has been registered; `false` otherwise.
2325
+ */
2326
+ hasRegisteredConfig(uuid) {
2327
+ return this._configIdList.indexOf(uuid) !== -1;
2328
+ }
2329
+ /**
2330
+ * Returns the `RouteMockConfig` object associated with the specified `URL` instance and HTTP method.
2331
+ *
2332
+ * @param url The `URL` instance for which to find a route config.
2333
+ * @param method The HTTP method for which to find a route config.
2334
+ * @returns The `RouteMockConfig` object associated with the specified `URL` instance and HTTP method whether it exists;
2335
+ * `undefined` otherwise.
2336
+ */
2337
+ getRouteConfig(url, method) {
2338
+ const urlConfigList = this._configList.get(url.origin);
2339
+ const route = url.pathname;
2340
+ let result = undefined;
2341
+ if (!urlConfigList)
2342
+ return result;
2343
+ const methodList = urlConfigList.get(method);
2344
+ if (!methodList)
2345
+ return result;
2346
+ let len = methodList.length - 1;
2347
+ while (len >= 0) {
2348
+ const methodMap = methodList[len];
2349
+ const regexp = methodMap.regexp;
2350
+ if (regexp.test(route)) {
2351
+ result = {
2352
+ methodConfig: methodMap.methodMock,
2353
+ parameters: this.buildParameters(regexp, methodMap.keys, route)
2354
+ };
2355
+ break;
2356
+ }
2357
+ len--;
2358
+ }
2359
+ return result;
2360
+ }
2361
+ /**
2362
+ * @rivate
2363
+ */
2364
+ buildParameters(regexp, keys, route) {
2365
+ const execResult = regexp.exec(route);
2366
+ if (!execResult)
2367
+ return null;
2368
+ const params = {};
2369
+ let len = execResult.length - 1;
2370
+ let i = 1;
2371
+ for (; i <= len; ++i) {
2372
+ const key = keys[i - 1];
2373
+ params[key.name] = execResult[i];
2374
+ }
2375
+ return params;
2376
+ }
2377
+ /**
2378
+ * @rivate
2379
+ */
2380
+ extractConfig(interceptor, globalOrigin, configId) {
2381
+ const endpoints = interceptor.endpoints;
2382
+ let origin = interceptor.origin;
2383
+ if (origin)
2384
+ this.checkOrigin(origin);
2385
+ else
2386
+ origin = globalOrigin;
2387
+ if (!this._configList.has(origin))
2388
+ this._configList.set(origin, new Map());
2389
+ endpoints.forEach((endpoint) => {
2390
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.GET, configId);
2391
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.POST, configId);
2392
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.PUT, configId);
2393
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.DELETE, configId);
2394
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.HEAD, configId);
2395
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.OPTIONS, configId);
2396
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.PATCH, configId);
2397
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.CONNECT, configId);
2398
+ this.extractEndpointConfig(origin, endpoint, HTTPMethodRef.TRACE, configId);
2399
+ });
2400
+ }
2401
+ /**
2402
+ * @rivate
2403
+ */
2404
+ extractEndpointConfig(origin, endpoint, method, configId) {
2405
+ const ep = endpoint;
2406
+ if (!ep[method])
2407
+ return;
2408
+ const originConfig = this._configList.get(origin);
2409
+ const route = endpoint.route;
2410
+ const data = stringToTokenData(route);
2411
+ const keys = [];
2412
+ const regexp = tokenDataToRegexp(data, keys, {});
2413
+ if (!originConfig.has(method))
2414
+ originConfig.set(method, []);
2415
+ const methodConfig = originConfig.get(method);
2416
+ methodConfig.push({
2417
+ regexp: regexp,
2418
+ keys: keys,
2419
+ methodMock: ep[method],
2420
+ configId: configId
2421
+ });
2422
+ }
2423
+ /**
2424
+ * @rivate
2425
+ */
2426
+ checkOrigin(origin) {
2427
+ if (origin.endsWith(DEFAULT_DELIMITER))
2428
+ throw new SyntaxError(`Origin must not end with a / character: ["${origin}"].`);
2429
+ }
2430
+ /**
2431
+ * @rivate
2432
+ */
2433
+ deleteConfigById(storageMap, configId) {
2434
+ storageMap.forEach((storage, key) => {
2435
+ const cleanedConfig = this.cleanConfig(storage, configId);
2436
+ if (cleanedConfig.length)
2437
+ storageMap.set(key, cleanedConfig);
2438
+ else
2439
+ storageMap.delete(key);
2440
+ });
2441
+ }
2442
+ /**
2443
+ * @rivate
2444
+ */
2445
+ cleanConfig(storage, configId) {
2446
+ return storage.filter((value) => value.configId !== configId);
2447
+ }
2448
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: HttpMockService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2449
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: HttpMockService, providedIn: 'root' }); }
2450
+ }
2451
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: HttpMockService, decorators: [{
2452
+ type: Injectable,
2453
+ args: [{
2454
+ providedIn: 'root'
2455
+ }]
2456
+ }] });
2457
+
2458
+ /**
2459
+ * @license
2460
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2461
+ *
2462
+ * Use of this source code is governed by an MIT-style license that can be found in
2463
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2464
+ */
2465
+ /**
2466
+ * The definition function for the `@HttpMock` decorator.
2467
+ *
2468
+ * @param config The `HttpMockConfig` object used to initialize the HTTP Mocking Framework.
2469
+ */
2470
+ const HttpMock = (config) => {
2471
+ return (constructor) => {
2472
+ const getMockService = (instance) => {
2473
+ return Object.values(instance).find((v) => {
2474
+ return (v.hasOwnProperty('type') && v.type === HTTP_MOCK_SERVICE);
2475
+ });
2476
+ };
2477
+ const ngOnInit = constructor.prototype.ngOnInit;
2478
+ const ngOnDestroy = constructor.prototype.ngOnDestroy;
2479
+ const uiid = config.id || Uuid.build();
2480
+ if (!ngOnDestroy)
2481
+ throw new ReferenceError("Component must implement the OnDestroy interface.");
2482
+ if (!ngOnInit)
2483
+ throw new ReferenceError("Component must implement the OnInit interface.");
2484
+ if (!config.id)
2485
+ config.id = uiid;
2486
+ constructor.prototype.ngOnInit = function () {
2487
+ const mockService = getMockService(this);
2488
+ if (!mockService)
2489
+ throw new ReferenceError("No provider found for HttpMockService.");
2490
+ mockService.addConfig(config);
2491
+ ngOnInit.call(this);
2492
+ };
2493
+ constructor.prototype.ngOnDestroy = function () {
2494
+ const mockService = getMockService(this);
2495
+ // An exception is already thrown by the ngOnInit() method when HttpMockService is not provided.
2496
+ // Following check statement prevents failure during Unit Testing:
2497
+ if (mockService)
2498
+ mockService.removeConfig(uiid);
2499
+ ngOnDestroy.call(this);
2500
+ };
2501
+ };
2502
+ };
2503
+
2504
+ /**
2505
+ * @license
2506
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2507
+ *
2508
+ * Use of this source code is governed by an MIT-style license that can be found in
2509
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2510
+ */
2511
+ /**
2512
+ * @private
2513
+ */
2514
+ const OK = "OK";
2515
+ /**
2516
+ * A statefull builder for creating new `HttpResponseMock` instances.
2517
+ */
2518
+ class HttpResponseMockBuilder {
2519
+ constructor() {
2520
+ /**
2521
+ * @private
2522
+ */
2523
+ this._response = {
2524
+ url: null,
2525
+ body: null,
2526
+ status: HttpStatusCode.Ok,
2527
+ statusText: OK,
2528
+ error: null,
2529
+ delay: 0
2530
+ };
2531
+ }
2532
+ /**
2533
+ * Sets the body property of the new `HttpResponseMock` instance with the specified `body` value.
2534
+ *
2535
+ * @param body The value used to set the body property of the new `HttpResponseMock` instance.
2536
+ *
2537
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2538
+ */
2539
+ body(body) {
2540
+ this._response.body = body;
2541
+ return this;
2542
+ }
2543
+ /**
2544
+ * Sets the headers property of the new `HttpResponseMock` instance with the specified `headers` value.
2545
+ *
2546
+ * @param headers The value used to set the `headers` property of the new `HttpResponseMock` instance.
2547
+ *
2548
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2549
+ */
2550
+ headers(headers) {
2551
+ this._response.headers = headers;
2552
+ return this;
2553
+ }
2554
+ /**
2555
+ * Sets the `status` property of the new `HttpResponseMock` instance with the specified `status` value.
2556
+ *
2557
+ * @param status The value used to set the `status` property of the new `HttpResponseMock` instance.
2558
+ *
2559
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2560
+ */
2561
+ status(status) {
2562
+ this._response.status = status;
2563
+ return this;
2564
+ }
2565
+ /**
2566
+ * Sets the `statusText` property of the new `HttpResponseMock` instance with the specified `statusText` value.
2567
+ *
2568
+ * @param statusText The value used to set the `statusText` property of the new `HttpResponseMock` instance.
2569
+ *
2570
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2571
+ */
2572
+ statusText(statusText) {
2573
+ this._response.statusText = statusText;
2574
+ return this;
2575
+ }
2576
+ /**
2577
+ * Sets the `url` property of the new `HttpResponseMock` instance with the specified `url` value.
2578
+ *
2579
+ * @param url The value used to set the `url` property of the new `HttpResponseMock` instance.
2580
+ *
2581
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2582
+ */
2583
+ url(url) {
2584
+ this._response.url = url;
2585
+ return this;
2586
+ }
2587
+ /**
2588
+ * Sets the `delay` property of the new `HttpResponseMock` instance with the specified `timer` duration.
2589
+ * Maximum value is `10000` miliseconds (10 seconds).
2590
+ *
2591
+ * @param timer The value used to set the `delay` property of the new `HttpResponseMock` instance.
2592
+ *
2593
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2594
+ */
2595
+ delay(timer = 0) {
2596
+ this._response.delay = timer;
2597
+ return this;
2598
+ }
2599
+ /**
2600
+ * Returns a new `HttpResponseMock` instance, built from the properties specified with the
2601
+ * `HttpResponseMockBuilder` methods.
2602
+ *
2603
+ * @param error An optional value used to set the `error` property of the new `HttpResponseMock` instance.
2604
+ * The `error` parameter values take precedence over all other properties of the `HttpResponseMock`
2605
+ * instance.
2606
+ * @returns A new `HttpResponseMock` instance.
2607
+ */
2608
+ response(error = null) {
2609
+ this._response.error = error;
2610
+ return this._response;
2611
+ }
2612
+ }
2613
+ /**
2614
+ * A utility function used to create new "chainable" `HttpResponseMockBuilder` instances.
2615
+ *
2616
+ * @returns A new `HttpResponseMockBuilder` instance.
2617
+ */
2618
+ const httpResponseMock = () => new HttpResponseMockBuilder();
2619
+
2620
+ /**
2621
+ * @license
2622
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2623
+ *
2624
+ * Use of this source code is governed by an MIT-style license that can be found in
2625
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2626
+ */
2627
+ /**
2628
+ * A statefull builder for creating new `HttpHeaders` instances.
2629
+ */
2630
+ class HttpHeadersMockBuilder {
2631
+ constructor() {
2632
+ /**
2633
+ * @private
2634
+ */
2635
+ this._headers = new HttpHeaders();
2636
+ }
2637
+ /**
2638
+ * Sets the `"Cache-Control"` property of the new `HttpHeaders` instance with the specified value.
2639
+ *
2640
+ * @param value The value used to set the `"Cache-Control"` property of the new `HttpHeaders` instance.
2641
+ * Default value is `"no-cache"`.
2642
+ *
2643
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2644
+ */
2645
+ cacheControl(value = "no-cache") {
2646
+ this.setHeader("Cache-Control", value);
2647
+ return this;
2648
+ }
2649
+ /**
2650
+ * Sets the `"CContent-Type"` property of the new `HttpHeaders` instance with the specified value.
2651
+ *
2652
+ * @param value The value used to set the `"Content-Type"` property of the new `HttpHeaders` instance.
2653
+ * Default value is `"application/json; charset=utf-8"`.
2654
+ *
2655
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2656
+ */
2657
+ contentType(value = "application/json; charset=utf-8") {
2658
+ this.setHeader("Content-Type", value);
2659
+ return this;
2660
+ }
2661
+ /**
2662
+ * Sets the `"Priority"` property of the new `HttpHeaders` instance with the specified value.
2663
+ *
2664
+ * @param value The value used to set the `"Priority"` property of the new `HttpHeaders` instance.
2665
+ * Default value is `"u=0, i"`.
2666
+ *
2667
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2668
+ */
2669
+ priority(value = "u=0, i") {
2670
+ this.setHeader("Priority", value);
2671
+ return this;
2672
+ }
2673
+ /**
2674
+ * Sets the `"User-Agent"` property of the new `HttpHeaders` instance with the specified value.
2675
+ *
2676
+ * @param value The value used to set the `"User-Agent"` property of the new `HttpHeaders` instance.
2677
+ * Default value is the navigator user agent.
2678
+ *
2679
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2680
+ */
2681
+ userAgent(value = null) {
2682
+ this.setHeader("User-Agent", value || navigator.userAgent);
2683
+ return this;
2684
+ }
2685
+ /**
2686
+ * Sets the `"Accept-Language"` property of the new `HttpHeaders` instance with the specified value.
2687
+ *
2688
+ * @param value The value used to set the `"Accept-Language"` property of the new `HttpHeaders` instance.
2689
+ * Default value is the navigator language.
2690
+ *
2691
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2692
+ */
2693
+ acceptLanguage(value = null) {
2694
+ this.setHeader("Accept-Language", value || navigator.language);
2695
+ return this;
2696
+ }
2697
+ /**
2698
+ * Sets the `"Accept"` property of the new `HttpHeaders` instance with the specified value.
2699
+ *
2700
+ * @param value The value used to set the `"Accept"` property of the new `HttpHeaders` instance.
2701
+ * Default value is `'*\/*'`.
2702
+ *
2703
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2704
+ */
2705
+ accept(value = "*/*") {
2706
+ this.setHeader("Accept", value);
2707
+ return this;
2708
+ }
2709
+ /**
2710
+ * Sets the `"Accept-Encoding"` property of the new `HttpHeaders` instance with the specified value.
2711
+ *
2712
+ * @param value The value used to set the `"Accept-Encoding"` property of the new `HttpHeaders` instance.
2713
+ * Default value is `"ngzip, deflate, br, zstd"`.
2714
+ *
2715
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2716
+ */
2717
+ acceptEncoding(value = "gzip, deflate, br, zstd") {
2718
+ this.setHeader("Accept-Encoding", value);
2719
+ return this;
2720
+ }
2721
+ /**
2722
+ * Sets or modifies a value of the new `HttpHeaders` instance.
2723
+ *
2724
+ * @param name The header name.
2725
+ * @param value The value or values to set or override for the given header.
2726
+ *
2727
+ * @returns A reference to this `HttpResponseMockBuilder` instance.
2728
+ */
2729
+ set(name, value) {
2730
+ this.setHeader(name, value);
2731
+ return this;
2732
+ }
2733
+ /**
2734
+ * Return a new `HttpHeaders` instance, built from the properties specified with the
2735
+ * `HttpHeadersMockBuilder` methods.
2736
+ *
2737
+ * @returns A new `HttpHeaders` instance.
2738
+ */
2739
+ headers() {
2740
+ return this._headers;
2741
+ }
2742
+ /**
2743
+ * @private
2744
+ */
2745
+ setHeader(name, value) {
2746
+ const values = Array.isArray(value) ? value.join(", ") : value;
2747
+ this._headers = this._headers.set(name, values);
2748
+ }
2749
+ }
2750
+ /**
2751
+ * A utility function used to create new "chainable" `HttpHeadersMockBuilder` instances.
2752
+ *
2753
+ * @returns A new `HttpHeadersMockBuilder` instance;
2754
+ */
2755
+ const httpHeadersMock = () => new HttpHeadersMockBuilder();
2756
+
2757
+ /**
2758
+ * @license
2759
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2760
+ *
2761
+ * Use of this source code is governed by an MIT-style license that can be found in
2762
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2763
+ */
2764
+ /**
2765
+ * @private
2766
+ * A utility class used by delegate `XhrProxy` instances to dispatch `ProgressEvent`
2767
+ * instances.
2768
+ *
2769
+ * This class is not exposed.
2770
+ */
2771
+ class ProgressEventMock extends ProgressEvent {
2772
+ constructor() {
2773
+ super(...arguments);
2774
+ /**
2775
+ * @private
2776
+ */
2777
+ this._total = NaN;
2778
+ /**
2779
+ * @private
2780
+ */
2781
+ this._loaded = 0;
2782
+ }
2783
+ /**
2784
+ * A 64-bit unsigned integer indicating the size, in bytes, of the data already
2785
+ * transmitted or processed.
2786
+ */
2787
+ set total(value) {
2788
+ this._total = value;
2789
+ }
2790
+ get total() {
2791
+ return this._total;
2792
+ }
2793
+ /**
2794
+ * A 64-bit unsigned integer indicating the total size, in bytes, of the data being
2795
+ * transmitted or processed.
2796
+ */
2797
+ set loaded(value) {
2798
+ this._loaded = value;
2799
+ }
2800
+ get loaded() {
2801
+ return this._loaded;
2802
+ }
2803
+ }
2804
+
2805
+ /**
2806
+ * @license
2807
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2808
+ *
2809
+ * Use of this source code is governed by an MIT-style license that can be found in
2810
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2811
+ *
2812
+ * This source code is derived from the following original source code:
2813
+ * - https://github.com/benlesh/event-target-polyfill
2814
+ * - Copyright (c) 2020 Ben Lesh
2815
+ *
2816
+ * Use of the original source code is governed by an MIT-style license
2817
+ * that can be found in the LICENSE file at
2818
+ * https://github.com/benlesh/event-target-polyfill/blob/master/LICENSE
2819
+ */
2820
+ /**
2821
+ * @private
2822
+ */
2823
+ const ADD = "addEventListener";
2824
+ /**
2825
+ * @private
2826
+ */
2827
+ const REMOVE = "removeEventListener";
2828
+ /**
2829
+ * @private
2830
+ * A utility class the provides an implementation for the `EventTarget` interface.
2831
+ * This class is used internally by the framework; please do not expose it.
2832
+ *
2833
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
2834
+ */
2835
+ class EventTargetImpl {
2836
+ /**
2837
+ * @private
2838
+ */
2839
+ constructor() {
2840
+ this._listenerList = new Map();
2841
+ }
2842
+ /**
2843
+ * @private
2844
+ * Sets up a function that will be called whenever the specified event is delivered to the target.
2845
+ *
2846
+ * @param type a case-sensitive string representing the event type to listen for.
2847
+ * @param listener the object that receives a notification (an object that implements the
2848
+ * `Event` interface) when an event of the specified type occurs.
2849
+ * @param options an object that specifies characteristics about the event listener.
2850
+ *
2851
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
2852
+ */
2853
+ addEventListener(type, listener, options) {
2854
+ this.checkArgLength(arguments.length, ADD);
2855
+ const ll = this._listenerList;
2856
+ if (!ll.has(type))
2857
+ ll.set(type, new Map());
2858
+ const listenersForType = ll.get(type);
2859
+ if (!listenersForType.has(listener)) {
2860
+ // Any given listener is only registered once
2861
+ listenersForType.set(listener, options);
2862
+ }
2863
+ }
2864
+ /**
2865
+ * @private
2866
+ * Removes an event listener previously registered with `EventTarget.addEventListener()` from the target.
2867
+ *
2868
+ * @param type a case-sensitive which specifies the type of event for which to remove an event listener.
2869
+ * @param listener the event listener function of the event handler to remove from the event target.
2870
+ * @param options An options object that specifies characteristics about the event listener.
2871
+ *
2872
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
2873
+ */
2874
+ removeEventListener(type, listener, options) {
2875
+ this.checkArgLength(arguments.length, REMOVE);
2876
+ const ll = this._listenerList;
2877
+ if (ll.has(type)) {
2878
+ const listenersForType = ll.get(type);
2879
+ if (listenersForType.has(listener))
2880
+ listenersForType.delete(listener);
2881
+ }
2882
+ }
2883
+ /**
2884
+ * @private
2885
+ * Sends an `Event` to this to the `Event` object, (synchronously) invoking the affected event listeners
2886
+ * in the appropriate order.
2887
+ *
2888
+ * @param event the `Event object to dispatch. Its Event.target property will be set to the current EventTarget.
2889
+ * @returns true since there are no cancellable events on a base `EventTarget`.
2890
+ *
2891
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
2892
+ */
2893
+ dispatchEvent(event) {
2894
+ if (!(event instanceof Event)) {
2895
+ throw new TypeError("Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.");
2896
+ }
2897
+ const type = event.type;
2898
+ const ll = this._listenerList;
2899
+ const listenersForType = ll.get(type);
2900
+ if (!listenersForType)
2901
+ return true;
2902
+ for (const listnerEntry of listenersForType.entries()) {
2903
+ const listener = listnerEntry[0];
2904
+ const options = listnerEntry[1];
2905
+ // Listener functions must be executed with the EventTarget as the `this` context.
2906
+ if (typeof listener === FUNCTION)
2907
+ listener.call(this, event);
2908
+ // Listener objects have their handleEvent method called, if they have one
2909
+ else if (listener && typeof listener.handleEvent === FUNCTION)
2910
+ listener.handleEvent(event);
2911
+ if (options && options.once)
2912
+ listenersForType.delete(listener);
2913
+ }
2914
+ return true;
2915
+ }
2916
+ /**
2917
+ * @private
2918
+ */
2919
+ checkArgLength(argLen, method) {
2920
+ if (argLen < 2) {
2921
+ throw new TypeError(`TypeError: Failed to execute '${method}' on 'EventTarget': 2 arguments required, but ${argLen === 1 ? 'only 1' : '0'} present.`);
2922
+ }
2923
+ }
2924
+ }
2925
+
2926
+ /**
2927
+ * @license
2928
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
2929
+ *
2930
+ * Use of this source code is governed by an MIT-style license that can be found in
2931
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
2932
+ */
2933
+ /**
2934
+ * @private
2935
+ *
2936
+ * Elemenets marked as "Useless" are never invoked by the Angular framework.
2937
+ */
2938
+ class XhrBase extends EventTargetImpl {
2939
+ constructor() {
2940
+ super(...arguments);
2941
+ /**
2942
+ * @private
2943
+ *
2944
+ * XMLHTTPRequest API
2945
+ */
2946
+ this.UNSENT = 0;
2947
+ /**
2948
+ * @private
2949
+ *
2950
+ * XMLHTTPRequest API
2951
+ */
2952
+ this.OPENED = 1;
2953
+ /**
2954
+ * @private
2955
+ *
2956
+ * XMLHTTPRequest API
2957
+ */
2958
+ this.HEADERS_RECEIVED = 2;
2959
+ /**
2960
+ * @private
2961
+ *
2962
+ * XMLHTTPRequest API
2963
+ */
2964
+ this.LOADING = 3;
2965
+ /**
2966
+ * @private
2967
+ *
2968
+ * XMLHTTPRequest API
2969
+ */
2970
+ this.DONE = 4;
2971
+ /**
2972
+ * @private
2973
+ *
2974
+ * XMLHTTPRequest API
2975
+ */
2976
+ this.withCredentials = false;
2977
+ /**
2978
+ * @private
2979
+ *
2980
+ * XMLHTTPRequest API - Useless
2981
+ */
2982
+ this.onabort = null;
2983
+ /**
2984
+ * @private
2985
+ *
2986
+ * XMLHTTPRequest API - Useless
2987
+ */
2988
+ this.onerror = null;
2989
+ /**
2990
+ * @private
2991
+ *
2992
+ * XMLHTTPRequest API - Useless
2993
+ */
2994
+ this.onload = null;
2995
+ /**
2996
+ * @private
2997
+ *
2998
+ * XMLHTTPRequest API - Useless
2999
+ */
3000
+ this.onloadend = null;
3001
+ /**
3002
+ * @private
3003
+ *
3004
+ * XMLHTTPRequest API - Useless
3005
+ */
3006
+ this.onloadstart = null;
3007
+ /**
3008
+ * @private
3009
+ *
3010
+ * XMLHTTPRequest API - Useless
3011
+ */
3012
+ this.onprogress = null;
3013
+ /**
3014
+ * @private
3015
+ *
3016
+ * XMLHTTPRequest API - Useless
3017
+ */
3018
+ this.onreadystatechange = null;
3019
+ /**
3020
+ * @private
3021
+ *
3022
+ * XMLHTTPRequest API - Useless
3023
+ */
3024
+ this.ontimeout = null;
3025
+ }
3026
+ /**
3027
+ * @private
3028
+ *
3029
+ * XMLHTTPRequest API - Useless
3030
+ */
3031
+ get responseXML() {
3032
+ return null;
3033
+ }
3034
+ /**
3035
+ * @private
3036
+ *
3037
+ * XMLHTTPRequest API - Useless
3038
+ */
3039
+ overrideMimeType(mime) { }
3040
+ /**
3041
+ * @private
3042
+ *
3043
+ * XMLHTTPRequest API - Useless
3044
+ */
3045
+ getResponseHeader(name) { return null; }
3046
+ }
3047
+
3048
+ /**
3049
+ * @license
3050
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3051
+ *
3052
+ * Use of this source code is governed by an MIT-style license that can be found in
3053
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3054
+ */
3055
+ /**
3056
+ * @private
3057
+ * Internal reference to a new line character.
3058
+ */
3059
+ const NL = "\n";
3060
+ /**
3061
+ * @private
3062
+ * A set of static utilities for manipulating `HttpHeaders` objects.
3063
+ */
3064
+ class HttpHeadersUtil {
3065
+ /**
3066
+ * @private
3067
+ * Returns a string representation the the specified `HttpHeaders `object, compatible with the format
3068
+ * expected by the `XMLHttpRequest.getAllResponseHeaders()` method.
3069
+ *
3070
+ * @param headers The `HttpHeaders` object to format.
3071
+ *
3072
+ * @returns A string compatible with the format expected by the `XMLHttpRequest.getAllResponseHeaders()` method.
3073
+ */
3074
+ static stringify(headers) {
3075
+ let result = EMPTY_STRING;
3076
+ if (!headers)
3077
+ return result;
3078
+ const keys = headers.keys();
3079
+ const last = keys.length - 1;
3080
+ keys.forEach((key, index) => {
3081
+ result += `${key}: ${headers.getAll(key)}${index !== last ? NL : EMPTY_STRING}`;
3082
+ });
3083
+ return result;
3084
+ }
3085
+ /**
3086
+ * @private
3087
+ * Creates the default `HttpHeaders` object for a mocked HTTP request.
3088
+ *
3089
+ * @returns The default `HttpHeaders` object for a mocked HTTP request.
3090
+ */
3091
+ static createDefaultRequestHeaders() {
3092
+ // "Accept" header is set by Angular framework when missing
3093
+ return httpHeadersMock().cacheControl()
3094
+ .acceptEncoding()
3095
+ .acceptLanguage()
3096
+ .priority()
3097
+ .userAgent()
3098
+ .headers();
3099
+ }
3100
+ }
3101
+
3102
+ /**
3103
+ * @license
3104
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3105
+ *
3106
+ * Use of this source code is governed by an MIT-style license that can be found in
3107
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3108
+ */
3109
+ /**
3110
+ * @private
3111
+ * A static utility class for building `DataStorage` objects.
3112
+ */
3113
+ class DataStorageBuilder {
3114
+ /**
3115
+ * @private
3116
+ * Builds and returns a new `DataStorage` objects.
3117
+ *
3118
+ * @param httpResponse The `HttpResponseMock` to be stored by the framework.
3119
+ * @param data The data of the HTTP response to be stored by the framework.
3120
+ *
3121
+ * @returns A new `DataStorage` objects.
3122
+ */
3123
+ static buildDataStorage(httpResponse, data) {
3124
+ // TODO: add support for different data types (string, Blob, etc.)
3125
+ const stringifiedData = data ? JSON.stringify(data) : EMPTY_STRING;
3126
+ return {
3127
+ httpResponse: httpResponse,
3128
+ loaded: 0,
3129
+ total: data ? new Blob([stringifiedData]).size : 0,
3130
+ data: data,
3131
+ stringifiedData: stringifiedData
3132
+ };
3133
+ }
3134
+ }
3135
+
3136
+ /**
3137
+ * @license
3138
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3139
+ *
3140
+ * Use of this source code is governed by an MIT-style license that can be found in
3141
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3142
+ */
3143
+ /**
3144
+ * @private
3145
+ * The maximum value for a delayed HTTP response.
3146
+ */
3147
+ const MAX_TIMER = 10000;
3148
+ /**
3149
+ * @private
3150
+ * Intenal "onreadystatechange" event.
3151
+ */
3152
+ const READY_STATE_CHANGE_EVENT = new Event("onreadystatechange");
3153
+ /**
3154
+ * @private
3155
+ */
3156
+ const EVT_PROPS_CONFIG = { writable: false, value: this };
3157
+ /**
3158
+ * @private
3159
+ * A utility class used as delegate of `XMLHttpRequest` functionalities when
3160
+ * a HTTP request is intercepted by the Mocking Framework .
3161
+ */
3162
+ class DelegateXhr extends XhrBase {
3163
+ /**
3164
+ * Returns the response body content.
3165
+ *
3166
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/response
3167
+ */
3168
+ get response() {
3169
+ return this._dataStorage?.data || null;
3170
+ }
3171
+ /**
3172
+ * Returns the numerical HTTP status code of the `XMLHttpRequest` response.
3173
+ *
3174
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/status
3175
+ */
3176
+ get status() {
3177
+ return this._status;
3178
+ }
3179
+ /**
3180
+ * Returns a string containing the response status message as returned by the HTTP server.
3181
+ *
3182
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/statusText
3183
+ */
3184
+ get statusText() {
3185
+ return this._statusText;
3186
+ }
3187
+ /**
3188
+ * Returns the state the `XMLHttpRequest` client is in.
3189
+ *
3190
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/readyState
3191
+ */
3192
+ get readyState() {
3193
+ return this._readyState;
3194
+ }
3195
+ /**
3196
+ * Returns the serialized URL of the response or the empty string if the URL is `null`.
3197
+ *
3198
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseURL
3199
+ */
3200
+ get responseURL() {
3201
+ return this._url;
3202
+ }
3203
+ /**
3204
+ * Returns the text received from a server following a request being sent.
3205
+ *
3206
+ * Throws an `InvalidStateError` DOMException if responseType is not the empty string or "text".
3207
+ *
3208
+ * @see https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseText
3209
+ */
3210
+ get responseText() {
3211
+ return this._dataStorage?.stringifiedData || EMPTY_STRING;
3212
+ }
3213
+ /**
3214
+ * Returns an `XMLHttpRequestUpload` object that can be observed to monitor an upload progress.
3215
+ *
3216
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/upload
3217
+ */
3218
+ get upload() {
3219
+ return null;
3220
+ }
3221
+ /**
3222
+ * @private
3223
+ */
3224
+ open(method, url, async, username, password) {
3225
+ this._method = method;
3226
+ this._url = url;
3227
+ this.setReadyState(this.OPENED);
3228
+ }
3229
+ /**
3230
+ * Aborts the request if it has already been sent. When a request is aborted, its `readyState`
3231
+ * is changed to `XMLHttpRequest.UNSENT` and the request status code is set to `0`.
3232
+ */
3233
+ abort() {
3234
+ this._readyState = this.UNSENT;
3235
+ this._status = 0;
3236
+ this.eventDispatch("abort");
3237
+ }
3238
+ /**
3239
+ * Returns all the response headers, separated by CRLF, as a string, or returns `null`
3240
+ * if no response has been received.
3241
+ *
3242
+ * @returns All the response headers, separated by CRLF, as a string, or returns `null`
3243
+ * if no response has been received.
3244
+ */
3245
+ getAllResponseHeaders() {
3246
+ return this._dataStorage ? HttpHeadersUtil.stringify(this._headers) : EMPTY_STRING;
3247
+ }
3248
+ /**
3249
+ * Sends the request to the server.
3250
+ *
3251
+ * @param body A body of data to be sent in the XHR request.
3252
+ */
3253
+ send(body) {
3254
+ const request = new HttpRequest(this._method, this._url, body);
3255
+ const rc = this._routeConfig;
3256
+ const httpResponseMock = rc.methodConfig.data(request, rc.parameters);
3257
+ let timer = httpResponseMock.delay || 0;
3258
+ if (timer > MAX_TIMER)
3259
+ timer = MAX_TIMER;
3260
+ this._loadSubscription = this.loadData(httpResponseMock).subscribe((data) => {
3261
+ this._dataStorage = DataStorageBuilder.buildDataStorage(httpResponseMock, data);
3262
+ const error = this._dataStorage.httpResponse.error;
3263
+ setTimeout(() => {
3264
+ this.setReadyState(this.HEADERS_RECEIVED);
3265
+ if (error)
3266
+ return this.onError(error);
3267
+ this.setReadyState(this.LOADING);
3268
+ const response = this._dataStorage.httpResponse;
3269
+ let headers = response.headers;
3270
+ if (headers) {
3271
+ this._headers.keys().forEach((key) => {
3272
+ headers = headers.set(key, this._headers.get(key));
3273
+ });
3274
+ this._headers = headers;
3275
+ }
3276
+ if (!this._progressiveDownload) {
3277
+ this._statusText = response.statusText || EMPTY_STRING;
3278
+ this._status = response.status || 0;
3279
+ return this.onLoadComplete();
3280
+ }
3281
+ this.doProgressiveDownload();
3282
+ }, timer);
3283
+ });
3284
+ }
3285
+ /**
3286
+ * Sets the value of an HTTP request header.
3287
+ *
3288
+ * @param name The name of the header whose value is to be set.
3289
+ * @param value The value to set as the body of the header.
3290
+ */
3291
+ setRequestHeader(name, value) {
3292
+ this._headers = this._headers.set(name, value);
3293
+ }
3294
+ /**
3295
+ * @private
3296
+ */
3297
+ constructor(routeConfig) {
3298
+ super();
3299
+ /**
3300
+ * @private
3301
+ * Indicates whether the progressive download is activated, or not.
3302
+ */
3303
+ this._progressiveDownload = false;
3304
+ /**
3305
+ * @private
3306
+ *
3307
+ * Internal storage for HTTP response `data`.
3308
+ */
3309
+ this._dataStorage = null;
3310
+ /**
3311
+ * @private
3312
+ *
3313
+ * Internal storage for the HTTP request `readyState`.
3314
+ */
3315
+ this._readyState = this.UNSENT;
3316
+ /**
3317
+ * @private
3318
+ *
3319
+ * Internal storage for the HTTP request `headers`.
3320
+ */
3321
+ this._headers = null;
3322
+ /**
3323
+ * @private
3324
+ *
3325
+ * Internal storage for the HTTP request `status`.
3326
+ */
3327
+ this._status = 0;
3328
+ /**
3329
+ * @private
3330
+ *
3331
+ * Internal storage for the HTTP request `statusText`.
3332
+ */
3333
+ this._statusText = EMPTY_STRING;
3334
+ /**
3335
+ * @private
3336
+ */
3337
+ this._loadSubscription = null;
3338
+ /**
3339
+ * Returns an an enumerated string value specifying the type of data contained in the response.
3340
+ *
3341
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
3342
+ */
3343
+ this.responseType = "";
3344
+ const methodConfig = routeConfig.methodConfig;
3345
+ this._routeConfig = routeConfig;
3346
+ this._progressiveDownload = methodConfig.progressive || false;
3347
+ this.responseType = methodConfig.responseType || "";
3348
+ this._headers = new HttpHeaders();
3349
+ }
3350
+ /**
3351
+ * @private
3352
+ * Internally used by the framework to delete a `DelegateXhr` instance.
3353
+ */
3354
+ destroy() {
3355
+ this._routeConfig = null;
3356
+ this._headers = null;
3357
+ this._dataStorage = null;
3358
+ if (this._loadSubscription) {
3359
+ this._loadSubscription.unsubscribe();
3360
+ this._loadSubscription = null;
3361
+ }
3362
+ }
3363
+ /**
3364
+ * @private
3365
+ */
3366
+ doProgressiveDownload() {
3367
+ const total = this._dataStorage.total;
3368
+ if (total <= 200) {
3369
+ console.warn("[Angular Toolbox]: Body content is too small for emulating progressive download! Minimum size is 200 octets.");
3370
+ return this.onLoadComplete();
3371
+ }
3372
+ // TODO: ameliorate the following process:
3373
+ const self = this;
3374
+ const chunckSize = Math.floor(total / 10);
3375
+ let cursor = 0;
3376
+ this._statusText = "Partial Content";
3377
+ this._status = HttpStatusCode.PartialContent;
3378
+ const idx = setInterval(() => {
3379
+ cursor += chunckSize;
3380
+ if (cursor > total) {
3381
+ cursor = total;
3382
+ clearInterval(idx);
3383
+ self.onLoadComplete();
3384
+ }
3385
+ else {
3386
+ this._dataStorage.loaded = cursor;
3387
+ self.dispatchProgressEvent();
3388
+ }
3389
+ }, 100);
3390
+ }
3391
+ /**
3392
+ * @private
3393
+ */
3394
+ onLoadComplete() {
3395
+ this._dataStorage.loaded = this._dataStorage.total;
3396
+ this.setReadyState(this.DONE);
3397
+ this.dispatchProgressEvent("load");
3398
+ }
3399
+ /**
3400
+ * @private
3401
+ */
3402
+ onError(error) {
3403
+ this._status = error.status;
3404
+ this._statusText = error.statusText;
3405
+ this.setReadyState(this.DONE);
3406
+ this.dispatchProgressEvent("error");
3407
+ }
3408
+ /**
3409
+ * @private
3410
+ */
3411
+ eventDispatch(type) {
3412
+ const event = new Event(type);
3413
+ Object.defineProperty(event, 'target', EVT_PROPS_CONFIG);
3414
+ Object.defineProperty(event, 'currentTarget', EVT_PROPS_CONFIG);
3415
+ this.dispatchEvent(event);
3416
+ }
3417
+ /**
3418
+ * @private
3419
+ */
3420
+ dispatchProgressEvent(type = "progress") {
3421
+ const d = this._dataStorage;
3422
+ const event = new ProgressEventMock(type);
3423
+ event.loaded = d.loaded;
3424
+ event.total = d.total;
3425
+ this.dispatchEvent(event);
3426
+ }
3427
+ /**
3428
+ * @private
3429
+ */
3430
+ setReadyState(state) {
3431
+ this._readyState = state;
3432
+ const event = this.onreadystatechange;
3433
+ if (event)
3434
+ event.call(this, READY_STATE_CHANGE_EVENT);
3435
+ }
3436
+ /**
3437
+ * @private
3438
+ */
3439
+ loadData(httpResponseMock) {
3440
+ const responseBody = httpResponseMock.body;
3441
+ return (responseBody instanceof Observable) ? responseBody : of(responseBody);
3442
+ }
3443
+ }
3444
+
3445
+ /**
3446
+ * @license
3447
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3448
+ *
3449
+ * Use of this source code is governed by an MIT-style license that can be ound in
3450
+ * fthe LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3451
+ */
3452
+ /**
3453
+ * @private
3454
+ * An error used as reference for unit testing.
3455
+ * Angular framework calls `XMLHttpRequest` method only after the `open()` method invokation.
3456
+ */
3457
+ const XHR_ERROR = (method) => {
3458
+ throw new Error(`Attempt to call ${method}() method before calling open().`);
3459
+ };
3460
+ /**
3461
+ * @private
3462
+ * A XHR proxy that is used by the Mocking Framework to apply HTTP call strategies.
3463
+ */
3464
+ class XhrProxyImpl extends XhrBase {
3465
+ /**
3466
+ * @private
3467
+ *
3468
+ * XMLHTTPRequest API
3469
+ */
3470
+ get response() {
3471
+ return this.XHR ? this.XHR.response : undefined;
3472
+ }
3473
+ /**
3474
+ * @private
3475
+ *
3476
+ * XMLHTTPRequest API
3477
+ */
3478
+ get status() {
3479
+ return this.XHR ? this.XHR.status : 0;
3480
+ }
3481
+ /**
3482
+ * @private
3483
+ *
3484
+ * XMLHTTPRequest API
3485
+ */
3486
+ get statusText() {
3487
+ return this.XHR ? this.XHR.statusText : EMPTY_STRING;
3488
+ }
3489
+ /**
3490
+ * @private
3491
+ *
3492
+ * XMLHTTPRequest API
3493
+ */
3494
+ get readyState() {
3495
+ return this.XHR ? this.XHR.readyState : this.UNSENT;
3496
+ }
3497
+ /**
3498
+ * @private
3499
+ *
3500
+ * XMLHTTPRequest API
3501
+ */
3502
+ get responseURL() {
3503
+ return this.XHR ? this.XHR.responseURL : EMPTY_STRING;
3504
+ }
3505
+ /**
3506
+ * @private
3507
+ *
3508
+ * XMLHTTPRequest API
3509
+ */
3510
+ get responseText() {
3511
+ return this.XHR ? this.XHR.responseText : EMPTY_STRING;
3512
+ }
3513
+ /**
3514
+ * @private
3515
+ *
3516
+ * XMLHTTPRequest API
3517
+ */
3518
+ get responseType() {
3519
+ return this.XHR ? this.XHR.responseType : EMPTY_STRING;
3520
+ }
3521
+ /**
3522
+ * @private
3523
+ *
3524
+ * XMLHTTPRequest API
3525
+ */
3526
+ set responseType(value) {
3527
+ if (!this.XHR)
3528
+ XHR_ERROR("responseType");
3529
+ this.XHR.responseType = value;
3530
+ }
3531
+ get upload() {
3532
+ return this.XHR.upload;
3533
+ }
3534
+ open(method, url, async, username, password) {
3535
+ const m = method.toString().toLowerCase();
3536
+ const parsedUrl = URL.canParse(url) ? new URL(url) : new URL(this._httpMockService.getAppOrigin() + url);
3537
+ const config = this._httpMockService.getRouteConfig(parsedUrl, m);
3538
+ if (this.XHR && this.XHR instanceof DelegateXhr)
3539
+ this.XHR.destroy();
3540
+ this.XHR = config ? new DelegateXhr(config) : new XMLHttpRequest();
3541
+ this.XHR.withCredentials = this.withCredentials;
3542
+ this.XHR.open(m.toString(), parsedUrl.toString());
3543
+ }
3544
+ /**
3545
+ * @private
3546
+ *
3547
+ * XMLHTTPRequest API
3548
+ */
3549
+ abort() {
3550
+ if (this.XHR)
3551
+ return this.XHR.abort();
3552
+ XHR_ERROR("abort");
3553
+ }
3554
+ /**
3555
+ * @private
3556
+ *
3557
+ * XMLHTTPRequest API
3558
+ */
3559
+ getAllResponseHeaders() {
3560
+ return this.XHR ? this.XHR.getAllResponseHeaders() : EMPTY_STRING;
3561
+ }
3562
+ /**
3563
+ * @private
3564
+ *
3565
+ * XMLHTTPRequest API
3566
+ */
3567
+ addEventListener(type, listener, options) {
3568
+ if (this.XHR)
3569
+ return this.XHR.addEventListener(type, listener, options);
3570
+ XHR_ERROR("addEventListener");
3571
+ }
3572
+ /**
3573
+ * @private
3574
+ *
3575
+ * XMLHTTPRequest API
3576
+ */
3577
+ removeEventListener(type, listener, options) {
3578
+ if (this.XHR)
3579
+ return this.XHR.removeEventListener(type, listener, options);
3580
+ XHR_ERROR("removeEventListener");
3581
+ }
3582
+ /**
3583
+ * @private
3584
+ *
3585
+ * XMLHTTPRequest API
3586
+ */
3587
+ send(body) {
3588
+ if (this.XHR)
3589
+ return this.XHR.send(body);
3590
+ XHR_ERROR("send");
3591
+ }
3592
+ /**
3593
+ * @private
3594
+ *
3595
+ * XMLHTTPRequest API
3596
+ */
3597
+ setRequestHeader(name, value) {
3598
+ if (this.XHR)
3599
+ return this.XHR.setRequestHeader(name, value);
3600
+ XHR_ERROR("setRequestHeader");
3601
+ }
3602
+ /**
3603
+ * @private
3604
+ *
3605
+ * For Unit Testing only.
3606
+ */
3607
+ instanceOf(classRef) {
3608
+ return this.XHR instanceof classRef;
3609
+ }
3610
+ /**
3611
+ * @private
3612
+ */
3613
+ constructor(_httpMockService) {
3614
+ super();
3615
+ this._httpMockService = _httpMockService;
3616
+ }
3617
+ }
3618
+
3619
+ /**
3620
+ * @license
3621
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3622
+ *
3623
+ * Use of this source code is governed by an MIT-style license that can be found in
3624
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3625
+ */
3626
+ /**
3627
+ * @private
3628
+ * The concrete implementation of the `XhrFactory` interface.
3629
+ */
3630
+ class XhrProxyFactoryImpl extends XhrFactory {
3631
+ /**
3632
+ * @private
3633
+ */
3634
+ constructor(_httpMockService) {
3635
+ super();
3636
+ this._httpMockService = _httpMockService;
3637
+ }
3638
+ /**
3639
+ * @private
3640
+ */
3641
+ build() {
3642
+ return new XhrProxyImpl(this._httpMockService);
3643
+ }
3644
+ }
3645
+
3646
+ /**
3647
+ * @license
3648
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3649
+ *
3650
+ * Use of this source code is governed by an MIT-style license that can be found in
3651
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3652
+ */
3653
+ /**
3654
+ * A factory function that creates and returns a new `XhrFactory` object.
3655
+ *
3656
+ * @returns A new `XhrFactory` object.
3657
+ */
3658
+ const httpMockFactory = () => {
3659
+ return new XhrProxyFactoryImpl(inject(HttpMockService));
3660
+ };
3661
+
3662
+ /**
3663
+ * A basic implementation of HTML sanitization pipe.
3664
+ */
3665
+ class SafeHtmlPipe {
3666
+ /**
3667
+ * @private
3668
+ */
3669
+ constructor(_sanitizer) {
3670
+ this._sanitizer = _sanitizer;
3671
+ }
3672
+ /**
3673
+ * Transforms the HTML input string value into a `SafeHtml` instance and returns the result
3674
+ * of the transformation.
3675
+ *
3676
+ * @param value The HTML input value to transform into a `SafeHtml` instance.
3677
+ * @returns A `SafeHtml` instance based on the specified input value.
3678
+ */
3679
+ transform(value) {
3680
+ return this._sanitizer.bypassSecurityTrustHtml(value);
3681
+ }
3682
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
3683
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.0.3", ngImport: i0, type: SafeHtmlPipe, isStandalone: true, name: "safeHtml" }); }
3684
+ }
3685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: SafeHtmlPipe, decorators: [{
3686
+ type: Pipe,
3687
+ args: [{
3688
+ name: 'safeHtml',
3689
+ standalone: true
3690
+ }]
3691
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }] });
3692
+
3693
+ /**
3694
+ * @license
3695
+ * Copyright Pascal ECHEMANN. All Rights Reserved.
3696
+ *
3697
+ * Use of this source code is governed by an MIT-style license that can be found in
3698
+ * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
3699
+ */
3700
+ /*
3701
+ * Public API Surface of angular-toolbox
3702
+ */
3703
+
3704
+ /**
3705
+ * Generated bundle index. Do not edit.
3706
+ */
3707
+
3708
+ export { APP_PRIDGE_REF, AnchorLinklDirective, AngularToolboxModule, AppBridgeError, AppBrigeService, BIGINT, BOOLEAN, BUTTON_ROLE, ButtonRoleDirective, CSS_PROP, ContentRendererDirective, DARK_MODE_CONFIG, DarkModeService, EMPTY_STRING, FUNCTION, HTTP_MOCK_SERVICE, HttpHeadersMockBuilder, HttpMock, HttpMockService, HttpMockServiceError, HttpResponseMockBuilder, IdentifiableComponent, IntegrityError, LINK_ROLE, NUMBER, NavigateToUrlDirective, OBJECT, STORAGE_KEY, STRING, SYMBOL, SafeHtmlPipe, ScrollService, SubscriptionError, SubscriptionService, UNDEFINED, Uuid, VERSION_CONFIG, VersionService, httpHeadersMock, httpMockFactory, httpResponseMock };
3709
+ //# sourceMappingURL=angular-toolbox.mjs.map