@ngx-resource/core
Version:
Core of resource library
503 lines • 69.1 kB
JavaScript
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