UNPKG

@mgrcto/angular-odata-v401

Version:

Odata Library for Angular made with Angular CLI

726 lines (714 loc) 27 kB
import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { NgModule, Injectable } from '@angular/core'; import { throwError } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import * as i1 from '@angular/common/http'; import { HttpParams, HttpHeaders } from '@angular/common/http'; class AngularOdataV401Module { static forRoot() { return { ngModule: AngularOdataV401Module }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AngularOdataV401Module, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: AngularOdataV401Module, imports: [CommonModule] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AngularOdataV401Module, imports: [CommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AngularOdataV401Module, decorators: [{ type: NgModule, args: [{ declarations: [], imports: [CommonModule ], exports: [] }] }] }); class ODataOperation { constructor(typeName, config, http) { this.typeName = typeName; this.config = config; this.http = http; this._expand = []; this._select = []; } Expand(expand) { if (expand) { this._expand = this.toStringArray(expand); } return this; } /** * Selects Entities. If String is separated by "/" the first part will be expanded and the second part will be selected in the expand. * @param select * @returns ODataOperation<T> */ Select(select) { if (select) { this._select = this.toStringArray(select); } return this; } getParams(aParams) { const expandData = new Map(); const normalSelects = []; this._expand.forEach((name) => expandData.set(name, [])); this._select.forEach((select) => { const items = select.split('/'); // Select contains string like: `Boss/Name` if (items.length > 1) { const expandName = items[0]; const propertyName = items[1]; if (!expandData.has(expandName)) { expandData.set(expandName, []); } expandData.get(expandName).push(propertyName); } else { // Select is just a simple string like: `Boss` normalSelects.push(select); } }); let params = (aParams && Object.keys(aParams).length > 0) ? aParams : new HttpParams(); const expands = []; expandData.forEach((val, key) => { if (val.length) { expands.push(`${key}(${this.config.keys.select}=${this.toCommaString(val)})`); return; } expands.push(key); }); if (expands.length) { params = params.append(this.config.keys.expand, this.toCommaString(expands)); } if (normalSelects.length) { params = params.append(this.config.keys.select, this.toCommaString(normalSelects)); } return params; } handleResponse(entity) { return entity .pipe(map(this.extractData), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } getDefaultRequestOptions() { const options = Object.assign({}, this.config.defaultRequestOptions); options.params = this.getParams(options.params); return options; } getPostRequestOptions() { const options = Object.assign({}, this.config.postRequestOptions); options.params = this.getParams(options.params); return options; } GeneratePostUrl(entitiesUri) { const params = this.getParams(this.config.postRequestOptions.params); if (params.keys().length > 0) { return `${entitiesUri}?${params}`; } return entitiesUri; } GenerateUrl(entitiesUri) { const params = this.getParams(this.config.defaultRequestOptions.params); if (params.keys().length > 0) { return `${entitiesUri}?${params}`; } return entitiesUri; } toStringArray(input) { if (!input) { return []; } if (input instanceof String || typeof input === 'string') { return input.split(',').map(s => s.trim()); } if (input instanceof Array) { return input; } return []; } toCommaString(input) { if (input instanceof String || typeof input === 'string') { return input; } if (input instanceof Array) { return input.join(); } return ""; } extractData(res) { if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } const body = res.body; return body || {}; } } class OperationWithKey extends ODataOperation { constructor(_typeName, config, http, entityKey) { super(_typeName, config, http); this._typeName = _typeName; this.config = config; this.http = http; this.entityKey = entityKey; } getEntityUri() { return this.config.getEntityUri(this.entityKey, this.typeName); } GetUrl() { return this.GenerateUrl(this.getEntityUri()); } } class OperationWithEntity extends ODataOperation { constructor(_typeName, config, http, entity) { super(_typeName, config, http); this._typeName = _typeName; this.config = config; this.http = http; this.entity = entity; } getEntitiesUri() { return this.config.getEntitiesUri(this._typeName); } GetUrl() { return this.GenerateUrl(this.getEntitiesUri()); } } class OperationWithKeyAndEntity extends OperationWithKey { constructor(_typeName, config, http, entityKey, entity) { super(_typeName, config, http, entityKey); this._typeName = _typeName; this.config = config; this.http = http; this.entityKey = entityKey; this.entity = entity; } getEntityUri() { return this.config.getEntityUri(this.entityKey, this._typeName); } } class GetOperation extends OperationWithKey { Exec() { return super.handleResponse(this.http.get(this.getEntityUri(), this.getDefaultRequestOptions())); } } class PostOperation extends OperationWithEntity { Exec() { const body = this.entity ? JSON.stringify(this.entity) : null; return super.handleResponse(this.http.post(this.getEntitiesUri(), body, this.getPostRequestOptions())); } GetUrl() { return this.GeneratePostUrl(this.getEntitiesUri()); } } class PatchOperation extends OperationWithKeyAndEntity { Exec() { const body = this.entity ? JSON.stringify(this.entity) : null; return super.handleResponse(this.http.patch(this.getEntityUri(), body, this.getPostRequestOptions())); } GetUrl() { return this.GeneratePostUrl(this.getEntityUri()); } } class PutOperation extends OperationWithKeyAndEntity { Exec() { const body = this.entity ? JSON.stringify(this.entity) : null; return super.handleResponse(this.http.put(this.getEntityUri(), body, this.getPostRequestOptions())); } GetUrl() { return this.GeneratePostUrl(this.getEntityUri()); } } class DeleteOperation extends OperationWithKey { Exec() { return super.handleResponse(this.http.delete(this.getEntityUri(), this.config.defaultRequestOptions)); } } var ODataExecReturnType; (function (ODataExecReturnType) { // Default ODataExecReturnType[ODataExecReturnType["Array"] = 0] = "Array"; ODataExecReturnType[ODataExecReturnType["Count"] = 1] = "Count"; ODataExecReturnType[ODataExecReturnType["PagedResult"] = 2] = "PagedResult"; ODataExecReturnType[ODataExecReturnType["MetadataResult"] = 3] = "MetadataResult"; })(ODataExecReturnType || (ODataExecReturnType = {})); class ODataQuery extends ODataOperation { constructor(typeName, config, http) { super(typeName, config, http); this._filter = ""; this._top = 0; this._skip = 0; this._search = ""; this._orderBy = []; this._apply = []; this._maxPerPage = 0; this._customQueryOptions = []; this._customQueryHeaders = []; this._entitiesUri = config.getEntitiesUri(this.typeName); } Filter(filter) { if (filter) { this._filter = filter; } return this; } Search(search) { if (search) { this._search = search; } return this; } Top(top) { if (top > -1) { this._top = top; } return this; } Skip(skip) { if (skip > -1) { this._skip = skip; } return this; } OrderBy(orderBy) { if (orderBy) { this._orderBy = this.toStringArray(orderBy); } return this; } MaxPerPage(maxPerPage) { if (maxPerPage > -1) { this._maxPerPage = maxPerPage; } return this; } Apply(apply) { if (apply) { this._apply = this.toStringArray(apply); } return this; } CustomQueryOptions(customOptions) { if (customOptions) { this._customQueryOptions = Array.isArray(customOptions) ? customOptions : [customOptions]; } return this; } CustomQueryHeaders(customHeaders) { if (customHeaders) { this._customQueryHeaders = Array.isArray(customHeaders) ? customHeaders : [customHeaders]; } return this; } GetUrl(returnType) { let url = this._entitiesUri; if (returnType === ODataExecReturnType.Count) { url = `${url}/${this.config.keys.count}`; } const params = this.getQueryParams(this.config.defaultRequestOptions.params); if (params.keys().length > 0) { return `${url}?${params}`; } return url; } Exec(returnType) { const requestOptions = this.getQueryRequestOptions(returnType); switch (returnType) { case ODataExecReturnType.Count: return this.execGetCount(requestOptions); case ODataExecReturnType.PagedResult: return this.execGetArrayDataWithCount(this._entitiesUri, requestOptions); case ODataExecReturnType.MetadataResult: return this.execGetArrayDataWithMetadata(this._entitiesUri, requestOptions); default: return this.execGetArrayData(requestOptions); } } ExecWithCount() { return this.Exec(ODataExecReturnType.PagedResult); } NextPage(pagedResult) { const requestOptions = this.getQueryRequestOptions(ODataExecReturnType.PagedResult); return this.execGetArrayDataWithCount(pagedResult.nextLink, requestOptions); } execGetCount(requestOptions) { const countUrl = `${this._entitiesUri}/${this.config.keys.count}`; return this.http.get(countUrl, requestOptions) .pipe(map(res => this.extractDataAsNumber(res, this.config)), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } execGetArrayDataWithCount(url, requestOptions) { return this.http.get(url, requestOptions) .pipe(map(res => this.extractArrayDataWithCount(res, this.config)), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } execGetArrayDataWithMetadata(url, requestOptions) { return this.http.get(url, requestOptions) .pipe(map(res => this.extractArrayDataWithMetadata(res, this.config)), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } execGetArrayData(requestOptions) { return this.http.get(this._entitiesUri, requestOptions) .pipe(map(res => this.extractArrayData(res, this.config)), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } getQueryRequestOptions(returnType) { const options = Object.assign({}, this.config.defaultRequestOptions); options.params = this.getQueryParams(options.params); options.headers = this.getQueryHeaders(options.headers, returnType); return options; } getQueryHeaders(headers, returnType) { if (!headers) { headers = new HttpHeaders(); } if (this._maxPerPage > 0) { headers = headers.set('Prefer', `${this.config.keys.maxPerPage}=${this._maxPerPage}`); } headers = headers.set(`${this.config.keys.metadata}`, `${(returnType && returnType >= ODataExecReturnType.PagedResult) ? 'full' : 'none'}`); if (this._customQueryHeaders.length > 0) { this._customQueryHeaders.forEach(customQueryHeader => { headers = headers.set(customQueryHeader.key, customQueryHeader.value); }); } return headers; } getQueryParams(aParams) { let params = super.getParams(aParams); if (this._filter) { params = params.append(this.config.keys.filter, this._filter); } if (this._search) { params = params.append(this.config.keys.search, this._search); } if (this._top > 0) { params = params.append(this.config.keys.top, this._top.toString()); } if (this._skip > 0) { params = params.append(this.config.keys.skip, this._skip.toString()); } if (this._orderBy.length > 0) { params = params.append(this.config.keys.orderBy, this.toCommaString(this._orderBy)); } if (this._apply.length > 0) { params = params.append(this.config.keys.apply, this.toCommaString(this._apply)); } if (this._customQueryOptions.length > 0) { this._customQueryOptions.forEach(customQueryOption => (params = params.append(this.checkReservedCustomQueryOptionKey(customQueryOption.key), customQueryOption.value))); } return params; } extractDataAsNumber(res, config) { return config.extractQueryResultDataAsNumber(res); } extractArrayData(res, config) { return config.extractQueryResultData(res); } extractArrayDataWithCount(res, config) { return config.extractQueryResultDataWithCount(res); } extractArrayDataWithMetadata(res, config) { return config.extractQueryResultDataWithMetadata(res); } checkReservedCustomQueryOptionKey(key) { if (key === null || key === undefined) { throw new Error('Custom query options MUST NOT be null or undefined.'); } if (key.indexOf('$') === 0 || key.indexOf('@') === 0) { throw new Error('Custom query options MUST NOT begin with a $ or @ character.'); } return key; } } class ODataUtils { static convertObjectToString(obj) { const properties = []; for (const prop in obj) { if (obj.hasOwnProperty(prop) && obj[prop] !== undefined) { const value = ODataUtils.quoteValue(obj[prop]); properties.push(`${prop}=${value}`); } } return properties.join(', '); } static quoteValue(value) { // check if GUID (UUID) type if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) { return value; } // check if string if (typeof value === 'string') { const escaped = value.replace(/'/g, '\'\''); return `'${escaped}'`; } // check if boolean or number if (typeof value === 'boolean' || typeof value === 'number') { return `${value}`; } const parts = []; Object.getOwnPropertyNames(value).forEach((propertyName) => { const propertyValue = value[propertyName]; parts.push(`${propertyName}=${ODataUtils.quoteValue(propertyValue)}`); }); return parts.length > 0 ? parts.join(', ') : `${value}`; } static tryParseInt(input) { if (input !== null && !isNaN(input)) { const parsed = parseInt(input, 10); return { valid: !isNaN(parsed), value: parsed }; } return { valid: false, value: NaN }; } } class ODataService { constructor(_typeName, _http, config) { this._typeName = _typeName; this._http = _http; this.config = config; this._entitiesUri = config.getEntitiesUri(_typeName); } get TypeName() { return this._typeName; } Get(key) { return new GetOperation(this._typeName, this.config, this._http, key); } Post(entity) { return new PostOperation(this._typeName, this.config, this._http, entity); } Patch(entity, key) { return new PatchOperation(this._typeName, this.config, this._http, key, entity); } Put(entity, key) { return new PutOperation(this._typeName, this.config, this._http, key, entity); } Delete(key) { return new DeleteOperation(this._typeName, this.config, this._http, key); } CustomAction(key, actionName, postdata) { const body = postdata ? JSON.stringify(postdata) : null; return this._http.post(`${this.getEntityUri(key)}/${actionName}`, body, this.config.customRequestOptions).pipe(map(resp => resp)); } CustomCollectionAction(actionName, postdata) { const body = postdata ? JSON.stringify(postdata) : null; return this._http.post(`${this._entitiesUri}/${actionName}`, body, this.config.customRequestOptions).pipe(map(resp => resp)); } CustomFunction(key, functionName, parameters) { if (parameters) { const params = ODataUtils.convertObjectToString(parameters); functionName = `${functionName}(${params})`; } else if (!functionName.endsWith(')') && !functionName.endsWith('()')) { functionName = `${functionName}()`; } return this._http.get(`${this.getEntityUri(key)}/${functionName}`, this.config.defaultRequestOptions).pipe(map(resp => resp)); } CustomCollectionFunction(functionName, parameters) { if (parameters) { const params = ODataUtils.convertObjectToString(parameters); functionName = `${functionName}(${params})`; } else if (!functionName.endsWith(')') && !functionName.endsWith('()')) { functionName = `${functionName}()`; } return this._http.get(`${this._entitiesUri}/${functionName}`, this.config.defaultRequestOptions).pipe(map(resp => resp)); } getNestedEntityService(key, typeName) { let nestedTypeName = `${this.config.getEntityPath(key, this._typeName)}/${typeName}`; return new ODataService(nestedTypeName, this._http, this.config); } ItemProperty(key, propertyName) { return this._http.get(`${this.getEntityUri(key)}/${propertyName}`, this.config.defaultRequestOptions) .pipe(map(r => r.body)); } Query() { return new ODataQuery(this.TypeName, this.config, this._http); } getEntityUri(key) { return this.config.getEntityUri(key, this._typeName); } handleResponse(entity) { return entity .pipe(map(this.extractData), catchError((err, caught) => { if (this.config.handleError) { this.config.handleError(err, caught); } return throwError(err); })); } extractData(res) { if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } const body = res.body; return body || {}; } } class KeyConfigs { constructor() { this.filter = '$filter'; this.top = '$top'; this.skip = '$skip'; this.orderBy = '$orderby'; this.select = '$select'; this.search = '$search'; this.expand = '$expand'; this.apply = '$apply'; this.count = '$count'; this.maxPerPage = 'odata.maxpagesize'; this.metadata = 'odata.metadata'; this.responseCount = '@odata.count'; this.responseNextLink = '@odata.nextLink'; } } class ODataConfiguration { constructor() { this._postHeaders = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' }); this._baseUrl = 'http://localhost/odata'; this.keys = new KeyConfigs(); this.defaultRequestOptions = { headers: new HttpHeaders(), observe: 'response' }; this.postRequestOptions = { headers: this._postHeaders, observe: 'response' }; this.customRequestOptions = { headers: new HttpHeaders(), observe: 'response' }; } set baseUrl(baseUrl) { this._baseUrl = baseUrl.replace(/\/+$/, ''); } get baseUrl() { return this._baseUrl; } getEntitiesUri(typeName) { if (typeName) { return `${this.baseUrl}/${this.sanitizeTypeName(typeName)}`; } return this.baseUrl; } getEntityUri(key, typeName) { return `${this.getEntitiesUri(typeName)}(${ODataUtils.quoteValue(key)})`; } getEntityPath(key, typeName) { return `${this.sanitizeTypeName(typeName)}(${ODataUtils.quoteValue(key)})`; } handleError(err, caught) { console.warn('OData error: ', err, caught); } extractQueryResultDataAsNumber(res) { if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } return (res && res.body); } extractQueryResultData(res) { if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } return (res && res.body && res.body.value); } extractQueryResultDataWithCount(res) { let pagedResult; if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } const body = res.body; let entities = body.value; delete body.value; if (!Array.isArray(entities)) { entities = []; } pagedResult = body; pagedResult.data = entities; const parseResult = ODataUtils.tryParseInt(body[`${this.keys.responseCount}`]); if (parseResult.valid) { pagedResult.count = parseResult.value; } else { console.warn('Cannot determine OData entities count. Falling back to collection length.'); pagedResult.count = entities.length; } if (body[`${this.keys.responseNextLink}`]) { pagedResult.nextLink = body[`${this.keys.responseNextLink}`]; } return pagedResult; } extractQueryResultDataWithMetadata(res) { let result; if (res.status < 200 || res.status >= 300) { throw new Error('Bad response status: ' + res.status); } const body = res.body; let entities = body.value; delete body.value; if (!Array.isArray(entities)) { entities = []; } result = body; result.data = entities; const parseResult = ODataUtils.tryParseInt(body[`${this.keys.responseCount}`]); if (parseResult.valid) { result.count = parseResult.value; } else { console.warn('Cannot determine OData entities count. Falling back to collection length.'); result.count = entities.length; } if (body[`${this.keys.responseNextLink}`]) { result.nextLink = body[`${this.keys.responseNextLink}`]; } return result; } sanitizeTypeName(typeName) { return typeName.replace(/\/+$/, '').replace(/^\/+/, ''); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataConfiguration }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataConfiguration, decorators: [{ type: Injectable }] }); class ODataServiceFactory { constructor(http, config) { this.http = http; this.config = config; } CreateService(typeName, config) { return new ODataService(typeName, this.http, config ? config : this.config); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataServiceFactory, deps: [{ token: i1.HttpClient }, { token: ODataConfiguration }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataServiceFactory }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ODataServiceFactory, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.HttpClient }, { type: ODataConfiguration }] }); /* * Public API Surface of angular-odata-v401 */ /** * Generated bundle index. Do not edit. */ export { AngularOdataV401Module, DeleteOperation, GetOperation, ODataConfiguration, ODataExecReturnType, ODataOperation, ODataQuery, ODataService, ODataServiceFactory, OperationWithEntity, OperationWithKey, OperationWithKeyAndEntity, PatchOperation, PostOperation, PutOperation }; //# sourceMappingURL=mgrcto-angular-odata-v401.mjs.map