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