UNPKG

@orbit/jsonapi

Version:

JSON:API support for Orbit.

233 lines 34.2 kB
import { Orbit } from '@orbit/core'; import { requestOptionsForSource } from '@orbit/data'; import { NetworkError, InvalidServerResponse, ClientError, ServerError } from './lib/exceptions'; import { deepMerge, toArray } from '@orbit/utils'; import { JSONAPIURLBuilder } from './jsonapi-url-builder'; import { buildJSONAPISerializerFor } from './serializers/jsonapi-serializer-builder'; import { JSONAPISerializers } from './serializers/jsonapi-serializers'; const { assert, deprecate } = Orbit; export class JSONAPIRequestProcessor { constructor(settings) { let { sourceName, allowedContentTypes, schema, keyMap, SerializerClass, serializerFor, serializerClassFor, serializerSettingsFor } = settings; this.sourceName = sourceName; this.allowedContentTypes = allowedContentTypes || [ 'application/vnd.api+json', 'application/json' ]; this.schema = schema; this.keyMap = keyMap; if (SerializerClass) { deprecate("The 'SerializerClass' setting for 'JSONAPIRequestProcessor' has been deprecated. Pass 'serializerFor', 'serializerClassFor', and/or 'serializerSettingsFor' instead."); this._serializer = new SerializerClass({ schema, keyMap }); } this._serializerFor = buildJSONAPISerializerFor({ schema, keyMap, serializerFor, serializerClassFor, serializerSettingsFor }); const URLBuilderClass = settings.URLBuilderClass || JSONAPIURLBuilder; const urlBuilderOptions = { host: settings.host, namespace: settings.namespace, keyMap: settings.keyMap, serializer: this._serializer, serializerFor: this._serializerFor }; this.urlBuilder = new URLBuilderClass(urlBuilderOptions); this.initDefaultFetchSettings(settings); } /** * @deprecated since v0.17, use `serializerFor` instead */ get serializer() { deprecate("'JSONAPIRequestProcessor#serializer' has been deprecated. Use 'serializerFor' instead."); if (this._serializer) { return this._serializer; } else { return this._serializerFor(JSONAPISerializers.ResourceDocument); } } get serializerFor() { return this._serializerFor; } fetch(url, customSettings) { let settings = this.initFetchSettings(customSettings); let fullUrl = url; if (settings.params) { fullUrl = this.urlBuilder.appendQueryParams(fullUrl, settings.params); delete settings.params; } let fetchFn = Orbit.fetch || Orbit.globals.fetch; // console.log('fetch', fullUrl, settings, 'polyfill', fetchFn.polyfill); if (settings.timeout !== undefined && settings.timeout > 0) { let timeout = settings.timeout; delete settings.timeout; return new Promise((resolve, reject) => { let timedOut; let timer = Orbit.globals.setTimeout(() => { timedOut = true; reject(new NetworkError(`No fetch response within ${timeout}ms.`)); }, timeout); fetchFn(fullUrl, settings) .catch((e) => { Orbit.globals.clearTimeout(timer); if (!timedOut) { return this.handleFetchError(e); } }) .then((response) => { Orbit.globals.clearTimeout(timer); if (!timedOut) { return this.handleFetchResponse(response); } }) .then(resolve, reject); }); } else { return fetchFn(fullUrl, settings) .catch((e) => this.handleFetchError(e)) .then((response) => this.handleFetchResponse(response)); } } initFetchSettings(customSettings = {}) { let settings = deepMerge({}, this.defaultFetchSettings, customSettings); if (settings.json) { assert("`json` and `body` can't both be set for fetch requests.", !settings.body); settings.body = JSON.stringify(settings.json); delete settings.json; } if (settings.headers && !settings.body) { delete settings.headers['Content-Type']; } return settings; } operationsFromDeserializedDocument(deserialized) { const records = []; Array.prototype.push.apply(records, toArray(deserialized.data)); if (deserialized.included) { Array.prototype.push.apply(records, deserialized.included); } return records.map((record) => { return { op: 'updateRecord', record }; }); } buildFetchSettings(request) { var _a; const settings = { params: {}, ...(_a = request.options) === null || _a === void 0 ? void 0 : _a.settings }; if (request.options) { const { filter, sort, page, include, fields } = request.options; if (filter) { settings.params.filter = this.urlBuilder.buildFilterParam(filter, request); } if (sort) { settings.params.sort = this.urlBuilder.buildSortParam(sort, request); } if (page) { settings.params.page = this.urlBuilder.buildPageParam(page, request); } if (include) { settings.params.include = this.urlBuilder.buildIncludeParam(include, request); } if (fields) { settings.params.fields = this.urlBuilder.buildFieldsParam(fields, request); } } return settings; } mergeRequestOptions(options) { return requestOptionsForSource(options, this.sourceName); } /** * @deprecated since v0.17, use `mergeRequestOptions` instead */ customRequestOptions(queryOrTransform, queryExpressionOrOperation) { deprecate("'JSONAPIRequestProcessor#customRequestOptions' has been deprecated. Use 'mergeRequestOptions' instead."); return this.mergeRequestOptions([ queryOrTransform.options, queryExpressionOrOperation.options ]); } /* eslint-disable @typescript-eslint/no-unused-vars */ preprocessResponseDocument(document, request) { } /* eslint-enable @typescript-eslint/no-unused-vars */ responseHasContent(response, ignoreUnrecognizedContent) { let contentType = response.headers.get('Content-Type'); if (contentType) { for (let allowedContentType of this.allowedContentTypes) { if (contentType.indexOf(allowedContentType) > -1) { return true; } } if (!ignoreUnrecognizedContent) { throw new InvalidServerResponse(`The server responded with the content type '${contentType}', which is not allowed. Allowed content types include: '${this.allowedContentTypes.join("', '")}'.`); } } return false; } initDefaultFetchSettings(settings) { this.defaultFetchSettings = { headers: { Accept: 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json' }, timeout: 5000 }; if (settings.defaultFetchSettings) { deepMerge(this.defaultFetchSettings, settings.defaultFetchSettings); } } async handleFetchResponse(response) { const responseDetail = { response }; if (response.status >= 200 && response.status < 300) { if (response.status !== 204 && this.responseHasContent(response)) { responseDetail.document = await response.json(); } } else if (response.status !== 304 && response.status !== 404) { if (this.responseHasContent(response, true)) { const document = await response.json(); await this.handleFetchResponseError(response, document); } else { await this.handleFetchResponseError(response); } } return responseDetail; } async handleFetchResponseError(response, data) { let error; if (response.status >= 400 && response.status < 500) { error = new ClientError(response.statusText); } else { error = new ServerError(response.statusText); } error.response = response; error.data = data; throw error; } async handleFetchError(e) { if (typeof e === 'string') { throw new NetworkError(e); } else { throw e; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbmFwaS1yZXF1ZXN0LXByb2Nlc3Nvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9qc29uYXBpLXJlcXVlc3QtcHJvY2Vzc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDcEMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBVXRELE9BQU8sRUFDTCxZQUFZLEVBQ1oscUJBQXFCLEVBQ3JCLFdBQVcsRUFDWCxXQUFXLEVBQ1osTUFBTSxrQkFBa0IsQ0FBQztBQUcxQixPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUlsRCxPQUFPLEVBQ0wsaUJBQWlCLEVBRWxCLE1BQU0sdUJBQXVCLENBQUM7QUFVL0IsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDckYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFJdkUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFvQ3BDLE1BQU0sT0FBTyx1QkFBdUI7SUFVbEMsWUFBWSxRQUF5QztRQUNuRCxJQUFJLEVBQ0YsVUFBVSxFQUNWLG1CQUFtQixFQUNuQixNQUFNLEVBQ04sTUFBTSxFQUNOLGVBQWUsRUFDZixhQUFhLEVBQ2Isa0JBQWtCLEVBQ2xCLHFCQUFxQixFQUN0QixHQUFHLFFBQVEsQ0FBQztRQUViLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsSUFBSTtZQUNoRCwwQkFBMEI7WUFDMUIsa0JBQWtCO1NBQ25CLENBQUM7UUFDRixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLGVBQWUs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O1xuaW1wb3J0IHsgcmVxdWVzdE9wdGlvbnNGb3JTb3VyY2UgfSBmcm9tICdAb3JiaXQvZGF0YSc7XG5pbXBvcnQge1xuICBSZWNvcmRLZXlNYXAsXG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRTY2hlbWEsXG4gIFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgUmVjb3JkVHJhbnNmb3JtLFxuICBSZWNvcmRRdWVyeVxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBEaWN0IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIE5ldHdvcmtFcnJvcixcbiAgSW52YWxpZFNlcnZlclJlc3BvbnNlLFxuICBDbGllbnRFcnJvcixcbiAgU2VydmVyRXJyb3Jcbn0gZnJvbSAnLi9saWIvZXhjZXB0aW9ucyc7XG5pbXBvcnQgeyBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0IH0gZnJvbSAnLi9saWIvdHJhbnNmb3JtLXJlcXVlc3RzJztcbmltcG9ydCB7IFJlY29yZFF1ZXJ5UmVxdWVzdCB9IGZyb20gJy4vbGliL3F1ZXJ5LXJlcXVlc3RzJztcbmltcG9ydCB7IGRlZXBNZXJnZSwgdG9BcnJheSB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBSZXNvdXJjZURvY3VtZW50IH0gZnJvbSAnLi9yZXNvdXJjZS1kb2N1bWVudCc7XG5pbXBvcnQgeyBSZWNvcmREb2N1bWVudCB9IGZyb20gJy4vcmVjb3JkLWRvY3VtZW50JztcbmltcG9ydCB7IEpTT05BUElSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vbGliL2pzb25hcGktcmVxdWVzdC1vcHRpb25zJztcbmltcG9ydCB7XG4gIEpTT05BUElVUkxCdWlsZGVyLFxuICBKU09OQVBJVVJMQnVpbGRlclNldHRpbmdzXG59IGZyb20gJy4vanNvbmFwaS11cmwtYnVpbGRlcic7XG5pbXBvcnQge1xuICBKU09OQVBJU2VyaWFsaXplcixcbiAgSlNPTkFQSVNlcmlhbGl6ZXJTZXR0aW5nc1xufSBmcm9tICcuL2pzb25hcGktc2VyaWFsaXplcic7XG5pbXBvcnQge1xuICBTZXJpYWxpemVyRm9yRm4sXG4gIFNlcmlhbGl6ZXJDbGFzc0ZvckZuLFxuICBTZXJpYWxpemVyU2V0dGluZ3NGb3JGblxufSBmcm9tICdAb3JiaXQvc2VyaWFsaXplcnMnO1xuaW1wb3J0IHsgYnVpbGRKU09OQVBJU2VyaWFsaXplckZvciB9IGZyb20gJy4vc2VyaWFsaXplcnMvanNvbmFwaS1zZXJpYWxpemVyLWJ1aWxkZXInO1xuaW1wb3J0IHsgSlNPTkFQSVNlcmlhbGl6ZXJzIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXNlcmlhbGl6ZXJzJztcbmltcG9ydCB7IFJlY29yZE9wZXJhdGlvbiB9IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IEpTT05BUElSZXNwb25zZSB9IGZyb20gJy4vanNvbmFwaS1yZXNwb25zZSc7XG5cbmNvbnN0IHsgYXNzZXJ0LCBkZXByZWNhdGUgfSA9IE9yYml0O1xuXG5leHBvcnQgaW50ZXJmYWNlIEZldGNoU2V0dGluZ3Mge1xuICBoZWFkZXJzPzogRGljdDxhbnk+O1xuICBtZXRob2Q/OiBzdHJpbmc7XG4gIGpzb24/OiBEaWN0PGFueT47XG4gIGJvZHk/OiBzdHJpbmc7XG4gIHBhcmFtcz86IERpY3Q8YW55PjtcbiAgdGltZW91dD86IG51bWJlcjtcbiAgY3JlZGVudGlhbHM/OiBzdHJpbmc7XG4gIGNhY2hlPzogc3RyaW5nO1xuICByZWRpcmVjdD86IHN0cmluZztcbiAgcmVmZXJyZXI/OiBzdHJpbmc7XG4gIHJlZmVycmVyUG9saWN5Pzogc3RyaW5nO1xuICBpbnRlZ3JpdHk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3JTZXR0aW5ncyB7XG4gIHNvdXJjZU5hbWU6IHN0cmluZztcbiAgc2VyaWFsaXplckZvcj86IFNlcmlhbGl6ZXJGb3JGbjtcbiAgc2VyaWFsaXplckNsYXNzRm9yPzogU2VyaWFsaXplckNsYXNzRm9yRm47XG4gIHNlcmlhbGl6ZXJTZXR0aW5nc0Zvcj86IFNlcmlhbGl6ZXJTZXR0aW5nc0ZvckZuO1xuICBTZXJpYWxpemVyQ2xhc3M/OiBuZXcgKFxuICAgIHNldHRpbmdzOiBKU09OQVBJU2VyaWFsaXplclNldHRpbmdzXG4gICkgPT4gSlNPTkFQSVNlcmlhbGl6ZXI7XG4gIFVSTEJ1aWxkZXJDbGFzcz86IG5ldyAoXG4gICAgc2V0dGluZ3M6IEpTT05BUElVUkxCdWlsZGVyU2V0dGluZ3NcbiAgKSA9PiBKU09OQVBJVVJMQnVpbGRlcjtcbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xuICBob3N0Pzogc3RyaW5nO1xuICBkZWZhdWx0RmV0Y2hTZXR0aW5ncz86IEZldGNoU2V0dGluZ3M7XG4gIGFsbG93ZWRDb250ZW50VHlwZXM/OiBzdHJpbmdbXTtcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWE7XG4gIGtleU1hcD86IFJlY29yZEtleU1hcDtcbn1cblxuZXhwb3J0IGNsYXNzIEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yIHtcbiAgc291cmNlTmFtZTogc3RyaW5nO1xuICB1cmxCdWlsZGVyOiBKU09OQVBJVVJMQnVpbGRlcjtcbiAgYWxsb3dlZENvbnRlbnRUeXBlczogc3RyaW5nW107XG4gIGRlZmF1bHRGZXRjaFNldHRpbmdzITogRmV0Y2hTZXR0aW5ncztcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWE7XG4gIGtleU1hcD86IFJlY29yZEtleU1hcDtcbiAgcHJvdGVjdGVkIF9zZXJpYWxpemVyPzogSlNPTkFQSVNlcmlhbGl6ZXI7XG4gIHByb3RlY3RlZCBfc2VyaWFsaXplckZvcjogU2VyaWFsaXplckZvckZuO1xuXG4gIGNvbnN0cnVjdG9yKHNldHRpbmdzOiBKU09OQVBJUmVxdWVzdFByb2Nlc3NvclNldHRpbmdzKSB7XG4gICAgbGV0IHtcbiAgICAgIHNvdXJjZU5hbWUsXG4gICAgICBhbGxvd2VkQ29udGVudFR5cGVzLFxuICAgICAgc2NoZW1hLFxuICAgICAga2V5TWFwLFxuICAgICAgU2VyaWFsaXplckNsYXNzLFxuICAgICAgc2VyaWFsaXplckZvcixcbiAgICAgIHNlcmlhbGl6ZXJDbGFzc0ZvcixcbiAgICAgIHNlcmlhbGl6ZXJTZXR0aW5nc0ZvclxuICAgIH0gPSBzZXR0aW5ncztcblxuICAgIHRoaXMuc291cmNlTmFtZSA9IHNvdXJjZU5hbWU7XG4gICAgdGhpcy5hbGxvd2VkQ29udGVudFR5cGVzID0gYWxsb3dlZENvbnRlbnRUeXBlcyB8fCBbXG4gICAgICAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uJyxcbiAgICAgICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgIF07XG4gICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgdGhpcy5rZXlNYXAgPSBrZXlNYXA7XG4gICAgaWYgKFNlcmlhbGl6ZXJDbGFzcykge1xuICAgICAgZGVwcmVjYXRlKFxuICAgICAgICBcIlRoZSAnU2VyaWFsaXplckNsYXNzJyBzZXR0aW5nIGZvciAnSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3InIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBhc3MgJ3NlcmlhbGl6ZXJGb3InLCAnc2VyaWFsaXplckNsYXNzRm9yJywgYW5kL29yICdzZXJpYWxpemVyU2V0dGluZ3NGb3InIGluc3RlYWQuXCJcbiAgICAgICk7XG4gICAgICB0aGlzLl9zZXJpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXJDbGFzcyh7XG4gICAgICAgIHNjaGVtYSxcbiAgICAgICAga2V5TWFwXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5fc2VyaWFsaXplckZvciA9IGJ1aWxkSlNPTkFQSVNlcmlhbGl6ZXJGb3Ioe1xuICAgICAgc2NoZW1hLFxuICAgICAga2V5TWFwLFxuICAgICAgc2VyaWFsaXplckZvcixcbiAgICAgIHNlcmlhbGl6ZXJDbGFzc0ZvcixcbiAgICAgIHNlcmlhbGl6ZXJTZXR0aW5nc0ZvclxuICAgIH0pO1xuICAgIGNvbnN0IFVSTEJ1aWxkZXJDbGFzcyA9IHNldHRpbmdzLlVSTEJ1aWxkZXJDbGFzcyB8fCBKU09OQVBJVVJMQnVpbGRlcjtcbiAgICBjb25zdCB1cmxCdWlsZGVyT3B0aW9uczogSlNPTkFQSVVSTEJ1aWxkZXJTZXR0aW5ncyA9IHtcbiAgICAgIGhvc3Q6IHNldHRpbmdzLmhvc3QsXG4gICAgICBuYW1lc3BhY2U6IHNldHRpbmdzLm5hbWVzcGFjZSxcbiAgICAgIGtleU1hcDogc2V0dGluZ3Mua2V5TWFwLFxuICAgICAgc2VyaWFsaXplcjogdGhpcy5fc2VyaWFsaXplcixcbiAgICAgIHNlcmlhbGl6ZXJGb3I6IHRoaXMuX3NlcmlhbGl6ZXJGb3JcbiAgICB9O1xuICAgIHRoaXMudXJsQnVpbGRlciA9IG5ldyBVUkxCdWlsZGVyQ2xhc3ModXJsQnVpbGRlck9wdGlvbnMpO1xuICAgIHRoaXMuaW5pdERlZmF1bHRGZXRjaFNldHRpbmdzKHNldHRpbmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBzaW5jZSB2MC4xNywgdXNlIGBzZXJpYWxpemVyRm9yYCBpbnN0ZWFkXG4gICAqL1xuICBnZXQgc2VyaWFsaXplcigpOiBKU09OQVBJU2VyaWFsaXplciB7XG4gICAgZGVwcmVjYXRlKFxuICAgICAgXCInSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3Ijc2VyaWFsaXplcicgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlICdzZXJpYWxpemVyRm9yJyBpbnN0ZWFkLlwiXG4gICAgKTtcbiAgICBpZiAodGhpcy5fc2VyaWFsaXplcikge1xuICAgICAgcmV0dXJuIHRoaXMuX3NlcmlhbGl6ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLl9zZXJpYWxpemVyRm9yKFxuICAgICAgICBKU09OQVBJU2VyaWFsaXplcnMuUmVzb3VyY2VEb2N1bWVudFxuICAgICAgKSBhcyBKU09OQVBJU2VyaWFsaXplcjtcbiAgICB9XG4gIH1cblxuICBnZXQgc2VyaWFsaXplckZvcigpOiBTZXJpYWxpemVyRm9yRm4ge1xuICAgIHJldHVybiB0aGlzLl9zZXJpYWxpemVyRm9yO1xuICB9XG5cbiAgZmV0Y2godXJsOiBzdHJpbmcsIGN1c3RvbVNldHRpbmdzPzogRmV0Y2hTZXR0aW5ncyk6IFByb21pc2U8SlNPTkFQSVJlc3BvbnNlPiB7XG4gICAgbGV0IHNldHRpbmdzID0gdGhpcy5pbml0RmV0Y2hTZXR0aW5ncyhjdXN0b21TZXR0aW5ncyk7XG5cbiAgICBsZXQgZnVsbFVybCA9IHVybDtcbiAgICBpZiAoc2V0dGluZ3MucGFyYW1zKSB7XG4gICAgICBmdWxsVXJsID0gdGhpcy51cmxCdWlsZGVyLmFwcGVuZFF1ZXJ5UGFyYW1zKGZ1bGxVcmwsIHNldHRpbmdzLnBhcmFtcyk7XG4gICAgICBkZWxldGUgc2V0dGluZ3MucGFyYW1zO1xuICAgIH1cblxuICAgIGxldCBmZXRjaEZuID0gKE9yYml0IGFzIGFueSkuZmV0Y2ggfHwgT3JiaXQuZ2xvYmFscy5mZXRjaDtcblxuICAgIC8vIGNvbnNvbGUubG9nKCdmZXRjaCcsIGZ1bGxVcmwsIHNldHRpbmdzLCAncG9seWZpbGwnLCBmZXRjaEZuLnBvbHlmaWxsKTtcblxuICAgIGlmIChzZXR0aW5ncy50aW1lb3V0ICE9PSB1bmRlZmluZWQgJiYgc2V0dGluZ3MudGltZW91dCA+IDApIHtcbiAgICAgIGxldCB0aW1lb3V0ID0gc2V0dGluZ3MudGltZW91dDtcbiAgICAgIGRlbGV0ZSBzZXR0aW5ncy50aW1lb3V0O1xuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBsZXQgdGltZWRPdXQ6IGJvb2xlYW47XG5cbiAgICAgICAgbGV0IHRpbWVyID0gT3JiaXQuZ2xvYmFscy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aW1lZE91dCA9IHRydWU7XG4gICAgICAgICAgcmVqZWN0KG5ldyBOZXR3b3JrRXJyb3IoYE5vIGZldGNoIHJlc3BvbnNlIHdpdGhpbiAke3RpbWVvdXR9bXMuYCkpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcblxuICAgICAgICBmZXRjaEZuKGZ1bGxVcmwsIHNldHRpbmdzKVxuICAgICAgICAgIC5jYXRjaCgoZTogRXJyb3IpID0+IHtcbiAgICAgICAgICAgIE9yYml0Lmdsb2JhbHMuY2xlYXJUaW1lb3V0KHRpbWVyKTtcblxuICAgICAgICAgICAgaWYgKCF0aW1lZE91dCkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVGZXRjaEVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oKHJlc3BvbnNlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIE9yYml0Lmdsb2JhbHMuY2xlYXJUaW1lb3V0KHRpbWVyKTtcblxuICAgICAgICAgICAgaWYgKCF0aW1lZE91dCkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVGZXRjaFJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZldGNoRm4oZnVsbFVybCwgc2V0dGluZ3MpXG4gICAgICAgIC5jYXRjaCgoZTogRXJyb3IpID0+IHRoaXMuaGFuZGxlRmV0Y2hFcnJvcihlKSlcbiAgICAgICAgLnRoZW4oKHJlc3BvbnNlOiBhbnkpID0+IHRoaXMuaGFuZGxlRmV0Y2hSZXNwb25zZShyZXNwb25zZSkpO1xuICAgIH1cbiAgfVxuXG4gIGluaXRGZXRjaFNldHRpbmdzKGN1c3RvbVNldHRpbmdzOiBGZXRjaFNldHRpbmdzID0ge30pOiBGZXRjaFNldHRpbmdzIHtcbiAgICBsZXQgc2V0dGluZ3M6IEZldGNoU2V0dGluZ3MgPSBkZWVwTWVyZ2UoXG4gICAgICB7fSxcbiAgICAgIHRoaXMuZGVmYXVsdEZldGNoU2V0dGluZ3MsXG4gICAgICBjdXN0b21TZXR0aW5nc1xuICAgICk7XG5cbiAgICBpZiAoc2V0dGluZ3MuanNvbikge1xuICAgICAgYXNzZXJ0KFxuICAgICAgICBcImBqc29uYCBhbmQgYGJvZHlgIGNhbid0IGJvdGggYmUgc2V0IGZvciBmZXRjaCByZXF1ZXN0cy5cIixcbiAgICAgICAgIXNldHRpbmdzLmJvZHlcbiAgICAgICk7XG4gICAgICBzZXR0aW5ncy5ib2R5ID0gSlNPTi5zdHJpbmdpZnkoc2V0dGluZ3MuanNvbik7XG4gICAgICBkZWxldGUgc2V0dGluZ3MuanNvbjtcbiAgICB9XG5cbiAgICBpZiAoc2V0dGluZ3MuaGVhZGVycyAmJiAhc2V0dGluZ3MuYm9keSkge1xuICAgICAgZGVsZXRlIHNldHRpbmdzLmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIHJldHVybiBzZXR0aW5ncztcbiAgfVxuXG4gIG9wZXJhdGlvbnNGcm9tRGVzZXJpYWxpemVkRG9jdW1lbnQoXG4gICAgZGVzZXJpYWxpemVkOiBSZWNvcmREb2N1bWVudFxuICApOiBSZWNvcmRPcGVyYXRpb25bXSB7XG4gICAgY29uc3QgcmVjb3JkczogSW5pdGlhbGl6ZWRSZWNvcmRbXSA9IFtdO1xuICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHJlY29yZHMsIHRvQXJyYXkoZGVzZXJpYWxpemVkLmRhdGEpKTtcblxuICAgIGlmIChkZXNlcmlhbGl6ZWQuaW5jbHVkZWQpIHtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHJlY29yZHMsIGRlc2VyaWFsaXplZC5pbmNsdWRlZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlY29yZHMubWFwKChyZWNvcmQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAndXBkYXRlUmVjb3JkJyxcbiAgICAgICAgcmVjb3JkXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgYnVpbGRGZXRjaFNldHRpbmdzKFxuICAgIHJlcXVlc3Q6IFJlY29yZFF1ZXJ5UmVxdWVzdCB8IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogRmV0Y2hTZXR0aW5ncyB7XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICBwYXJhbXM6IHt9LFxuICAgICAgLi4ucmVxdWVzdC5vcHRpb25zPy5zZXR0aW5nc1xuICAgIH07XG5cbiAgICBpZiAocmVxdWVzdC5vcHRpb25zKSB7XG4gICAgICBjb25zdCB7IGZpbHRlciwgc29ydCwgcGFnZSwgaW5jbHVkZSwgZmllbGRzIH0gPSByZXF1ZXN0Lm9wdGlvbnM7XG5cbiAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgc2V0dGluZ3MucGFyYW1zLmZpbHRlciA9IHRoaXMudXJsQnVpbGRlci5idWlsZEZpbHRlclBhcmFtKFxuICAgICAgICAgIGZpbHRlcixcbiAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzb3J0KSB7XG4gICAgICAgIHNldHRpbmdzLnBhcmFtcy5zb3J0ID0gdGhpcy51cmxCdWlsZGVyLmJ1aWxkU29ydFBhcmFtKHNvcnQsIHJlcXVlc3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFnZSkge1xuICAgICAgICBzZXR0aW5ncy5wYXJhbXMucGFnZSA9IHRoaXMudXJsQnVpbGRlci5idWlsZFBhZ2VQYXJhbShwYWdlLCByZXF1ZXN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluY2x1ZGUpIHtcbiAgICAgICAgc2V0dGluZ3MucGFyYW1zLmluY2x1ZGUgPSB0aGlzLnVybEJ1aWxkZXIuYnVpbGRJbmNsdWRlUGFyYW0oXG4gICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgc2V0dGluZ3MucGFyYW1zLmZpZWxkcyA9IHRoaXMudXJsQnVpbGRlci5idWlsZEZpZWxkc1BhcmFtKFxuICAgICAgICAgIGZpZWxkcyxcbiAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xuICB9XG5cbiAgbWVyZ2VSZXF1ZXN0T3B0aW9ucyhcbiAgICBvcHRpb25zOlxuICAgICAgfCBKU09OQVBJUmVxdWVzdE9wdGlvbnNcbiAgICAgIHwgdW5kZWZpbmVkXG4gICAgICB8IChKU09OQVBJUmVxdWVzdE9wdGlvbnMgfCB1bmRlZmluZWQpW11cbiAgKTogSlNPTkFQSVJlcXVlc3RPcHRpb25zIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gcmVxdWVzdE9wdGlvbnNGb3JTb3VyY2U8SlNPTkFQSVJlcXVlc3RPcHRpb25zPihcbiAgICAgIG9wdGlvbnMsXG4gICAgICB0aGlzLnNvdXJjZU5hbWVcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHNpbmNlIHYwLjE3LCB1c2UgYG1lcmdlUmVxdWVzdE9wdGlvbnNgIGluc3RlYWRcbiAgICovXG4gIGN1c3RvbVJlcXVlc3RPcHRpb25zKFxuICAgIHF1ZXJ5T3JUcmFuc2Zvcm06IFJlY29yZFF1ZXJ5IHwgUmVjb3JkVHJhbnNmb3JtLFxuICAgIHF1ZXJ5RXhwcmVzc2lvbk9yT3BlcmF0aW9uOiBSZWNvcmRRdWVyeUV4cHJlc3Npb24gfCBSZWNvcmRPcGVyYXRpb25cbiAgKTogSlNPTkFQSVJlcXVlc3RPcHRpb25zIHwgdW5kZWZpbmVkIHtcbiAgICBkZXByZWNhdGUoXG4gICAgICBcIidKU09OQVBJUmVxdWVzdFByb2Nlc3NvciNjdXN0b21SZXF1ZXN0T3B0aW9ucycgaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlICdtZXJnZVJlcXVlc3RPcHRpb25zJyBpbnN0ZWFkLlwiXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5tZXJnZVJlcXVlc3RPcHRpb25zKFtcbiAgICAgIHF1ZXJ5T3JUcmFuc2Zvcm0ub3B0aW9ucyxcbiAgICAgIHF1ZXJ5RXhwcmVzc2lvbk9yT3BlcmF0aW9uLm9wdGlvbnNcbiAgICBdKTtcbiAgfVxuXG4gIC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuICBwcmVwcm9jZXNzUmVzcG9uc2VEb2N1bWVudChcbiAgICBkb2N1bWVudDogUmVzb3VyY2VEb2N1bWVudCB8IHVuZGVmaW5lZCxcbiAgICByZXF1ZXN0OiBSZWNvcmRRdWVyeVJlcXVlc3QgfCBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IHZvaWQge31cbiAgLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cblxuICBwcm90ZWN0ZWQgcmVzcG9uc2VIYXNDb250ZW50KFxuICAgIHJlc3BvbnNlOiBSZXNwb25zZSxcbiAgICBpZ25vcmVVbnJlY29nbml6ZWRDb250ZW50PzogYm9vbGVhblxuICApOiBib29sZWFuIHtcbiAgICBsZXQgY29udGVudFR5cGUgPSByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJyk7XG4gICAgaWYgKGNvbnRlbnRUeXBlKSB7XG4gICAgICBmb3IgKGxldCBhbGxvd2VkQ29udGVudFR5cGUgb2YgdGhpcy5hbGxvd2VkQ29udGVudFR5cGVzKSB7XG4gICAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKGFsbG93ZWRDb250ZW50VHlwZSkgPiAtMSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlnbm9yZVVucmVjb2duaXplZENvbnRlbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRTZXJ2ZXJSZXNwb25zZShcbiAgICAgICAgICBgVGhlIHNlcnZlciByZXNwb25kZWQgd2l0aCB0aGUgY29udGVudCB0eXBlICcke2NvbnRlbnRUeXBlfScsIHdoaWNoIGlzIG5vdCBhbGxvd2VkLiBBbGxvd2VkIGNvbnRlbnQgdHlwZXMgaW5jbHVkZTogJyR7dGhpcy5hbGxvd2VkQ29udGVudFR5cGVzLmpvaW4oXG4gICAgICAgICAgICBcIicsICdcIlxuICAgICAgICAgICl9Jy5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBpbml0RGVmYXVsdEZldGNoU2V0dGluZ3MoXG4gICAgc2V0dGluZ3M6IEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yU2V0dGluZ3NcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5kZWZhdWx0RmV0Y2hTZXR0aW5ncyA9IHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgQWNjZXB0OiAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uJyxcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24nXG4gICAgICB9LFxuICAgICAgdGltZW91dDogNTAwMFxuICAgIH07XG5cbiAgICBpZiAoc2V0dGluZ3MuZGVmYXVsdEZldGNoU2V0dGluZ3MpIHtcbiAgICAgIGRlZXBNZXJnZSh0aGlzLmRlZmF1bHRGZXRjaFNldHRpbmdzLCBzZXR0aW5ncy5kZWZhdWx0RmV0Y2hTZXR0aW5ncyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZUZldGNoUmVzcG9uc2UoXG4gICAgcmVzcG9uc2U6IFJlc3BvbnNlXG4gICk6IFByb21pc2U8SlNPTkFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzcG9uc2VEZXRhaWw6IEpTT05BUElSZXNwb25zZSA9IHtcbiAgICAgIHJlc3BvbnNlXG4gICAgfTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwNCAmJiB0aGlzLnJlc3BvbnNlSGFzQ29udGVudChyZXNwb25zZSkpIHtcbiAgICAgICAgcmVzcG9uc2VEZXRhaWwuZG9jdW1lbnQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDMwNCAmJiByZXNwb25zZS5zdGF0dXMgIT09IDQwNCkge1xuICAgICAgaWYgKHRoaXMucmVzcG9uc2VIYXNDb250ZW50KHJlc3BvbnNlLCB0cnVlKSkge1xuICAgICAgICBjb25zdCBkb2N1bWVudCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGZXRjaFJlc3BvbnNlRXJyb3IocmVzcG9uc2UsIGRvY3VtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlRmV0Y2hSZXNwb25zZUVycm9yKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3BvbnNlRGV0YWlsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZUZldGNoUmVzcG9uc2VFcnJvcihcbiAgICByZXNwb25zZTogUmVzcG9uc2UsXG4gICAgZGF0YT86IHVua25vd25cbiAgKTogUHJvbWlzZTxFcnJvcj4ge1xuICAgIGxldCBlcnJvcjogYW55O1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gNDAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDUwMCkge1xuICAgICAgZXJyb3IgPSBuZXcgQ2xpZW50RXJyb3IocmVzcG9uc2Uuc3RhdHVzVGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yID0gbmV3IFNlcnZlckVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgIH1cbiAgICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICAgIGVycm9yLmRhdGEgPSBkYXRhO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZUZldGNoRXJyb3IoZTogRXJyb3IgfCBzdHJpbmcpOiBQcm9taXNlPEVycm9yPiB7XG4gICAgaWYgKHR5cGVvZiBlID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IE5ldHdvcmtFcnJvcihlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==