UNPKG

@o3r/apis-manager

Version:

This module provides services to help you communicate with your APIs. Its responsibility is to provide an API configuration to a service factory so that it could instantiate an API with the right configurations. It contains a default configuration and a m

222 lines (214 loc) 8.89 kB
import * as i0 from '@angular/core'; import { InjectionToken, Inject, Optional, Injectable, NgModule, makeEnvironmentProviders } from '@angular/core'; /** * Api manager is responsible to provide an api configuration to a service factory, so that it could instantiate an API * with the right parameters. It contains a default configuration and a map of specific configurations for API / set of * API. Configurations are only exposed through the method getConfiguration, which will merge the default configuration * and the requested one. */ class ApiManager { /** * Map of registered Api Client associated to specific API * Warning: This should not be used to get the ApiClient for an API, the function getConfiguration() should be used instead */ get registeredApiConfigurations() { return { ...this.apiConfigurations }; } /** * Create an API manager using a custom ApiClient * @param defaultConfiguration */ constructor(defaultConfiguration, apiConfigurations = {}) { this.defaultConfiguration = defaultConfiguration; this.apiConfigurations = apiConfigurations; } /** * Retrieve a configuration for a specific API * @param api API to get the configuration for * @note When passing a string the configuration is expecting to exist else an error is thrown * @note when passing an Api instance that does not match a registered configuration, the default one will be returned */ getConfiguration(api) { if (typeof api === 'string') { if (this.apiConfigurations[api]) { return this.apiConfigurations[api]; } else { throw new Error(`Unknown API configuration: ${api}\nKnown API configurations: ${Object.keys(this.apiConfigurations).join(', ')}`); } } return (api && this.apiConfigurations[api.apiName]) || this.defaultConfiguration; } /** * Set or override API configuration * @param apiClient API configuration to override to the given api * @param api API name to override, the default configuration will be used if not specified */ setConfiguration(apiClient, api) { if (api) { this.apiConfigurations[typeof api === 'string' ? api : api.apiName] = apiClient; } else { this.defaultConfiguration = apiClient; } } } /** * Token used by the core library to provide an Api manager to services. It can be provided in the app. */ const API_TOKEN = new InjectionToken('Custom API manager token'); /** * Initial APIs instantiations */ const INITIAL_APIS_TOKEN = new InjectionToken('Initial APIs token'); class ApiFactoryService { constructor(apiManager, apis) { this.apiManager = apiManager; /** Map of loaded APIs */ this.loadedApis = {}; if (apis) { this.updateApiMapping(apis); } } /** * Determine if the given parameter is a API class * @param apiClass object to check */ isApiClass(apiClass) { return !!apiClass.apiName && typeof apiClass === 'function'; } /** * Retrieve a specific API with loaded configuration * @param apiClass class of the API to retrieve * @param refreshCache Ignore cached API instance and refresh it * @param customApiName override the `apiName` set in the `apiClass` * @note When passing `customApiName` the configuration is expecting to exist else an error is thrown * @note When passing an Api instance that does not match a registered configuration without `customApiName`, the default one will be returned */ getApi(apiClass, refreshCache = false, customApiName) { const apiName = customApiName ?? apiClass.apiName; const cache = this.loadedApis[apiName]; if (!refreshCache && cache) { return cache; } const instance = new apiClass(this.getConfigFor(customApiName ?? apiClass)); this.loadedApis[apiName] = instance; return instance; } /** * Update the Map of loaded APIs. * Note: Can be used to override the a specific API * @param map Map of loaded APIs to update */ updateApiMapping(map) { const newItems = Array.isArray(map) ? map .reduce((acc, curr) => { acc[curr.apiName] = curr; return acc; }, {}) : map; this.loadedApis = { ...this.loadedApis, ...Object.entries(newItems) .reduce((acc, [apiName, api]) => { acc[apiName] = this.isApiClass(api) ? new api(this.getConfigFor(api)) : api; return acc; }, {}) }; } /** * Clear the cache of loaded APIs * @param apis Whitelist of APIs to clear from the cache, if specified only these apis will be removed from the cache */ clearCache(apis) { if (apis) { apis.forEach((api) => delete this.loadedApis[typeof api === 'string' ? api : api.apiName]); } else { this.loadedApis = {}; } } /** * Retrieve the configuration for a specific API * @param api API for which retrieving the configuration */ getConfigFor(api) { return this.apiManager.getConfiguration(api); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiFactoryService, deps: [{ token: API_TOKEN }, { token: INITIAL_APIS_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiFactoryService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiFactoryService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: ApiManager, decorators: [{ type: Inject, args: [API_TOKEN] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [INITIAL_APIS_TOKEN] }] }] }); /** * Add a preconnect `<link>` element to the DOM * @param baseUrl the origin href * @param supportCrossOrigin add crossorigin attribute to the link element */ function appendPreconnect(baseUrl, supportCrossOrigin = true) { const preConnectLink = document.createElement('link'); preConnectLink.setAttribute('rel', 'preconnect'); preConnectLink.setAttribute('href', baseUrl); if (supportCrossOrigin) { preConnectLink.setAttribute('crossorigin', ''); } document.head.append(preConnectLink); } /** * Module that needs to be imported by the application to instantiate an SDK configuration. */ class ApiManagerModule { /** * Provide a custom {@link ApiManager} * A factory can be provided via injection to the token {@link API_TOKEN} * @param apiManager * @deprecated Please use {@link provideApiManager} instead, will be removed in v14. */ static forRoot(apiManager) { return { ngModule: ApiManagerModule, providers: [ { provide: API_TOKEN, useValue: apiManager } ] }; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiManagerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.10", ngImport: i0, type: ApiManagerModule }); } /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiManagerModule, providers: [ ApiFactoryService ] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ApiManagerModule, decorators: [{ type: NgModule, args: [{ providers: [ ApiFactoryService ] }] }] }); /** * Provide a custom {@link ApiManager} * A factory can be provided via injection to the token {@link API_TOKEN} * @param apiManager */ function provideApiManager(apiManager) { return makeEnvironmentProviders([ ApiFactoryService, { provide: API_TOKEN, useValue: apiManager } ]); } /** * Generated bundle index. Do not edit. */ export { API_TOKEN, ApiFactoryService, ApiManager, ApiManagerModule, INITIAL_APIS_TOKEN, appendPreconnect, provideApiManager }; //# sourceMappingURL=o3r-apis-manager.mjs.map