UNPKG

@ngx-resource/core

Version:
503 lines 69.1 kB
import { __decorate, __metadata, __param } from "tslib"; import { Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; import { ResourceActionReturnType, ResourceRequestBodyType, ResourceRequestMethod } from './Declarations'; import { ResourceGlobalConfig } from './ResourceGlobalConfig'; import { ResourceHelper } from './ResourceHelper'; import { ResourceHandler } from './ResourceHandler'; import { ResourceModule } from './ResourceModule'; import { Optional } from '@angular/core'; let Resource = class Resource { get requestHandler() { if (!this._requestHandler) { if (!ResourceModule.injector) { throw new Error('ResourceModule.injector is missing'); } this._requestHandler = ResourceModule.injector.get(ResourceHandler); if (!this._requestHandler) { throw new Error('ResourceHandler provider is missing'); } } return this._requestHandler; } constructor(requestHandler) { this.$url = null; this.$pathPrefix = null; this.$path = null; this.$headers = null; this.$body = null; this.$params = null; this.$query = null; // tslint:disable-next-line:variable-name this._requestHandler = null; if (requestHandler) { this._requestHandler = requestHandler; } this.constructor.instance = this; } /** * Used to get url */ $getUrl(actionOptions = {}) { return this.$url || actionOptions.url || ResourceGlobalConfig.url || ''; } $setUrl(url) { this.$url = url; } /** * Used to get path prefix */ $getPathPrefix(actionOptions = {}) { return this.$pathPrefix || actionOptions.pathPrefix || ResourceGlobalConfig.pathPrefix || ''; } $setPathPrefix(path) { this.$pathPrefix = path; } /** * Used to get path */ $getPath(actionOptions = {}) { return this.$path || actionOptions.path || ResourceGlobalConfig.path || ''; } $setPath(path) { this.$path = path; } /** * Get headers. */ $getHeaders(actionOptions = {}) { return this.$headers || actionOptions.headers || ResourceGlobalConfig.headers || {}; } $setHeaders(headers) { this.$headers = headers; } /** * Get body */ $getBody(actionOptions = {}) { return this.$body || actionOptions.body || ResourceGlobalConfig.body || {}; } $setBody(body) { this.$body = body; } /** * Get path params */ $getParams(actionOptions = {}) { return this.$params || actionOptions.params || ResourceGlobalConfig.params || {}; } $setParams(params) { this.$params = params; } /** * Get query params */ $getQuery(actionOptions = {}) { return this.$query || actionOptions.query || ResourceGlobalConfig.query || {}; } $setQuery(query) { this.$query = query; } /** * Used to filter received data. * Is applied on each element of array or object */ $filter(data, options = {}) { return true; } /** * Used to map received data * Is applied on each element of array or object */ $map(data, options = {}) { return data; } /** * Used to create result object * Is applied on each element of array or object */ $resultFactory(data, options = {}) { return data == null ? {} : data; } $restAction(options) { this.$_setResourceActionInnerDefaults(options); this.$_setResourceActionOptionDefaults(options); if (!options.actionOptions) { throw new Error('Action options are not set'); } const actionOptions = options.actionOptions; if (!actionOptions.resultFactory) { throw new Error('Action options resultFactory is not set'); } if (!options.actionAttributes) { throw new Error('Action attributes is not set'); } if (actionOptions.mutateBody || options.isModel) { options.returnData = options.actionAttributes.body; } if (actionOptions.returnAs === ResourceActionReturnType.Resource) { options.returnData = actionOptions.expectJsonArray ? [] : actionOptions.resultFactory.call(this, null, options); } if (this.$_canSetInternalData(options)) { ResourceHelper.defineReturnDataPropertiesResolvedAbort(options.returnData); } options.mainObservable = this.$_createMainObservable(options); if (this.$_canSetInternalData(options)) { ResourceHelper.defineReturnDataPropertiesPromise(options.returnData, this.$_createPromise(options)); } switch (actionOptions.returnAs) { case ResourceActionReturnType.Observable: return options.mainObservable; case ResourceActionReturnType.Promise: return this.$_createPromise(options); default: return options.returnData; } } /** * Converts observable to promise and ads abort method */ $_createPromise(options) { if (!options.promise) { options.promise = new Promise((resolve, reject) => { if (!options.mainObservable) { reject(new Error('$_createPromise options.mainObservable missing')); return; } options.subscription = options.mainObservable.subscribe(resolve, error => { reject(error); options.subscription = null; }, () => { options.subscription = null; }); ResourceHelper.createNewAbortMethod(options); }); } return options.promise; } /** * Creates main request observable */ $_createMainObservable(options) { const requestPreparationPromise = this.$_setResolvedOptions(options) .then((o) => this.$_createRequestOptions(o)); return of(requestPreparationPromise) .pipe(switchMap((oPromise) => { return oPromise .then((o) => { if (!o.requestOptions) { throw new Error('IResourceActionInner miss request options'); } const handlerResp = this.requestHandler.handle(o.requestOptions); if (o.returnData && this.$_canSetInternalData(options)) { o.returnData.$abort = handlerResp.abort; } if (handlerResp.observable) { return handlerResp.observable; } return handlerResp.promise; }); }), switchMap(s => s instanceof Observable ? s : of(s)), map((resp) => this.$handleSuccessResponse(options, resp)), catchError((resp) => { throw this.$handleErrorResponse(options, resp); })); } /** * Success response handler */ $handleSuccessResponse(options, resp) { let body = resp.body; if (Array.isArray(body)) { body = this.$prepareSuccessResponseBodyArray(body, options); } else { body = this.$prepareSuccessResponseBodyObject(body, options); } if (this.$_canSetInternalData(options)) { options.returnData.$resolved = true; } if (options.actionOptions && options.actionOptions.asResourceResponse) { resp.body = body; body = resp; } if (options.actionAttributes && options.actionAttributes.onSuccess) { options.actionAttributes.onSuccess(body); } return body; } /** * Prepare success response body as array */ $prepareSuccessResponseBodyArray(body, options) { if (!options.actionOptions) { throw new Error('$prepareSuccessResponseBodyArray options.actionOptions missing'); } const actionOptions = options.actionOptions; body = body .filter((item) => { return actionOptions.filter ? actionOptions.filter.call(this, item, options) : true; }) .map((item) => { if (actionOptions.map) { item = actionOptions.map.call(this, item, options); } return actionOptions.resultFactory ? actionOptions.resultFactory.call(this, item, options) : item; }); if (options.returnData) { Array.prototype.push.apply(options.returnData, body); body = options.returnData; } return body; } /** * Prepare success response body as object */ $prepareSuccessResponseBodyObject(body, options) { if (!options.actionOptions) { throw new Error('$prepareSuccessResponseBodyObject options.actionOptions missing'); } const actionOptions = options.actionOptions; if (actionOptions.filter && !actionOptions.filter.call(this, body, options)) { return null; } if (actionOptions.map) { body = actionOptions.map.call(this, body, options); } let newBody = options.returnData; if (newBody) { if (typeof newBody.$setData === 'function') { newBody.$setData(body); } else { Object.assign(newBody, body); } } else { newBody = actionOptions.resultFactory ? actionOptions.resultFactory.call(this, body, options) : body; } body = newBody; // If it's model if (body.$resource) { body.$resolved = true; body.$promise = options.mainObservable; body.$abort = () => true; } return body; } /** * Handle error */ $handleErrorResponse(options, resp) { if (options.returnData && this.$_canSetInternalData(options)) { options.returnData.$resolved = true; } if (options.actionAttributes && options.actionAttributes.onError) { options.actionAttributes.onError(resp); } throw resp; } /** * Sets request options url */ $setRequestOptionsUrl(options) { const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options); const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options); const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options); if (!requestOptions.url) { requestOptions.url = (resolvedOptions.url || '') + (resolvedOptions.pathPrefix || '') + (resolvedOptions.path || ''); } options.usedInPath = {}; ResourceHelper.setRequestOptionsUrlParams(requestOptions, resolvedOptions, actionAttributes, options.usedInPath); // Removing double slashed from final url requestOptions.url = requestOptions.url.replace(/\/\/+/g, '/'); if (requestOptions.url.startsWith('http')) { requestOptions.url = requestOptions.url.replace(':/', '://'); } // Remove trailing slash if (options.actionOptions && options.actionOptions.removeTrailingSlash) { while (requestOptions.url[requestOptions.url.length - 1] === '/') { requestOptions.url = requestOptions.url.substr(0, requestOptions.url.length - 1); } } } $setRequestOptionsBody(options) { const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options); const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options); let body = actionAttributes.body; if (!body) { return; } const realBodyType = ResourceHelper.getRealTypeOf(body); let bodyOk = realBodyType === actionOptions.requestBodyType; if (!bodyOk && realBodyType === ResourceRequestBodyType.JSON && actionOptions.requestBodyType === ResourceRequestBodyType.FORM_DATA) { body = ResourceHelper.createRequestOptionsFormDataBody(body, actionOptions); bodyOk = true; } if (!bodyOk) { throw new Error('Can not convert body'); } if (!(body instanceof FormData)) { // Add root node if needed if (actionOptions.rootNode) { const newBody = {}; newBody[actionOptions.rootNode] = body; body = newBody; } if ((actionOptions.requestBodyType === ResourceRequestBodyType.NONE || (actionOptions.requestBodyType === ResourceRequestBodyType.JSON && typeof body === 'object' && Object.keys(body).length === 0)) && !actionOptions.keepEmptyBody) { return; } } requestOptions.body = body; } $setRequestOptionsQuery(options) { const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options); const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options); const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options); const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); options.usedInPath = options.usedInPath || {}; let oq = actionAttributes.query || {}; if (resolvedOptions.query) { oq = { ...resolvedOptions.query, ...oq }; } if (oq) { requestOptions.query = {}; Object.keys(oq).forEach((key) => { // tslint:disable-next-line: no-non-null-assertion if (oq.hasOwnProperty(key) && !options.usedInPath[key]) { this.$appendQueryParams(requestOptions.query, key, oq[key], options.queryMappingMethod); } }); } if (actionOptions.addTimestamp) { requestOptions.query = requestOptions.query || {}; this.$appendQueryParams(requestOptions.query, actionOptions.addTimestamp, Date.now().toString(10), options.queryMappingMethod); } } $appendQueryParams(query, key, value, queryMappingMethod) { ResourceHelper.appendQueryParams(query, key, value, queryMappingMethod); } $_setResourceActionInnerDefaults(options) { const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options); // Setting default request method if (!actionOptions.method) { actionOptions.method = ResourceRequestMethod.Get; } if (actionAttributes.body) { // Setting default request content type if (!actionOptions.requestBodyType) { actionOptions.requestBodyType = ResourceHelper.getRealTypeOf(actionAttributes.body); } // Setting params and query if needed if (actionOptions.requestBodyType === ResourceRequestBodyType.JSON && typeof actionAttributes.body === 'object' && !Array.isArray(actionAttributes.body)) { if (!actionAttributes.params) { actionAttributes.params = actionAttributes.body; } options.isModel = !!actionAttributes.body.$resource; } } actionAttributes.params = actionAttributes.params || {}; if (!actionAttributes.query && actionOptions.method === ResourceRequestMethod.Get) { actionAttributes.query = actionAttributes.params; } options.queryMappingMethod = actionOptions.queryMappingMethod || ResourceGlobalConfig.queryMappingMethod; } // tslint:disable-next-line: cognitive-complexity $_setResourceActionOptionDefaults(options) { const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); if (ResourceHelper.isNullOrUndefined(actionOptions.filter)) { actionOptions.filter = this.$filter; } if (ResourceHelper.isNullOrUndefined(actionOptions.map)) { actionOptions.map = this.$map; } if (ResourceHelper.isNullOrUndefined(actionOptions.resultFactory)) { actionOptions.resultFactory = this.$resultFactory; } if (ResourceHelper.isNullOrUndefined(actionOptions.removeTrailingSlash)) { actionOptions.removeTrailingSlash = ResourceGlobalConfig.removeTrailingSlash; } if (ResourceHelper.isNullOrUndefined(actionOptions.withCredentials)) { actionOptions.withCredentials = ResourceGlobalConfig.withCredentials; } if (ResourceHelper.isNullOrUndefined(actionOptions.returnAs)) { actionOptions.returnAs = ResourceGlobalConfig.returnAs; } if (ResourceHelper.isNullOrUndefined(actionOptions.responseBodyType)) { actionOptions.responseBodyType = ResourceGlobalConfig.responseBodyType; } if (ResourceHelper.isNullOrUndefined(actionOptions.lean)) { actionOptions.lean = !!ResourceGlobalConfig.lean; if (actionOptions.mutateBody && actionOptions.returnAs === ResourceActionReturnType.Resource && ResourceHelper.isNullOrUndefined(actionOptions.lean)) { actionOptions.lean = true; } } if (ResourceHelper.isNullOrUndefined(actionOptions.addTimestamp)) { actionOptions.addTimestamp = ResourceGlobalConfig.addTimestamp; if (actionOptions.addTimestamp && typeof actionOptions.addTimestamp !== 'string') { actionOptions.addTimestamp = 'ts'; } } } $_setResolvedOptions(options) { return Promise.all([ this.$getUrl(options.actionOptions), this.$getPathPrefix(options.actionOptions), this.$getPath(options.actionOptions), this.$getHeaders(options.actionOptions), this.$getBody(options.actionOptions), this.$getParams(options.actionOptions), this.$getQuery(options.actionOptions) ]) .then(([url, pathPrefix, path, headers, body, params, query]) => { options.resolvedOptions = { url, pathPrefix, path, headers, body, params, query }; return options; }); } $_createRequestOptions(options) { const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options); options.requestOptions = {}; // Step 1 set main options.requestOptions.method = actionOptions.method; options.requestOptions.headers = resolvedOptions.headers; options.requestOptions.withCredentials = actionOptions.withCredentials; options.requestOptions.responseBodyType = actionOptions.responseBodyType; options.requestOptions.requestBodyType = actionOptions.requestBodyType; // Step 2 create url this.$setRequestOptionsUrl(options); // Step 3 create body this.$setRequestOptionsBody(options); // Step 4 set query params this.$setRequestOptionsQuery(options); return options; } $_canSetInternalData(options) { const actionOptions = ResourceHelper.getActionOptionsOrThrow(options); return !!(options.returnData && (!actionOptions.lean || options.isModel)); } }; Resource = __decorate([ __param(0, Optional()), __metadata("design:paramtypes", [ResourceHandler]) ], Resource); export { Resource }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVzb3VyY2UvY29yZS9zcmMvbGliL1Jlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1RCxPQUFPLEVBSUwsd0JBQXdCLEVBRXhCLHVCQUF1QixFQUN2QixxQkFBcUIsRUFDdEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFRLE1BQU0sZUFBZSxDQUFDO0FBRXhDLElBQU0sUUFBUSxHQUFkLE1BQU0sUUFBUTtJQUVuQixJQUFjLGNBQWM7UUFFMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFFekIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQzthQUN2RDtZQUVELElBQUksQ0FBQyxlQUFlLEdBQUcsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsZUFBd0MsQ0FBQyxDQUFDO1lBRTdGLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7YUFDeEQ7U0FFRjtRQUVELE9BQU8sSUFBSSxDQUFD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IjpbImltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgSVJlc291cmNlQWN0aW9uLFxuICBJUmVzb3VyY2VBY3Rpb25Jbm5lcixcbiAgSVJlc291cmNlUmVzcG9uc2UsXG4gIFJlc291cmNlQWN0aW9uUmV0dXJuVHlwZSxcbiAgUmVzb3VyY2VRdWVyeU1hcHBpbmdNZXRob2QsXG4gIFJlc291cmNlUmVxdWVzdEJvZHlUeXBlLFxuICBSZXNvdXJjZVJlcXVlc3RNZXRob2Rcbn0gZnJvbSAnLi9EZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHsgUmVzb3VyY2VHbG9iYWxDb25maWcgfSBmcm9tICcuL1Jlc291cmNlR2xvYmFsQ29uZmlnJztcbmltcG9ydCB7IFJlc291cmNlSGVscGVyIH0gZnJvbSAnLi9SZXNvdXJjZUhlbHBlcic7XG5pbXBvcnQgeyBSZXNvdXJjZUhhbmRsZXIgfSBmcm9tICcuL1Jlc291cmNlSGFuZGxlcic7XG5pbXBvcnQgeyBSZXNvdXJjZU1vZHVsZSB9IGZyb20gJy4vUmVzb3VyY2VNb2R1bGUnO1xuaW1wb3J0IHsgT3B0aW9uYWwsIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGNsYXNzIFJlc291cmNlIHtcblxuICBwcm90ZWN0ZWQgZ2V0IHJlcXVlc3RIYW5kbGVyKCk6IFJlc291cmNlSGFuZGxlciB7XG5cbiAgICBpZiAoIXRoaXMuX3JlcXVlc3RIYW5kbGVyKSB7XG5cbiAgICAgIGlmICghUmVzb3VyY2VNb2R1bGUuaW5qZWN0b3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNvdXJjZU1vZHVsZS5pbmplY3RvciBpcyBtaXNzaW5nJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlcXVlc3RIYW5kbGVyID0gUmVzb3VyY2VNb2R1bGUuaW5qZWN0b3IuZ2V0KFJlc291cmNlSGFuZGxlciBhcyBUeXBlPFJlc291cmNlSGFuZGxlcj4pO1xuXG4gICAgICBpZiAoIXRoaXMuX3JlcXVlc3RIYW5kbGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVzb3VyY2VIYW5kbGVyIHByb3ZpZGVyIGlzIG1pc3NpbmcnKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0SGFuZGxlcjtcblxuICB9XG5cbiAgcHJpdmF0ZSAkdXJsOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSAkcGF0aFByZWZpeDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgJHBhdGg6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlICRoZWFkZXJzOiB7fSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlICRib2R5OiB7fSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlICRwYXJhbXM6IHt9IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgJHF1ZXJ5OiB7fSB8IG51bGwgPSBudWxsO1xuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX3JlcXVlc3RIYW5kbGVyOiBSZXNvdXJjZUhhbmRsZXIgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSByZXF1ZXN0SGFuZGxlcj86IFJlc291cmNlSGFuZGxlcikge1xuXG4gICAgaWYgKHJlcXVlc3RIYW5kbGVyKSB7XG4gICAgICB0aGlzLl9yZXF1ZXN0SGFuZGxlciA9IHJlcXVlc3RIYW5kbGVyO1xuICAgIH1cblxuICAgICh0aGlzLmNvbnN0cnVjdG9yIGFzIGFueSkuaW5zdGFuY2UgPSB0aGlzO1xuXG4gIH1cblxuICAvKipcbiAgICogVXNlZCB0byBnZXQgdXJsXG4gICAqL1xuICAkZ2V0VXJsKGFjdGlvbk9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbiA9IHt9KTogc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy4kdXJsIHx8IGFjdGlvbk9wdGlvbnMudXJsIHx8IFJlc291cmNlR2xvYmFsQ29uZmlnLnVybCB8fCAnJztcbiAgfVxuXG4gICRzZXRVcmwodXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLiR1cmwgPSB1cmw7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCB0byBnZXQgcGF0aCBwcmVmaXhcbiAgICovXG4gICRnZXRQYXRoUHJlZml4KGFjdGlvbk9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbiA9IHt9KTogc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy4kcGF0aFByZWZpeCB8fCBhY3Rpb25PcHRpb25zLnBhdGhQcmVmaXggfHwgUmVzb3VyY2VHbG9iYWxDb25maWcucGF0aFByZWZpeCB8fCAnJztcbiAgfVxuXG4gICRzZXRQYXRoUHJlZml4KHBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuJHBhdGhQcmVmaXggPSBwYXRoO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gZ2V0IHBhdGhcbiAgICovXG4gICRnZXRQYXRoKGFjdGlvbk9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbiA9IHt9KTogc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy4kcGF0aCB8fCBhY3Rpb25PcHRpb25zLnBhdGggfHwgUmVzb3VyY2VHbG9iYWxDb25maWcucGF0aCB8fCAnJztcbiAgfVxuXG4gICRzZXRQYXRoKHBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuJHBhdGggPSBwYXRoO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBoZWFkZXJzLlxuICAgKi9cbiAgJGdldEhlYWRlcnMoYWN0aW9uT3B0aW9uczogSVJlc291cmNlQWN0aW9uID0ge30pOiBhbnkgfCBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLiRoZWFkZXJzIHx8IGFjdGlvbk9wdGlvbnMuaGVhZGVycyB8fCBSZXNvdXJjZUdsb2JhbENvbmZpZy5oZWFkZXJzIHx8IHt9O1xuICB9XG5cbiAgJHNldEhlYWRlcnMoaGVhZGVyczogYW55KSB7XG4gICAgdGhpcy4kaGVhZGVycyA9IGhlYWRlcnM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGJvZHlcbiAgICovXG4gICRnZXRCb2R5KGFjdGlvbk9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbiA9IHt9KTogYW55IHwgUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy4kYm9keSB8fCBhY3Rpb25PcHRpb25zLmJvZHkgfHwgUmVzb3VyY2VHbG9iYWxDb25maWcuYm9keSB8fCB7fTtcbiAgfVxuXG4gICRzZXRCb2R5KGJvZHk6IGFueSkge1xuICAgIHRoaXMuJGJvZHkgPSBib2R5O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwYXRoIHBhcmFtc1xuICAgKi9cbiAgJGdldFBhcmFtcyhhY3Rpb25PcHRpb25zOiBJUmVzb3VyY2VBY3Rpb24gPSB7fSk6IGFueSB8IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuJHBhcmFtcyB8fCBhY3Rpb25PcHRpb25zLnBhcmFtcyB8fCBSZXNvdXJjZUdsb2JhbENvbmZpZy5wYXJhbXMgfHwge307XG4gIH1cblxuICAkc2V0UGFyYW1zKHBhcmFtczogYW55KSB7XG4gICAgdGhpcy4kcGFyYW1zID0gcGFyYW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBxdWVyeSBwYXJhbXNcbiAgICovXG4gICRnZXRRdWVyeShhY3Rpb25PcHRpb25zOiBJUmVzb3VyY2VBY3Rpb24gPSB7fSk6IGFueSB8IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuJHF1ZXJ5IHx8IGFjdGlvbk9wdGlvbnMucXVlcnkgfHwgUmVzb3VyY2VHbG9iYWxDb25maWcucXVlcnkgfHwge307XG4gIH1cblxuICAkc2V0UXVlcnkocXVlcnk6IGFueSkge1xuICAgIHRoaXMuJHF1ZXJ5ID0gcXVlcnk7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCB0byBmaWx0ZXIgcmVjZWl2ZWQgZGF0YS5cbiAgICogSXMgYXBwbGllZCBvbiBlYWNoIGVsZW1lbnQgb2YgYXJyYXkgb3Igb2JqZWN0XG4gICAqL1xuICAkZmlsdGVyKGRhdGE6IGFueSwgb3B0aW9uczogSVJlc291cmNlQWN0aW9uSW5uZXIgPSB7fSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWFwIHJlY2VpdmVkIGRhdGFcbiAgICogSXMgYXBwbGllZCBvbiBlYWNoIGVsZW1lbnQgb2YgYXJyYXkgb3Igb2JqZWN0XG4gICAqL1xuICAkbWFwKGRhdGE6IGFueSwgb3B0aW9uczogSVJlc291cmNlQWN0aW9uSW5uZXIgPSB7fSk6IGFueSB7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCB0byBjcmVhdGUgcmVzdWx0IG9iamVjdFxuICAgKiBJcyBhcHBsaWVkIG9uIGVhY2ggZWxlbWVudCBvZiBhcnJheSBvciBvYmplY3RcbiAgICovXG4gICRyZXN1bHRGYWN0b3J5KGRhdGE6IGFueSwgb3B0aW9uczogSVJlc291cmNlQWN0aW9uSW5uZXIgPSB7fSk6IGFueSB7XG4gICAgcmV0dXJuIGRhdGEgPT0gbnVsbCA/IHt9IDogZGF0YTtcbiAgfVxuXG4gICRyZXN0QWN0aW9uKG9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbklubmVyKSB7XG5cbiAgICB0aGlzLiRfc2V0UmVzb3VyY2VBY3Rpb25Jbm5lckRlZmF1bHRzKG9wdGlvbnMpO1xuICAgIHRoaXMuJF9zZXRSZXNvdXJjZUFjdGlvbk9wdGlvbkRlZmF1bHRzKG9wdGlvbnMpO1xuXG4gICAgaWYgKCFvcHRpb25zLmFjdGlvbk9wdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIG9wdGlvbnMgYXJlIG5vdCBzZXQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY3Rpb25PcHRpb25zID0gb3B0aW9ucy5hY3Rpb25PcHRpb25zO1xuXG4gICAgaWYgKCFhY3Rpb25PcHRpb25zLnJlc3VsdEZhY3RvcnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIG9wdGlvbnMgcmVzdWx0RmFjdG9yeSBpcyBub3Qgc2V0Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmFjdGlvbkF0dHJpYnV0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGF0dHJpYnV0ZXMgaXMgbm90IHNldCcpO1xuICAgIH1cblxuXG4gICAgaWYgKGFjdGlvbk9wdGlvbnMubXV0YXRlQm9keSB8fCBvcHRpb25zLmlzTW9kZWwpIHtcbiAgICAgIG9wdGlvbnMucmV0dXJuRGF0YSA9IG9wdGlvbnMuYWN0aW9uQXR0cmlidXRlcy5ib2R5O1xuICAgIH1cblxuICAgIGlmIChhY3Rpb25PcHRpb25zLnJldHVybkFzID09PSBSZXNvdXJjZUFjdGlvblJldHVyblR5cGUuUmVzb3VyY2UpIHtcbiAgICAgIG9wdGlvbnMucmV0dXJuRGF0YSA9IGFjdGlvbk9wdGlvbnMuZXhwZWN0SnNvbkFycmF5ID8gW10gOiBhY3Rpb25PcHRpb25zLnJlc3VsdEZhY3RvcnkuY2FsbCh0aGlzLCBudWxsLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy4kX2NhblNldEludGVybmFsRGF0YShvcHRpb25zKSkge1xuICAgICAgUmVzb3VyY2VIZWxwZXIuZGVmaW5lUmV0dXJuRGF0YVByb3BlcnRpZXNSZXNvbHZlZEFib3J0KG9wdGlvbnMucmV0dXJuRGF0YSk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5tYWluT2JzZXJ2YWJsZSA9IHRoaXMuJF9jcmVhdGVNYWluT2JzZXJ2YWJsZShvcHRpb25zKTtcblxuICAgIGlmICh0aGlzLiRfY2FuU2V0SW50ZXJuYWxEYXRhKG9wdGlvbnMpKSB7XG4gICAgICBSZXNvdXJjZUhlbHBlci5kZWZpbmVSZXR1cm5EYXRhUHJvcGVydGllc1Byb21pc2Uob3B0aW9ucy5yZXR1cm5EYXRhLCB0aGlzLiRfY3JlYXRlUHJvbWlzZShvcHRpb25zKSk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChhY3Rpb25PcHRpb25zLnJldHVybkFzKSB7XG4gICAgICBjYXNlIFJlc291cmNlQWN0aW9uUmV0dXJuVHlwZS5PYnNlcnZhYmxlOlxuICAgICAgICByZXR1cm4gb3B0aW9ucy5tYWluT2JzZXJ2YWJsZTtcblxuICAgICAgY2FzZSBSZXNvdXJjZUFjdGlvblJldHVyblR5cGUuUHJvbWlzZTpcbiAgICAgICAgcmV0dXJuIHRoaXMuJF9jcmVhdGVQcm9taXNlKG9wdGlvbnMpO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gb3B0aW9ucy5yZXR1cm5EYXRhO1xuXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb2JzZXJ2YWJsZSB0byBwcm9taXNlIGFuZCBhZHMgYWJvcnQgbWV0aG9kXG4gICAqL1xuICBwcm90ZWN0ZWQgJF9jcmVhdGVQcm9taXNlKG9wdGlvbnM6IElSZXNvdXJjZUFjdGlvbklubmVyKTogUHJvbWlzZTxhbnk+IHtcblxuICAgIGlmICghb3B0aW9ucy5wcm9taXNlKSB7XG4gICAgICBvcHRpb25zLnByb21pc2UgPSBuZXcgUHJvbWlzZTxhbnk+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblxuICAgICAgICBpZiAoIW9wdGlvbnMubWFpbk9ic2VydmFibGUpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKCckX2NyZWF0ZVByb21pc2Ugb3B0aW9ucy5tYWluT2JzZXJ2YWJsZSBtaXNzaW5nJykpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucy5zdWJzY3JpcHRpb24gPSBvcHRpb25zLm1haW5PYnNlcnZhYmxlLnN1YnNjcmliZShcbiAgICAgICAgICByZXNvbHZlLFxuICAgICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICBvcHRpb25zLnN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgICA