@kephas/angular
Version:
Provides integration capabilities with Angular.
908 lines (895 loc) • 30.9 kB
JavaScript
import { ChangeDetectorRef, Component, ElementRef, ViewContainerRef, ViewChildren, Input, forwardRef, Injector, ɵɵdefineInjectable, ɵɵinject, INJECTOR, Injectable } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Logger, SingletonAppServiceContract, AppServiceContract, AppService, Priority, Requires, LogLevel } from '@kephas/core';
import { Notification } from '@kephas/ui';
import { __decorate, __metadata, __awaiter } from 'tslib';
import { HTTP_INTERCEPTORS, XhrFactory, HttpBackend, HttpXhrBackend, HttpClient, HttpHandler } from '@angular/common/http';
import 'reflect-metadata';
import { CommandProcessorClient, CommandError } from '@kephas/commands';
import { retry, map, catchError } from 'rxjs/operators';
import { MessageProcessorClient, MessagingError } from '@kephas/messaging';
/**
* Provides base functionality for a widget.
*
* @export
* @class WidgetBase
*/
class WidgetBase {
/**
* Creates an instance of WidgetBase.
* @param {ElementRef} elementRef The element reference.
* @param {ViewContainerRef} viewContainerRef The view container reference.
* @memberof WidgetBase
*/
constructor(elementRef, viewContainerRef) {
this.elementRef = elementRef;
this.viewContainerRef = viewContainerRef;
this._isVisible = true;
this._readonly = false;
const injector = viewContainerRef.injector;
this.logger = injector.get(Logger);
this.notification = injector.get(Notification);
this.changeDetector = injector.get(ChangeDetectorRef);
}
/**
* Gets or sets the child editors query.
*
* @readonly
* @type {QueryList<EditorBase<any>>}
* @memberof EditorBase
*/
get childWidgets() {
return this._childWidgets;
}
set childWidgets(value) {
if (this._childWidgets === value) {
return;
}
const oldValue = this._childWidgets;
this._childWidgets = value;
this.onChildWidgetsChanged(oldValue, value);
}
/**
* Gets or sets a value indicating whether the widget is visible.
*
* @readonly
* @type {boolean}
* @memberof WidgetBase
*/
get isVisible() {
return this._isVisible;
}
set isVisible(value) {
if (this._isVisible === value) {
return;
}
this._isVisible = value;
}
/**
* Gets or sets a value indicating whether the editor allows edits or not.
*
* @readonly
* @type {boolean}
* @memberof EditorBase
*/
get readonly() {
return this._readonly;
}
set readonly(value) {
if (this._readonly === value) {
return;
}
const oldValue = this._readonly;
this._readonly = value;
this.onReadOnlyChanged(oldValue, value);
}
/**
* A callback method that is invoked immediately after the
* default change detector has checked the directive's
* data-bound properties for the first time,
* and before any of the view or content children have been checked.
* It is invoked only once when the directive is instantiated.
*
* @memberof WidgetBase
*/
ngOnInit() {
}
/**
* A callback method that is invoked immediately after
* Angular has completed initialization of a component's view.
* It is invoked only once when the view is instantiated.
*
* @memberof WidgetBase
*/
ngAfterViewInit() {
}
/**
* A callback method that is invoked immediately after the
* default change detector has checked data-bound properties
* if at least one has changed, and before the view and content
* children are checked.
*
* @param changes The changed properties.
* @memberof WidgetBase
*/
ngOnChanges(changes) {
}
/**
* A callback method that performs custom clean-up, invoked immediately
* after a directive, pipe, or service instance is destroyed.
*/
ngOnDestroy() {
}
/**
* When overridden in a derived class, this method is called when the read only state changes.
*
* @protected
* @param {boolean} oldValue The old value.
* @param {boolean} newValue The new value.
*
* @memberof WidgetBase
*/
onReadOnlyChanged(oldValue, newValue) {
}
/**
* When overridden in a derived class, this method is called when the child widgets query changed.
*
* @protected
* @param {QueryList<EditorBase<any>>} oldValue The old query.
* @param {QueryList<EditorBase<any>>} newValue The new query.
*
* @memberof EditorBase
*/
onChildWidgetsChanged(oldValue, newValue) {
}
}
WidgetBase.decorators = [
{ type: Component, args: [{
template: ''
},] }
];
WidgetBase.ctorParameters = () => [
{ type: ElementRef },
{ type: ViewContainerRef }
];
WidgetBase.propDecorators = {
childWidgets: [{ type: ViewChildren, args: [WidgetBase,] }],
isVisible: [{ type: Input }],
readonly: [{ type: Input }]
};
/**
* This function provides the component as a WidgetBase,
* to be able to import it over this base class instead of over its own class.
*
* For example, use it as @ViewChild(WidgetBase) or @ViewChildren(WidgetBase).
*
* @export
* @param {Type<any>} componentType The component type.
* @returns {Provider} The provider.
*/
function provideWidget(componentType) {
return {
provide: WidgetBase,
useExisting: forwardRef(() => componentType)
};
}
/**
* This function provides the component as a NG_VALUE_ACCESSOR.
* Thus, it is possible to bind it like this:
* <my-component [(ngModel)]="boundProperty"></my-component>
*
* @export
* @param {Type<any>} componentType The component type.
* @returns {Provider} The provider.
*/
function provideValueAccessor(componentType) {
return {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => componentType),
multi: true
};
}
/**
* Provides a base implementation for value editors.
*
* @export
* @abstract
* @class ValueEditorBase
* @implements {OnInit}
* @implements {AfterViewInit}
* @implements {ControlValueAccessor}
* @template TValue The value type.
*/
class ValueEditorBase extends WidgetBase {
/**
* Creates an instance of ValueEditorBase.
*
* @param {ElementRef} elementRef The element reference.
* @param {ViewContainerRef} viewContainerRef The view container reference.
* @memberof ValueEditorBase
*/
constructor(elementRef, viewContainerRef) {
super(elementRef, viewContainerRef);
/**
* Gets or sets a value indicating whether the value is changed from the change event.
*
* @protected
* @memberof ValueEditorBase
*/
this.valueChangeFromEvent = false;
/**
* Gets or sets a value indicating whether the value is changed from the value property.
*
* @protected
* @memberof ValueEditorBase
*/
this.valueChangeFromValue = false;
this._onChange = (_) => {
// The implementation will get overwritten by Angular in RegisterOnChange.
};
this._onTouched = () => {
// The implementation will get overwritten by Angular in RegisterOnTouched.
};
}
/**
* Gets or sets the value to edit.
*
* @type {TValue}
* @memberOf ValueEditorBase
*/
get value() {
return this.getEditorValue();
}
set value(value) {
if (this._valueBeforeChange === value) {
return;
}
this.updateEditor(value);
}
/**
* Updates the underlying editor with the provided value.
*
* @protected
* @param {TValue} value
* @returns {boolean}
* @memberof ValueEditorBase
*/
updateEditor(value) {
if (this.valueChangeFromValue) {
return false;
}
const prevValueChangeFromValue = this.valueChangeFromValue;
this.valueChangeFromValue = true;
try {
const oldValue = this._valueBeforeChange;
this.onValueChanging(oldValue, value);
this._valueBeforeChange = value;
if (!this.valueChangeFromEvent) {
this.setEditorValue(value);
value = this.getEditorValue();
}
this.onValueChanged(oldValue, value);
}
catch (error) {
this.logger.error(error, 'Error while updating the editor.');
throw error;
}
finally {
this.valueChangeFromValue = prevValueChangeFromValue;
}
return true;
}
/**
* Overridable method invoked when the value is about to be changed.
*
* @protected
* @param {(TValue | undefined)} oldValue The old value.
* @param {(TValue | undefined)} newValue The new value.
* @memberof ValueEditorBase
*/
onValueChanging(oldValue, newValue) {
}
/**
* Overridable method invoked after the value was changed.
*
* @protected
* @param {(TValue | undefined)} oldValue The old value.
* @param {(TValue | undefined)} newValue The new value.
* @memberof ValueEditorBase
*/
onValueChanged(oldValue, newValue) {
this._onChange(newValue);
}
/**
* Callback invoked from the change event of the underlying editor.
*
* @protected
* @param {*} e
* @returns
* @memberof PropertyEditorComponent
*/
onEditorChange(e) {
if (this.valueChangeFromValue) {
return;
}
const prevValueChangeFromEvent = this.valueChangeFromEvent;
this.valueChangeFromEvent = true;
try {
const newValue = this.getEditorValueOnChange(e);
this.value = newValue;
}
catch (error) {
this.notification.notifyError(error);
}
finally {
this.valueChangeFromEvent = prevValueChangeFromEvent;
}
}
/**
* Gets the underlying editor's value upon change.
*
* @protected
* @param {*} e The change event arguments.
* @returns {TValue} The widget value.
* @memberof ValueEditorBase
*/
getEditorValueOnChange(e) {
return this.getEditorValue();
}
/**
* Write a new value to the element.
*
* @param {*} obj The new value.
*
* @memberOf PropertyEditorComponent
*/
writeValue(obj) {
this.value = obj;
}
/**
* Set the function to be called when the control receives a change event.
*
* @param {*} fn The callback function.
*
* @memberOf PropertyEditorComponent
*/
registerOnChange(fn) {
this._onChange = fn;
}
/**
* Set the function to be called when the control receives a touch event.
*
* @param {*} fn The callback function.
*
* @memberOf PropertyEditorComponent
*/
registerOnTouched(fn) {
this._onTouched = fn;
}
/**
* This function is called when the control status changes to or from "DISABLED".
* Depending on the value, it will enable or disable the appropriate DOM element.
*
* @param {boolean} isDisabled True if the state is disabled.
*
* @memberOf PropertyEditorComponent
*/
setDisabledState(isDisabled) {
}
}
ValueEditorBase.decorators = [
{ type: Component, args: [{
template: ''
},] }
];
ValueEditorBase.ctorParameters = () => [
{ type: ElementRef },
{ type: ViewContainerRef }
];
ValueEditorBase.propDecorators = {
value: [{ type: Input }]
};
/**
* Base class for HTTP interceptors.
*
* @export
* @extends {AngularHttpInterceptor}
*/
let HttpInterceptor = class HttpInterceptor {
};
HttpInterceptor = __decorate([
SingletonAppServiceContract({ allowMultiple: true, contractToken: HTTP_INTERCEPTORS })
], HttpInterceptor);
SingletonAppServiceContract()(XhrFactory);
AppServiceContract()(HttpBackend);
AppServiceContract()(Injector);
AppServiceContract()(HttpXhrBackend);
AppService({ overridePriority: Priority.Low })(HttpXhrBackend);
// tslint:disable: max-classes-per-file
/**
* Browser implementation for an `XhrFactory`.
*
* @export
* @class BrowserXhrFactory
* @implements {XhrFactory}
*/
class BrowserXhrFactory {
build() {
return new XMLHttpRequest();
}
}
/**
* `HttpHandler` which applies an `HttpInterceptor` to an `HttpRequest`.
*
*
*/
class HttpInterceptorHandler {
constructor(next, interceptor) {
this.next = next;
this.interceptor = interceptor;
}
handle(req) {
return this.interceptor.intercept(req, this.next);
}
}
/**
* An injectable `HttpHandler` that applies multiple interceptors
* to a request before passing it to the given `HttpBackend`.
*
* The interceptors are loaded lazily from the injector, to allow
* interceptors to themselves inject classes depending indirectly
* on `HttpInterceptingHandler` itself.
* @see `HttpInterceptor`
*/
class HttpInterceptingHandler {
/**
* Creates an instance of HttpInterceptingHandler.
* @param {HttpBackend} backend
* @param {Injector} injector
* @memberof HttpInterceptingHandler
*/
constructor(backend, injector) {
this.backend = backend;
this.injector = injector;
this.chain = null;
}
handle(req) {
if (this.chain === null) {
const interceptors = this.injector.get(HTTP_INTERCEPTORS, []);
this.chain = interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), this.backend);
}
return this.chain.handle(req);
}
}
HttpInterceptingHandler.ɵprov = ɵɵdefineInjectable({ factory: function HttpInterceptingHandler_Factory() { return new HttpInterceptingHandler(ɵɵinject(HttpBackend), ɵɵinject(INJECTOR)); }, token: HttpInterceptingHandler, providedIn: "root" });
HttpInterceptingHandler.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
HttpInterceptingHandler.ctorParameters = () => [
{ type: HttpBackend },
{ type: Injector }
];
/**
* Registry for HTTP client services.
*
* @export
* @class HttpClientAppServiceInfoRegistry
*/
class HttpClientAppServiceInfoRegistry {
/**
* Gets the providers for the HTTP client.
*
* @returns {((StaticClassProvider | ExistingProvider)[])}
* @memberof HttpClientAppServiceInfoRegistry
*/
getHttpClientProviders() {
return [
{ provide: HttpClient, useClass: HttpClient, deps: [HttpHandler] },
{ provide: HttpHandler, useClass: HttpInterceptingHandler, deps: [HttpBackend, Injector] },
{ provide: HttpBackend, useClass: HttpXhrBackend, deps: [XhrFactory] },
{ provide: XhrFactory, useClass: BrowserXhrFactory, deps: [] },
];
}
}
/**
* Helper class for registering the services with the Angular injector.
*
* @export
*/
class AngularAppServiceInfoRegistry {
/**
* Creates an instance of AngularAppServiceInfoRegistry.
*
* @param {AppServiceInfoRegistry} serviceRegistry The service registry.
*/
constructor(serviceRegistry) {
this.serviceRegistry = serviceRegistry;
Requires.HasValue(serviceRegistry, 'serviceRegistry');
}
/**
* Registers the application services to the Angular DI container.
*
* @param {...string[]} modules The modules to import to collect the service metadata.
*/
registerServices() {
for (const serviceMetadata of this.serviceRegistry.services) {
Injectable({ providedIn: 'root' })(serviceMetadata.serviceType);
}
}
/**
* Gets the providers for the root.
*
* @returns {StaticClassProvider[]}
*/
getRootProviders() {
const providers = [];
for (const c of this.serviceRegistry.serviceContracts) {
const serviceContract = c;
for (const m of serviceContract.services) {
const serviceMetadata = m;
providers.push({
provide: serviceContract.contractToken || serviceContract.contractType,
useClass: serviceMetadata.serviceType,
multi: serviceContract.allowMultiple,
deps: this.getDependencies(serviceMetadata.serviceType),
});
}
}
providers.push(...new HttpClientAppServiceInfoRegistry().getHttpClientProviders());
return providers;
}
getDependencies(serviceType) {
let deps = Reflect.getMetadata('design:paramtypes', serviceType);
if (!deps && serviceType.ctorParameters) {
deps = serviceType.ctorParameters();
}
return deps || [];
}
}
/**
* Gets the application settings.
*
* @export
* @class AppSettings
*/
let AppSettings = class AppSettings {
/**
* Gets the base URL of the application.
*
* @readonly
* @type {string}
* @memberof AppSettings
*/
get baseUrl() {
const baseQuery = document.getElementsByTagName('base');
const baseElement = baseQuery && baseQuery[0];
return (baseElement && baseElement.href) || document.baseURI || '/';
}
/**
* Gets the base API URL of the application.
*
* @readonly
* @type {string}
* @memberof AppSettings
*/
get baseApiUrl() {
return `${this.baseUrl}api/`;
}
};
AppSettings = __decorate([
AppService({ overridePriority: Priority.Low }),
SingletonAppServiceContract()
], AppSettings);
/**
* Provides proxied command execution over HTTP.
*
* @export
* @class HttpCommandProcessorClient
*/
let HttpCommandProcessorClient = class HttpCommandProcessorClient extends CommandProcessorClient {
/**
* Initializes a new instance of the CommandProcessor class.
* @param {Notification} notification The notification service.
* @param {HttpClient} http The HTTP client.
* @param {AppSettings} appSettings The application settings.
*/
constructor(appSettings, http, notification, logger) {
super();
this.appSettings = appSettings;
this.http = http;
this.notification = notification;
this.logger = logger;
/**
* Gets or sets the base route for the command execution.
*
* @protected
* @type {string}
* @memberof CommandProcessor
*/
this.baseRoute = 'api/cmd/';
}
/**
* Processes the command asynchronously.
* @tparam T The command response type.
* @param {string} command The command.
* @param {{}} [args] Optional. The arguments.
* @param {CommandClientContext} [options] Optional. Options controlling the command processing.
* @returns {Observable{T}} An observable over the result.
*/
process(command, args, options) {
const url = this.getHttpGetUrl(command, args, options);
let obs = this.http.get(url, this.getHttpGetOptions(command, args, options));
if (options && options.retries) {
obs = obs.pipe(retry(options.retries), map(response => this._processResponse(response, options)), catchError(error => this._processError(error, options)));
}
else {
obs = obs.pipe(map(response => this._processResponse(response, options)), catchError(error => this._processError(error, options)));
}
return obs;
}
/**
* Gets the HTTP GET URL.
*
* @protected
* @param {string} command The command.
* @param {{}} [args] Optional. The arguments.
* @param {CommandClientContext} [options] Optional. Options controlling the command processing.
* @returns {string} The HTTP GET URL.
* @memberof CommandProcessor
*/
getHttpGetUrl(command, args, options) {
let baseUrl = this.appSettings.baseUrl;
if (!baseUrl.endsWith('/')) {
baseUrl = baseUrl + '/';
}
let url = `${baseUrl}${this.baseRoute}${command}/`;
if (args) {
url = url + '?' + Object.keys(args)
.map(key => `${key}=${args[key]}`)
.join('&');
}
return url;
}
/**
* Gets the HTTP GET options. By default it does not return any options.
*
* @protected
* @param {string} command The command.
* @param {{}} [args] Optional. The arguments.
* @param {CommandClientContext} [options] Optional. Options controlling the command processing.
* @returns {({
* headers?: HttpHeaders | {
* [header: string]: string | string[];
* };
* observe?: 'body';
* params?: HttpParams | {
* [param: string]: string | string[];
* };
* reportProgress?: boolean;
* responseType?: 'json';
* withCredentials?: boolean;
* } | undefined)} The options or undefined.
* @memberof CommandProcessor
*/
getHttpGetOptions(command, args, options) {
return undefined;
}
_processResponse(response, options) {
if (typeof response.severity === 'string') {
response.severity = LogLevel[response.severity];
}
if (response.severity <= LogLevel.Error) {
throw new CommandError(response.message, response);
}
if (response.severity === LogLevel.Warning) {
this.logger.log(response.severity, null, response.message);
if (!(options && (options.notifyWarnings === undefined || options.notifyWarnings))) {
this.notification.notifyWarning(response);
}
}
if (response.severity <= LogLevel.Error) {
throw new Error(response.message);
}
return response;
}
_processError(error, options) {
this.logger.error(error);
if (!(options && (options.notifyErrors === undefined || options.notifyErrors))) {
this.notification.notifyError(error);
}
throw error;
}
};
HttpCommandProcessorClient = __decorate([
AppService({ overridePriority: Priority.Low }),
__metadata("design:paramtypes", [AppSettings,
HttpClient,
Notification,
Logger])
], HttpCommandProcessorClient);
/**
* Provides proxied message processing over HTTP.
*
* @export
* @class MessageProcessor
*/
let HttpMessageProcessorClient = class HttpMessageProcessorClient extends MessageProcessorClient {
/**
* Initializes a new instance of the HttpMessageProcessor class.
* @param {Notification} notification The notification service.
* @param {HttpClient} http The HTTP client.
* @param {AppSettings} appSettings The application settings.
*/
constructor(appSettings, http, notification, logger) {
super();
this.appSettings = appSettings;
this.http = http;
this.notification = notification;
this.logger = logger;
/**
* Gets or sets the base route for the command execution.
*
* @protected
* @type {string}
* @memberof MessageProcessor
*/
this.baseRoute = 'api/msg/';
}
/**
* Processes the message asynchronously.
* @tparam T The message response type.
* @param {{}} message The message.
* @param {MessagingClientContext} [options] Optional. Options controlling the message processing.
* @returns {Observable{T}} An observable over the result.
*/
process(message, options) {
const url = this.getHttpPostUrl(message, options);
const obs = this.http.post(url, message, this.getHttpPostOptions(message, options));
const responseObj = (options && options.retries)
? obs.pipe(retry(options.retries), map(response => this._processResponse(response, options)), catchError(error => this._processError(error, options)))
: obs.pipe(map(response => this._processResponse(response, options)), catchError(error => this._processError(error, options)));
return responseObj;
}
/**
* Gets the HTTP GET URL.
*
* @protected
* @param {{}} message The message.
* @param {MessagingClientContext} [options] Optional. Options controlling the command processing.
* @returns {string} The HTTP GET URL.
* @memberof MessageProcessor
*/
getHttpPostUrl(message, options) {
let baseUrl = this.appSettings.baseUrl;
if (!baseUrl.endsWith('/')) {
baseUrl = baseUrl + '/';
}
const url = `${baseUrl}${this.baseRoute}`;
return url;
}
/**
* Gets the HTTP GET options. By default it does not return any options.
*
* @protected
* @param {string} command The command.
* @param {{}} [args] Optional. The arguments.
* @param {MessagingClientContext} [options] Optional. Options controlling the command processing.
* @returns {({
* headers?: HttpHeaders | {
* [header: string]: string | string[];
* };
* observe?: 'body';
* params?: HttpParams | {
* [param: string]: string | string[];
* };
* reportProgress?: boolean;
* responseType?: 'json';
* withCredentials?: boolean;
* } | undefined)} The options or undefined.
* @memberof MessageProcessor
*/
getHttpPostOptions(message, options) {
return undefined;
}
_processResponse(rawResponse, options) {
if (rawResponse.exception) {
const errorInfo = rawResponse.exception;
if (typeof errorInfo.severity === 'string') {
errorInfo.severity = LogLevel[errorInfo.severity];
}
throw new MessagingError(errorInfo.message, errorInfo);
}
const response = rawResponse.message;
if (typeof response.severity === 'string') {
response.severity = LogLevel[response.severity];
}
if (response.severity <= LogLevel.Error) {
throw new MessagingError(response.message, response);
}
if (response.severity === LogLevel.Warning) {
this.logger.log(response.severity, null, response.message);
if (!(options && (options.notifyWarnings === undefined || options.notifyWarnings))) {
this.notification.notifyWarning(response);
}
}
if (response.severity <= LogLevel.Error) {
throw new MessagingError(response.message, response);
}
return response;
}
_processError(error, options) {
this.logger.error(error);
if (!(options && (options.notifyErrors === undefined || options.notifyErrors))) {
this.notification.notifyError(error);
}
throw error;
}
};
HttpMessageProcessorClient = __decorate([
AppService({ overridePriority: Priority.Low }),
__metadata("design:paramtypes", [AppSettings,
HttpClient,
Notification,
Logger])
], HttpMessageProcessorClient);
var Configuration_1;
// https://stackoverflow.com/questions/50222998/error-encountered-in-metadata-generated-for-exported-symbol-when-constructing-an
// @dynamic
/**
* The configuration service.
*
* @export
* @class Configuration
* @implements {AsyncInitializable}
*/
let Configuration = Configuration_1 = class Configuration {
/**
* Ensures that the configuration file is initialized.
*
* @param {{ http: HttpClient, configurationFileUrl?: string }} context The context containing initialization data.
* @returns {Promise<void>}
* @memberof Configuration
*/
initializeAsync(context) {
return __awaiter(this, void 0, void 0, function* () {
if (Configuration_1.configurationFile) {
return;
}
const response = yield context.http.get(context.configurationFileUrl ? context.configurationFileUrl : Configuration_1.configurationFileUrl).toPromise();
Configuration_1.configurationFile = response || {};
});
}
/**
* Gets the configuration settings for the indicated section name.
*
* @template T The settings type.
* @param {string} sectionName The section name.
* @returns {T} The settings.
* @memberof Configuration
*/
getSettings(settingsType) {
if (!Configuration_1.configurationFile) {
throw new Error('The configuration manager must be initialized prior to requesting settings from it.');
}
let sectionName = settingsType.name;
const ending = 'Settings';
if (sectionName.endsWith(ending)) {
sectionName = sectionName.substr(0, sectionName.length - ending.length);
}
sectionName = sectionName[0].toLowerCase() + sectionName.substr(1, sectionName.length - 1);
return Configuration_1.configurationFile[sectionName];
}
};
Configuration.configurationFileUrl = '/app/configuration.json';
Configuration = Configuration_1 = __decorate([
AppService({ overridePriority: Priority.Low }),
SingletonAppServiceContract()
], Configuration);
/*
* Public API Surface of @kephas/angular
*/
/**
* Generated bundle index. Do not edit.
*/
export { AngularAppServiceInfoRegistry, AppSettings, BrowserXhrFactory, Configuration, HttpClientAppServiceInfoRegistry, HttpCommandProcessorClient, HttpInterceptingHandler, HttpInterceptor, HttpInterceptorHandler, HttpMessageProcessorClient, ValueEditorBase, WidgetBase, provideValueAccessor, provideWidget };
//# sourceMappingURL=kephas-angular.js.map