UNPKG

@fingerprintsoft/angular-spring-hal

Version:

This Angular module offers a HAL/JSON http-client to easily interact with a Spring Data Rest API or any API that implements the Spring Data Rest resource model

1,114 lines (1,101 loc) 53 kB
import * as i0 from '@angular/core'; import { Injectable, Inject, InjectionToken, NgModule } from '@angular/core'; import { HttpParams, HttpHeaders, HttpClient, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { of, throwError } from 'rxjs'; import { map, catchError, mergeMap } from 'rxjs/operators'; import * as hash from 'hash.js'; import * as url from 'url'; class CustomEncoder { encodeKey(key) { return encodeURIComponent(key); } encodeValue(value) { return encodeURIComponent(value); } decodeKey(key) { return decodeURIComponent(key); } decodeValue(value) { return decodeURIComponent(value); } } // @dynamic class Utils { static isNullOrUndefined(value) { return value === null || value === undefined; } static isPrimitive(value) { return (typeof value !== 'object' && typeof value !== 'function') || value === null; } } var EvictStrategy; (function (EvictStrategy) { EvictStrategy[EvictStrategy["EvictTrivial"] = 0] = "EvictTrivial"; EvictStrategy[EvictStrategy["EvictSmart"] = 1] = "EvictSmart"; })(EvictStrategy || (EvictStrategy = {})); // @dynamic class CacheHelper { static initClearCacheProcess() { if (this.isActive) { setInterval(() => { Date.now(); if (CacheHelper.evictStrategy == EvictStrategy.EvictTrivial) this.evictAll(); else if (CacheHelper.evictStrategy == EvictStrategy.EvictSmart) { this.cacheMap.forEach((value, key) => { if (value.expire > 0 && Date.now() > value.expire) this.evict(key); }); } }, 15 * 60 * 1000); } } static ifPresent(link, body, params, isActiveLocal = true) { if (!this.isActive || !isActiveLocal) return false; return this.cacheMap.has(CacheHelper.key(link, body, params)); } static getArray(link, body, params) { return this.cacheMap.get(CacheHelper.key(link, body, params)).entity; } static putArray(link, array, expireMs = 10 * 60 * 1000, body, params) { if (this.isActive) { let resourceExpire = { entity: array, expire: CacheHelper.expireDate(expireMs) }; this.cacheMap.set(CacheHelper.key(link, body, params), resourceExpire); } } static get(link, body, params) { return this.cacheMap.get(CacheHelper.key(link, body, params)).entity; } static put(link, array, expireMs = 10 * 60 * 1000, body, params) { if (this.isActive) { let resourceExpire = { entity: array, expire: CacheHelper.expireDate(expireMs) }; this.cacheMap.set(CacheHelper.key(link, body, params), resourceExpire); } } static expireDate(expireMs) { if (expireMs == 0) return 0; return Date.now() + expireMs; } static key(link, body, halOptions) { let k = link; if (body) k += body; if (halOptions) k += CacheHelper.toStringParams(halOptions); let key = hash.sha256().update(k).digest('hex'); return key; } static toStringParams(options) { let s = ''; if (options.size) { s = 'size=' + options.size.toString() + '&'; } if (options.notPaged) { s += 'notPaged=true&'; } if (options.params) { options.params.forEach(param => { s += param.key + '=' + param.value + '&'; }); } if (options.sort) { options.sort.forEach(sortInfo => { let sortString = ''; sortString = sortInfo.path ? sortString.concat(sortInfo.path) : sortString; sortString = sortInfo.order ? sortString.concat(',').concat(sortInfo.order) : sortString; s += 'sort' + sortString + '&'; }); } return s; } static evict(key) { this.cacheMap.delete(key); } static evictAll() { this.cacheMap.clear(); } } CacheHelper.cacheMap = new Map(); CacheHelper.isActive = true; // TODO CacheHelper.maxEntries = 100; CacheHelper.evictStrategy = EvictStrategy.EvictTrivial; CacheHelper.defaultExpire = 10 * 60 * 1000; //10 minutes class Resource { constructor() { } get subtypes() { return this._subtypes; } set subtypes(_subtypes) { this._subtypes = _subtypes; } // Get self uri() { if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links['self'])) { return ResourceHelper.getProxy(this._links['self'].href); } else { return null; } } // Get rel uri relURI(rel) { if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[rel])) { return ResourceHelper.getProxy(this._links[rel].href); } else { return null; } } // Get related resource getRelation(type, relation, builder, expireMs = CacheHelper.defaultExpire, isCacheActive = true) { let result = new type(); if (this.existRelationLink(relation)) { if (CacheHelper.ifPresent(this.getRelationLinkHref(relation), null, null, isCacheActive)) { const cached = CacheHelper.get(this.getRelationLinkHref(relation)); return of(cached); } let observable = ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), { headers: ResourceHelper.headers }); return observable.pipe(map((data) => { if (builder) { for (const embeddedClassName of Object.keys(data['_links'])) { if (embeddedClassName == 'self') { let href = data._links[embeddedClassName].href; let idx = href.lastIndexOf('/'); let realClassName = href.replace(ResourceHelper.getRootUri(), '').substring(0, idx); result = ResourceHelper.searchSubtypes(builder, realClassName, result); break; } } } let resource = ResourceHelper.instantiateResource(result, data); CacheHelper.put(this.getRelationLinkHref(relation), resource, expireMs); return resource; })); } else { return of(null); } } addRelations(relation, resources) { if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation])) { let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list'); let uris = resources.map(r => r._links.self.href).join('\n'); return ResourceHelper.getHttp().post(ResourceHelper.getProxy(this._links[relation].href), uris, { headers: header }); } else { return throwError('no relation found'); } } replaceRelations(relation, resources) { if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation])) { let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list'); let uris = resources.map(r => r._links.self.href).join('\n'); return ResourceHelper.getHttp().put(ResourceHelper.getProxy(this._links[relation].href), uris, { headers: header }); } else { return throwError('no relation found'); } } // Get collection of related resources getRelationArray(type, relation, _embedded, options, builder, expireMs = CacheHelper.defaultExpire, isCacheActive = true) { const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options); const result = ResourceHelper.createEmptyResult(Utils.isNullOrUndefined(_embedded) ? '_embedded' : _embedded); if (this.existRelationLink(relation)) { if (CacheHelper.ifPresent(this.getRelationLinkHref(relation), null, options, isCacheActive)) return of(CacheHelper.getArray(this.getRelationLinkHref(relation))); let observable = ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), { headers: ResourceHelper.headers, observe: 'response', params: params, }); return observable .pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, builder)), catchError(error => throwError(error))).pipe(map((array) => { CacheHelper.putArray(this.getRelationLinkHref(relation), array.result, expireMs); return array.result; })); } else { return of([]); } } getProjection(type, resource, id, projectionName, expireMs = CacheHelper.defaultExpire, isCacheActive = true) { const uri = this.getResourceUrl(resource).concat('/', id).concat('?projection=' + projectionName); const result = new type(); if (CacheHelper.ifPresent(uri, null, null, isCacheActive)) { const cached = CacheHelper.get(uri); return of(cached); } let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers }); return observable.pipe(map(data => { let resource = ResourceHelper.instantiateResource(result, data); CacheHelper.put(uri, resource, expireMs); return resource; }), catchError(error => throwError(error))); } getProjectionArray(type, resource, projectionName, expireMs = CacheHelper.defaultExpire, isCacheActive = true) { const uri = this.getResourceUrl(resource).concat('?projection=' + projectionName); const result = ResourceHelper.createEmptyResult('_embedded'); if (CacheHelper.ifPresent(uri, null, null, isCacheActive)) return of(CacheHelper.getArray(uri)); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result)), map((array) => { CacheHelper.putArray(uri, array.result, expireMs); return array.result; })); } getResourceUrl(resource) { let url = ResourceHelper.getURL(); if (!url.endsWith('/')) { url = url.concat('/'); } if (resource) { return url.concat(resource); } url = url.replace('{?projection}', ''); return url; } getRelationLinkHref(relation) { if (this._links[relation].templated) return this._links[relation].href.replace('{?projection}', ''); return this._links[relation].href; } existRelationLink(relation) { return !Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation]); } // Adds the given resource to the bound collection by the relation addRelation(relation, resource) { if (this.existRelationLink(relation)) { let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list'); return ResourceHelper.getHttp().post(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header }); } else { return throwError('no relation found'); } } // Allow for resources that are verbs instead of nouns e.g. payment/changeofaddress etc. postRelation(relation, type, resource = null) { if (this.existRelationLink(relation)) { let observable = ResourceHelper.getHttp().post(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource, { headers: ResourceHelper.headers, observe: 'response' }); const result = new type(); return observable.pipe(map((response) => { return ResourceHelper.instantiateResourceFromResponse(result, response); }), catchError(error => throwError(error))); } else { return throwError('no payment relation found'); } } updateRelation(relation, resource) { if (this.existRelationLink(relation)) { let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list'); return ResourceHelper.getHttp().patch(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header }); } else { return throwError('no relation found'); } } // Bind the given resource to this resource by the given relation substituteRelation(relation, resource) { if (this.existRelationLink(relation)) { let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list'); return ResourceHelper.getHttp().put(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header }); } else { return throwError('no relation found'); } } // Unbind the resource with the given relation from this resource deleteRelation(relation, resource) { if (this.existRelationLink(relation)) { let link = resource._links['self'].href; let idx = link.lastIndexOf('/') + 1; if (idx == -1) return throwError('no relation found'); let relationId = link.substring(idx); return ResourceHelper.getHttp().delete(ResourceHelper.getProxy(this.getRelationLinkHref(relation) + '/' + relationId), { headers: ResourceHelper.headers }); } else { return throwError('no relation found'); } } } Resource.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); Resource.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); // @dynamic class ResourceArray { constructor() { this.totalElements = 0; this.totalPages = 1; this.pageNumber = 1; this.result = []; this.push = (el) => { this.result.push(el); }; this.length = () => { return this.result.length; }; this.init = (type, response, sortInfo) => { const result = ResourceHelper.createEmptyResult(this._embedded); result.sortInfo = sortInfo; ResourceHelper.instantiateResourceCollection(type, response, result); return result; }; // Load next page this.next = (type) => { if (this.next_uri) { return ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.next_uri), { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); } return throwError('no next defined'); }; this.prev = (type) => { if (this.prev_uri) { return ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.prev_uri), { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); } return throwError('no prev defined'); }; // Load first page this.first = (type) => { if (this.first_uri) { return ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.first_uri), { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); } return throwError('no first defined'); }; // Load last page this.last = (type) => { if (this.last_uri) { return ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.last_uri), { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); } return throwError('no last defined'); }; // Load page with given pageNumber this.page = (type, pageNumber) => { this.self_uri = this.self_uri.replace('{?page,size,sort,projection}', ''); this.self_uri = this.self_uri.replace('{&sort}', ''); let urlParsed = url.parse(ResourceHelper.getProxy(this.self_uri)); let query = ResourceArray.replaceOrAdd(urlParsed.query, 'size', this.pageSize.toString()); query = ResourceArray.replaceOrAdd(query, 'page', pageNumber.toString()); let uri = urlParsed.query ? ResourceHelper.getProxy(this.self_uri).replace(urlParsed.query, query) : ResourceHelper.getProxy(this.self_uri).concat(query); uri = this.addSortInfo(uri); return ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); }; // Sort collection based on given sort attribute this.sortElements = (type, ...sort) => { this.self_uri = this.self_uri.replace('{?page,size,sort}', ''); this.self_uri = this.self_uri.replace('{&sort}', ''); let uri = ResourceHelper.getProxy(this.self_uri).concat('?', 'size=', this.pageSize.toString(), '&page=', this.pageNumber.toString()); uri = this.addSortInfo(uri); return ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, sort)), catchError(error => throwError(error))); }; // Load page with given size this.size = (type, size) => { let uri = ResourceHelper.getProxy(this.self_uri).concat('?', 'size=', size.toString()); uri = this.addSortInfo(uri); return ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' }).pipe(map(response => this.init(type, response, this.sortInfo)), catchError(error => throwError(error))); }; } addSortInfo(uri) { if (this.sortInfo) { for (const item of this.sortInfo) { uri = uri.concat('&sort=', item.path, ',', item.order); } } return uri; } static replaceOrAdd(query, field, value) { if (query) { let idx = query.indexOf(field); let idxNextAmp = query.indexOf('&', idx) == -1 ? query.indexOf('/', idx) : query.indexOf('&', idx); if (idx != -1) { let seachValue = query.substring(idx, idxNextAmp); query = query.replace(seachValue, field + '=' + value); } else { query = query.concat("&" + field + '=' + value); } } else { query = "?" + field + '=' + value; } return query; } } // @dynamic class ResourceHelper { static get headers() { if (Utils.isNullOrUndefined(this._headers)) this._headers = new HttpHeaders(); return this._headers; } static set headers(headers) { this._headers = headers; } static optionParams(params, options) { if (options) { params = this.params(params, options.params); if (options.size) { params = params.append('size', options.size.toString()); } if (options.sort) { for (const s of options.sort) { let sortString = ''; sortString = s.path ? sortString.concat(s.path) : sortString; sortString = s.order ? sortString.concat(',').concat(s.order) : sortString; params = params.append('sort', sortString); } } } return params; } static params(httpParams, params) { if (params) { for (const param of params) { httpParams = httpParams.append(param.key, param.value.toString()); } } return httpParams; } static resolveRelations(resource) { const result = {}; for (const key in resource) { if (!Utils.isNullOrUndefined(resource[key])) { if (ResourceHelper.className(resource[key]) .find((className) => className == 'Resource') || resource[key]['_links']) { if (resource[key]['_links']) result[key] = resource[key]['_links']['self']['href']; } else if (Array.isArray(resource[key])) { let array = resource[key]; if (array) { result[key] = new Array(); array.forEach((element) => { if (Utils.isPrimitive(element)) { result[key].push(element); } else { result[key].push(this.resolveRelations(element)); } }); } } else { result[key] = resource[key]; } } } return result; } static createEmptyResult(_embedded) { let resourceArray = new ResourceArray(); resourceArray._embedded = _embedded; return resourceArray; } static getClassName(obj) { var funcNameRegex = /function (.+?)\(/; var results = (funcNameRegex).exec(obj.constructor.toString()); return (results && results.length > 1) ? results[1] : ''; } static className(objProto) { let classNames = []; let obj = Object.getPrototypeOf(objProto); let className; while ((className = ResourceHelper.getClassName(obj)) !== 'Object') { classNames.push(className); obj = Object.getPrototypeOf(obj); } return classNames; } static instantiateResourceFromResponse(entity, response) { if (response.status >= 200 && response.status <= 207) { return ResourceHelper.instantiateResource(entity, response.body); } else if (response.status == 404) { return null; } } static instantiateResourceCollection(type, response, result, builder) { if (response.status >= 200 && response.status <= 207) { let payload = response.body; if (payload[result._embedded]) { for (const embeddedClassName of Object.keys(payload[result._embedded])) { let embedded = payload[result._embedded]; const items = embedded[embeddedClassName]; for (let item of items) { let instance = new type(); instance = this.searchSubtypes(builder, embeddedClassName, instance); this.instantiateResource(instance, item); result.push(instance); } } } result.totalElements = payload.page ? payload.page.totalElements : result.length; result.totalPages = payload.page ? payload.page.totalPages : 1; result.pageNumber = payload.page ? payload.page.number : 1; result.pageSize = payload.page ? payload.page.size : 20; result.self_uri = payload._links && payload._links.self ? payload._links.self.href : undefined; result.next_uri = payload._links && payload._links.next ? payload._links.next.href : undefined; result.prev_uri = payload._links && payload._links.prev ? payload._links.prev.href : undefined; result.first_uri = payload._links && payload._links.first ? payload._links.first.href : undefined; result.last_uri = payload._links && payload._links.last ? payload._links.last.href : undefined; } else if (response.status == 404) { result.result = []; } return result; } static searchSubtypes(builder, embeddedClassName, instance) { if (builder && builder.subtypes) { let keys = builder.subtypes.keys(); Array.from(keys).forEach((subtypeKey) => { if (embeddedClassName.toLowerCase().startsWith(subtypeKey.toLowerCase())) { let subtype = builder.subtypes.get(subtypeKey); instance = new subtype(); } }); } return instance; } static instantiateResource(entity, payload) { for (const p in payload) { //TODO array initClearCacheProcess /* if(entity[p].constructor === Array && isNullOrUndefined(payload[p])) entity[p] = []; else*/ entity[p] = payload[p]; } return entity; } static setProxyUri(proxy_uri) { ResourceHelper.proxy_uri = proxy_uri; } static setRootUri(root_uri) { ResourceHelper.root_uri = root_uri; } static getURL() { return ResourceHelper.proxy_uri && ResourceHelper.proxy_uri != '' ? ResourceHelper.addSlash(ResourceHelper.proxy_uri) : ResourceHelper.addSlash(ResourceHelper.root_uri); } static addSlash(uri) { let uriParsed = url.parse(uri); if (Utils.isNullOrUndefined(uriParsed.search) && uri && uri[uri.length - 1] != '/') return uri + '/'; return uri; } static getProxy(url) { url = url.replace('{?projection}', ''); if (!ResourceHelper.proxy_uri || ResourceHelper.proxy_uri == '') return url; return ResourceHelper.addSlash(ResourceHelper.removeUrlTemplateVars(url) .replace(ResourceHelper.root_uri, ResourceHelper.proxy_uri)); } static removeUrlTemplateVars(url) { return url.replace(ResourceHelper.URL_TEMPLATE_VAR_REGEXP, ResourceHelper.EMPTY_STRING); } static setHttp(http) { this.http = http; } static getHttp() { return this.http; } static getRootUri() { return this.root_uri; } } ResourceHelper.URL_TEMPLATE_VAR_REGEXP = /{[^}]*}/g; ResourceHelper.EMPTY_STRING = ''; class ExternalService { constructor(externalConfigurationService) { this.externalConfigurationService = externalConfigurationService; ResourceHelper.setProxyUri(externalConfigurationService.getProxyUri()); ResourceHelper.setRootUri(externalConfigurationService.getRootUri()); ResourceHelper.setHttp(externalConfigurationService.getHttp()); CacheHelper.initClearCacheProcess(); } updateExternalConfigurationHandlerInterface(externalConfigurationService) { this.externalConfigurationService = externalConfigurationService; ResourceHelper.setProxyUri(externalConfigurationService.getProxyUri()); ResourceHelper.setRootUri(externalConfigurationService.getRootUri()); ResourceHelper.setHttp(externalConfigurationService.getHttp()); } getExternalConfiguration() { return this.externalConfigurationService.getExternalConfiguration(); } getProxyUri() { return this.externalConfigurationService.getProxyUri(); } getRootUri() { return this.externalConfigurationService.getRootUri(); } getURL() { return ResourceHelper.getURL(); } getHttp() { return ResourceHelper.getHttp(); } } ExternalService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ExternalService, deps: [{ token: 'ExternalConfigurationService' }], target: i0.ɵɵFactoryTarget.Injectable }); ExternalService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ExternalService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ExternalService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: ['ExternalConfigurationService'] }] }]; } }); // @dynamic class ResourceService { constructor(externalService) { this.externalService = externalService; } static getURL() { return ResourceHelper.getURL(); } getAll(type, resource, _embedded, options, subType) { const uri = this.getResourceUrl(resource); const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options); const result = ResourceHelper.createEmptyResult(_embedded); this.setUrls(result); result.sortInfo = options ? options.sort : undefined; let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response', params: params, }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, subType)), catchError(error => throwError(error))); } get(type, resource, id, params, builder) { let self = this; const uri = this.getResourceUrl(resource).concat('/', id); let result = new type(); const httpParams = ResourceHelper.params(new HttpParams(), params); this.setUrlsResource(result); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response', params: httpParams, }); // return observable.pipe(map(data => ResourceHelper.instantiateResource(result, data)), // catchError(error => observableThrowError(error)),); return observable.pipe(map((response) => { if (builder) { let linkHref = url.parse(response.body._links.self.href).pathname; let regex = /([A-Za-z0-9]+)\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)/g; let match = regex.exec(linkHref); if (match != null) { let embeddedClassName = match[2]; result = ResourceHelper.searchSubtypes(builder, embeddedClassName, result); } } return ResourceHelper.instantiateResourceFromResponse(result, response); }), catchError(error => throwError(error))); } selfURI(type, resource, id) { return this.getResourceUrl(resource).concat('/', id); } getBySelfLink(type, resourceLink) { const result = new type(); this.setUrlsResource(result); let observable = ResourceHelper.getHttp().get(ResourceHelper.getProxy(resourceLink), { headers: ResourceHelper.headers }); return observable.pipe(map(data => ResourceHelper.instantiateResource(result, data)), catchError(error => throwError(error))); } search(type, query, resource, _embedded, options, subType) { const uri = this.getResourceUrl(resource).concat('/search/', query); const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options); const result = ResourceHelper.createEmptyResult(_embedded); this.setUrls(result); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response', params: params, }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, subType)), catchError(error => throwError(error))); } searchSingle(type, query, resource, options) { const uri = this.getResourceUrl(resource).concat('/search/', query); const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options); const result = new type(); this.setUrlsResource(result); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, params: params }); return observable.pipe(map(response => ResourceHelper.instantiateResource(result, response)), catchError(error => throwError(error))); } customQuery(type, query, resource, _embedded, options, subType) { const uri = this.getResourceUrl(resource + query); const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options); const result = ResourceHelper.createEmptyResult(_embedded); this.setUrls(result); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response', params: params, }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, subType)), catchError(error => throwError(error))); } customQueryPost(type, query, resource, _embedded, options, body, subType) { const uri = this.getResourceUrl(resource + query); const params = ResourceHelper.optionParams(new HttpParams(), options); const result = ResourceHelper.createEmptyResult(_embedded); this.setUrls(result); let observable = ResourceHelper.getHttp().post(uri, body, { headers: ResourceHelper.headers, observe: 'response', params: params, }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, subType)), catchError(error => throwError(error))); } getByRelation(type, resourceLink) { let result = new type(); this.setUrlsResource(result); let observable = ResourceHelper.getHttp().get(resourceLink, { headers: ResourceHelper.headers }); return observable.pipe(map(data => ResourceHelper.instantiateResource(result, data)), catchError(error => throwError(error))); } getByRelationArray(type, resourceLink, _embedded, builder) { const result = ResourceHelper.createEmptyResult(_embedded); this.setUrls(result); let observable = ResourceHelper.getHttp().get(resourceLink, { headers: ResourceHelper.headers, observe: 'response', }); return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, builder)), catchError(error => throwError(error))); } getProjection(type, resource, id, projectionName) { const uri = this.getResourceUrl(resource).concat('/', id).concat('?projection=' + projectionName); const result = new type(); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers }); return observable.pipe(map(data => ResourceHelper.instantiateResource(result, data)), catchError(error => throwError(error))); } getProjectionArray(type, resource, projectionName) { const uri = this.getResourceUrl(resource).concat('?projection=' + projectionName); const result = ResourceHelper.createEmptyResult('_embedded'); let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' }); return observable .pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result)), catchError(error => throwError(error))).pipe(map((resourceArray) => { return resourceArray.result; })); } count(resource, query, options) { const uri = this.getResourceUrl(resource).concat('/search/' + (query === undefined ? 'countAll' : query)); const params = ResourceHelper.optionParams(new HttpParams(), options); return ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response', params: params, }).pipe(map((response) => Number(response.body)), catchError(error => throwError(error))); } create(selfResource, entity) { const uri = ResourceHelper.getURL() + selfResource; const payload = ResourceHelper.resolveRelations(entity); this.setUrlsResource(entity); let observable = ResourceHelper.getHttp().post(uri, payload, { headers: ResourceHelper.headers, observe: 'response', }); return observable.pipe(map((response) => { if (response.status >= 200 && response.status <= 207) return ResourceHelper.instantiateResource(entity, response.body); else if (response.status == 500) { let body = response.body; return throwError(body.error); } }), catchError(error => throwError(error))); } query(resource, query, options) { const uri = this.getResourceUrl(resource).concat('/search/', query); const params = ResourceHelper.optionParams(new HttpParams(), options); return ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, params: params }).pipe(map(response => response), catchError(error => throwError(error))); } update(entity) { const uri = ResourceHelper.getProxy(entity._links.self.href); const payload = ResourceHelper.resolveRelations(entity); this.setUrlsResource(entity); let observable = ResourceHelper.getHttp().put(uri, payload, { headers: ResourceHelper.headers, observe: 'response' }); return observable.pipe(map((response) => { if (response.status >= 200 && response.status <= 207) return ResourceHelper.instantiateResource(entity, response.body); else if (response.status == 500) { let body = response.body; return throwError(body.error); } }), catchError(error => throwError(error))); } patch(entity) { const uri = ResourceHelper.getProxy(entity._links.self.href); const payload = ResourceHelper.resolveRelations(entity); this.setUrlsResource(entity); let observable = ResourceHelper.getHttp().patch(uri, payload, { headers: ResourceHelper.headers, observe: 'response' }); return observable.pipe(map((response) => { if (response.status >= 200 && response.status <= 207) return ResourceHelper.instantiateResource(entity, response.body); else if (response.status == 500) { let body = response.body; return throwError(body.error); } }), catchError(error => throwError(error))); } delete(entity) { const uri = ResourceHelper.getProxy(entity._links.self.href); return ResourceHelper.getHttp().delete(uri, { headers: ResourceHelper.headers }).pipe(catchError(error => throwError(error))); } hasNext(resourceArray) { return resourceArray.next_uri != undefined; } hasPrev(resourceArray) { return resourceArray.prev_uri != undefined; } hasFirst(resourceArray) { return resourceArray.first_uri != undefined; } hasLast(resourceArray) { return resourceArray.last_uri != undefined; } next(resourceArray, type) { return resourceArray.next(type); } prev(resourceArray, type) { return resourceArray.prev(type); } first(resourceArray, type) { return resourceArray.first(type); } last(resourceArray, type) { return resourceArray.last(type); } page(resourceArray, type, id) { return resourceArray.page(type, id); } sortElements(resourceArray, type, ...sort) { return resourceArray.sortElements(type, ...sort); } size(resourceArray, type, size) { return resourceArray.size(type, size); } getResourceUrl(resource) { let url = ResourceService.getURL(); if (!url.endsWith('/')) { url = url.concat('/'); } if (resource) { return url.concat(resource); } url = url.replace('{?projection}', ''); return url; } setUrls(result) { result.proxyUrl = this.externalService.getProxyUri(); result.rootUrl = this.externalService.getRootUri(); } setUrlsResource(result) { result.proxyUrl = this.externalService.getProxyUri(); result.rootUrl = this.externalService.getRootUri(); } } ResourceService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ResourceService, deps: [{ token: ExternalService }], target: i0.ɵɵFactoryTarget.Injectable }); ResourceService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ResourceService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ResourceService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: ExternalService }]; } }); const TokenConfigService = new InjectionToken("TokenConfig"); class Auth { } class AuthInterceptor { constructor(config) { this.config = config; } intercept(request, next) { // add authorization header with jwt token if available if (this.config) { const token = Object.assign(Auth, JSON.parse(sessionStorage.getItem(this.config.token))); if (token && !request.url.endsWith('oauth/token')) { const headers = new HttpHeaders({ 'Authorization': 'Bearer ' + token.access_token, 'Content-Type': 'application/json' }); request = request.clone({ headers }); } } return next.handle(request); } } AuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AuthInterceptor, deps: [{ token: TokenConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); AuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AuthInterceptor }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AuthInterceptor, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [TokenConfigService] }] }]; } }); class AngularHalModule { static forRoot(tokenConfig) { return { ngModule: AngularHalModule, providers: [ ExternalService, HttpClient, { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true, deps: [TokenConfigService], }, { provide: TokenConfigService, useValue: tokenConfig == null ? '' : tokenConfig, }, { provide: ResourceService, useClass: ResourceService, deps: [ExternalService], }, ], }; } } AngularHalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AngularHalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); AngularHalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: AngularHalModule, imports: [HttpClientModule], exports: [HttpClientModule] }); AngularHalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AngularHalModule, providers: [ ExternalService, HttpClient, { provide: ResourceService, useClass: ResourceService, deps: [ExternalService], } ], imports: [HttpClientModule, HttpClientModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: AngularHalModule, decorators: [{ type: NgModule, args: [{ imports: [HttpClientModule], declarations: [], exports: [HttpClientModule], providers: [ ExternalService, HttpClient, { provide: ResourceService, useClass: ResourceService, deps: [ExternalService], } ], }] }] }); // @dynamic class RestService { constructor(type, resource, injector, _embedded) { this.injector = injector; this._embedded = '_embedded'; this.type = type; this.resource = resource; this.resourceService = injector.get(ResourceService); if (!Utils.isNullOrUndefined(_embedded)) this._embedded = _embedded; } handleError(error) { return RestService.handleError(error); } static handleError(error) { return throwError(error); } getAll(options, subType) { return this.resourceService.getAll(this.type, this.resource, this._embedded, options, subType).pipe(mergeMap((resourceArray) => { if (options && options.notPaged && !Utils.isNullOrUndefined(resourceArray.first_uri)) { options.notPaged = false; options.size = resourceArray.totalElements; return this.getAll(options); } else { this.resourceArray = resourceArray; return of(resourceArray.result); } })); } get(id, params, builder) { return this.resourceService.get(this.type, this.resource, id, params, builder); } selfURI(id) { return this.resourceService.selfURI(this.type, this.resource, id); } getBySelfLink(selfLink) { return this.resourceService.getBySelfLink(this.type, selfLink); } search(query, options, subType) { return this.resourceService.search(this.type, query, this.resource, this._embedded, options, subType).pipe(mergeMap((resourceArray) => { if (options && options.notPaged && !Utils.isNullOrUndefined(resourceArray.first_uri)) { options.notPaged = false; options.size = resourceArray.totalElements; return this.search(query, options, subType); } else { this.resourceArray = resourceArray; return of(resourceArray.result); } })); } query(query, options) { return this.resourceService.query(this.resource, query, options); } searchSingle(query, options) { return this.resourceService.searchSingle(this.type, query, this.resource, options); } customQuery(query, options, subType) { return this.resourceService.customQuery(this.type, query, this.resource, this._embedded, options, subType).pipe(mergeMap((resourceArray) => { if (options && options.notPaged && !Utils.isNullOrUndefined(resourceArray.first_uri)) { options.notPaged = false; options.size = resourceArray.totalElements; return this.customQuery(query, options, subType); } else { this.resourceArray = resourceArray; return of(resourceArray.result); } })); } customQueryPost(query, options, body, subType) { return this.resourceService.customQueryPost(this.type, query, this.resource, this._embedded, options, body, subType).pipe(mergeMap((resourceArray) => { if (options && options.notPaged && !Utils.isNullOrUndefined(resourceArray.first_uri)) { options.notPaged = false; options.size = resourceArray.totalElements; return this.customQueryPost(query, options, body, subType); } else { this.resourceArray = resourceArray; return of(resourceArray.result); } })); } getByRelationArray(relation, builder) { return this.resourceService.getByRelationArray(this.type, relation, this._embedded, builder).pipe(map((resourceArray) => { this.resourceArray = resourceArray; return resourceArray.result; })); } getByRelation(relation) { return this.resourceService.getByRelation(this.type, relation); } count(query, options) { return this.resourceService.count(this.resource, query, options); } create(entity) { return this.resourceService.create(this.resource, entity); } update(entity) { return this.resourceService.update(entity); } patch(entity) { return this.resourceService.patch(entity); } delete(entity) { return this.resourceService.delete(entity); } totalElement() { if (this.resourceArray && this.resou