UNPKG

@data-client/rest

Version:

Quickly define typed REST resources and endpoints

283 lines (275 loc) 40.1 kB
import _objectDestructuringEmpty from "@babel/runtime/helpers/esm/objectDestructuringEmpty"; import _extends from "@babel/runtime/helpers/esm/extends"; import _classPrivateFieldLooseBase from "@babel/runtime/helpers/esm/classPrivateFieldLooseBase"; import _classPrivateFieldLooseKey from "@babel/runtime/helpers/esm/classPrivateFieldLooseKey"; import { Endpoint } from '@data-client/endpoint'; import extractCollection from './extractCollection.js'; import mapCollection from './mapCollection.js'; import NetworkError from './NetworkError.js'; import { createPaginationSchema } from './paginatedCollections.js'; import paramsToString from './paramsToString.js'; import { getUrlBase, getUrlTokens, getPathRegex, isPojo } from './RestHelpers.js'; const textLikeRe = /\btext\b|\bxml\b|\bhtml\b|\bjavascript\b|\bcss\b|\bcsv\b|\burlencoded\b/; function jsonResponse(response) { return response.json().catch(error => { error.status = 400; throw error; }); } /** Simplifies endpoint definitions that follow REST patterns * * @see https://dataclient.io/rest/api/RestEndpoint */ var _hasBody = /*#__PURE__*/_classPrivateFieldLooseKey("hasBody"); export default class RestEndpoint extends Endpoint { constructor(options) { var _options$fetch; super((_options$fetch = options.fetch) != null ? _options$fetch : async function (...args) { const urlParams = _classPrivateFieldLooseBase(this, _hasBody)[_hasBody] && args.length < 2 ? {} : args[0] || {}; const body = _classPrivateFieldLooseBase(this, _hasBody)[_hasBody] ? args[args.length - 1] : undefined; return this.fetchResponse(this.url(urlParams), await this.getRequestInit(body)).then(response => this.parseResponse(response)).then(res => this.process(res, ...args)); }, options); // we want to use the prototype chain here Object.defineProperty(this, _hasBody, { writable: true, value: void 0 }); if (!('sideEffect' in this) || 'method' in options && !('sideEffect' in options)) { this.sideEffect = options.method === 'GET' || options.method === undefined ? undefined : true; } if (this.method === undefined) { this.method = this.sideEffect ? 'POST' : 'GET'; } if (this.urlPrefix === undefined) { this.urlPrefix = ''; } _classPrivateFieldLooseBase(this, _hasBody)[_hasBody] = (!('body' in this) || this.body !== undefined) && !['GET', 'DELETE'].includes(this.method); /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { if (this.content && this.content !== 'json' && this.schema != null && typeof this.schema !== 'string' && typeof this.schema !== 'undefined') { console.error(`content '${this.content}' is incompatible with schema. Binary/text responses cannot be normalized. Use schema: undefined.`); } } Object.defineProperty(this, 'name', { get() { // using 'in' to ensure inheritance lookup if ('__name' in this) return this.__name; return this.urlPrefix + this.path; } }); } key(...args) { return `${this.method} ${this.url(_classPrivateFieldLooseBase(this, _hasBody)[_hasBody] && args.length < 2 ? {} : args[0] || {})}`; } /** Get the url */ url(urlParams = {}) { const tokens = getUrlTokens(this.path); const pathParams = {}; const searchParams = {}; Object.keys(urlParams).forEach(k => { if (tokens.has(k)) { if (urlParams[k] !== undefined) pathParams[k] = Array.isArray(urlParams[k]) ? urlParams[k].map(String) : String(urlParams[k]); } else { searchParams[k] = urlParams[k]; } }); const urlBase = getUrlBase(this.path)(pathParams); if (Object.keys(searchParams).length) { return `${this.urlPrefix}${urlBase}?${this.searchToString(searchParams)}`; } return `${this.urlPrefix}${urlBase}`; } /** Encode the url searchParams */ searchToString(searchParams) { return paramsToString(searchParams); } getHeaders(headers) { return headers; } /** Init options for fetch - run at fetch */ async getRequestInit(body) { const bodyIsPojo = isPojo(body); if (bodyIsPojo) { body = JSON.stringify(body); } const init = _extends({}, this.requestInit, { method: this.method, signal: this.signal, body }); if (!body || bodyIsPojo) { init.headers = _extends({ // default to application/json but allow user explicit overrides 'Content-Type': 'application/json' }, init.headers); } init.headers = await this.getHeaders(init.headers); return init; } /** Perform network request and resolve with HTTP Response */ fetchResponse(input, init) { return fetch(input, init).then(response => { if (!response.ok) { throw new NetworkError(response); } return response; }).catch(error => { // ensure CORS, network down, and parse errors are still caught by NetworkErrorBoundary if (error instanceof TypeError) { error.status = 500; } throw error; }); } parseResponse(response) { if (response.status === 204) return Promise.resolve(null); if (this.content) { /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { if (this.content !== 'json' && this.schema != null && typeof this.schema !== 'string' && typeof this.schema !== 'undefined') { const error = new NetworkError(response); error.status = 400; error.message = `content '${this.content}' is incompatible with schema. Binary/text responses cannot be normalized. Use schema: undefined.`; throw error; } } if (this.content === 'stream') return Promise.resolve(response.body); return this.content === 'json' ? jsonResponse(response) : response[this.content](); } const contentType = response.headers.get('content-type'); if (contentType != null && contentType.includes('json')) return jsonResponse(response); const isBinary = contentType && !textLikeRe.test(contentType); if (typeof this.schema === 'string' || typeof this.schema === 'undefined' || this.schema === null || this.process !== RestEndpoint.prototype.process) return isBinary ? response.blob() : response.text(); if (isBinary) { const error = new NetworkError(response); error.status = 400; error.message = `Unexpected binary content-type for schema ${this.schema}`; /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { error.message = `Unexpected binary content-type "${contentType}" for schema ${this.schema}. Binary responses cannot be normalized. Use schema: undefined or set content: 'blob'.`; } throw error; } return response.text().then(text => { const error = new NetworkError(response); error.status = 404; error.message = `Unexpected text response for schema ${this.schema}`; /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { if (!(contentType != null && contentType.includes('html') || text.startsWith('<!doctype html>'))) { if (tryParse(text) !== undefined) { error.message = `"content-type" header does not include "json", but JSON response found. See https://www.rfc-editor.org/rfc/rfc4627 for information on JSON responses Using parsed JSON. If text content was expected see https://dataclient.io/rest/api/RestEndpoint#parseResponse`; } } else { error.message = `Unexpected html response for schema ${this.schema} This likely means no API endpoint was configured for this request, resulting in an HTML fallback. Response (first 300 characters): ${text.substring(0, 300)}`; } } throw error; }); } process(value) { return value; } errorPolicy(error) { return error.status >= 500 ? 'soft' : undefined; } get pathRegex() { return getPathRegex(this.path); } testKey(key) { const prefix = this.method + ' ' + this.urlPrefix; if (!key.startsWith(prefix)) return false; let lastQuestion = key.lastIndexOf('?'); if (lastQuestion === -1) lastQuestion = undefined; return this.pathRegex.test(key.substring(prefix.length, lastQuestion)); } extend(options) { // make a constructor/prototype based off this // extend from it and init with options sent class E extends this.constructor {} Object.assign(E.prototype, this); return new E(// fetch get overridden by function prototype, so we must set it explicitly every time _extends({ fetch: this.fetch }, options)); } paginated(removeCursor) { if (typeof removeCursor === 'string') { const fieldName = removeCursor; removeCursor = _ref => { let params = _extends({}, (_objectDestructuringEmpty(_ref), _ref)); delete params[fieldName]; return [params]; }; } let found = false; const createPaginatedSchema = collection => { found = true; return createPaginationSchema(removeCursor, collection); }; const newSchema = mapCollection(this.schema, createPaginatedSchema); if (!found) throw new Error('Missing Collection'); const sup = this; return this.extend({ schema: newSchema, key(...args) { return sup.key.call(this, ...removeCursor(...args)); }, name: this.name + '.getPage' }); } get getPage() { return this.paginated(this.paginationField); } get push() { return this.extend({ method: 'POST', schema: extractCollection(this.schema, s => s.push), name: this.name + '.create' }); } get unshift() { return this.extend({ method: 'POST', schema: extractCollection(this.schema, s => s.unshift), name: this.name + '.create' }); } get assign() { return this.extend({ method: 'POST', schema: extractCollection(this.schema, s => s.assign), name: this.name + '.create' }); } get remove() { return this.extend({ method: 'PATCH', schema: extractCollection(this.schema, s => s.remove), name: this.name + '.partialUpdate' }); } get move() { const options = { method: 'PATCH', schema: extractCollection(this.schema, s => s.move), searchParams: undefined, name: this.name + '.partialUpdate' }; if (this.movePath) options.path = this.movePath; return this.extend(options); } } const tryParse = input => { try { return JSON.parse(input); } catch (e) { return undefined; } }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFbmRwb2ludCIsImV4dHJhY3RDb2xsZWN0aW9uIiwibWFwQ29sbGVjdGlvbiIsIk5ldHdvcmtFcnJvciIsImNyZWF0ZVBhZ2luYXRpb25TY2hlbWEiLCJwYXJhbXNUb1N0cmluZyIsImdldFVybEJhc2UiLCJnZXRVcmxUb2tlbnMiLCJnZXRQYXRoUmVnZXgiLCJpc1Bvam8iLCJ0ZXh0TGlrZVJlIiwianNvblJlc3BvbnNlIiwicmVzcG9uc2UiLCJqc29uIiwiY2F0Y2giLCJlcnJvciIsInN0YXR1cyIsIl9oYXNCb2R5IiwiX2NsYXNzUHJpdmF0ZUZpZWxkTG9vc2VLZXkiLCJSZXN0RW5kcG9pbnQiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJfb3B0aW9ucyRmZXRjaCIsImZldGNoIiwiYXJncyIsInVybFBhcmFtcyIsIl9jbGFzc1ByaXZhdGVGaWVsZExvb3NlQmFzZSIsImxlbmd0aCIsImJvZHkiLCJ1bmRlZmluZWQiLCJmZXRjaFJlc3BvbnNlIiwidXJsIiwiZ2V0UmVxdWVzdEluaXQiLCJ0aGVuIiwicGFyc2VSZXNwb25zZSIsInJlcyIsInByb2Nlc3MiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsIndyaXRhYmxlIiwidmFsdWUiLCJzaWRlRWZmZWN0IiwibWV0aG9kIiwidXJsUHJlZml4IiwiaW5jbHVkZXMiLCJlbnYiLCJOT0RFX0VOViIsImNvbnRlbnQiLCJzY2hlbWEiLCJjb25zb2xlIiwiZ2V0IiwiX19uYW1lIiwicGF0aCIsImtleSIsInRva2VucyIsInBhdGhQYXJhbXMiLCJzZWFyY2hQYXJhbXMiLCJrZXlzIiwiZm9yRWFjaCIsImsiLCJoYXMiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJTdHJpbmciLCJ1cmxCYXNlIiwic2VhcmNoVG9TdHJpbmciLCJnZXRIZWFkZXJzIiwiaGVhZGVycyIsImJvZHlJc1Bvam8iLCJKU09OIiwic3RyaW5naWZ5IiwiaW5pdCIsIl9leHRlbmRzIiwicmVxdWVzdEluaXQiLCJzaWduYWwiLCJpbnB1dCIsIm9rIiwiVHlwZUVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtZXNzYWdlIiwiY29udGVudFR5cGUiLCJpc0JpbmFyeSIsInRlc3QiLCJwcm90b3R5cGUiLCJibG9iIiwidGV4dCIsInN0YXJ0c1dpdGgiLCJ0cnlQYXJzZSIsInN1YnN0cmluZyIsImVycm9yUG9saWN5IiwicGF0aFJlZ2V4IiwidGVzdEtleSIsInByZWZpeCIsImxhc3RRdWVzdGlvbiIsImxhc3RJbmRleE9mIiwiZXh0ZW5kIiwiRSIsImFzc2lnbiIsInBhZ2luYXRlZCIsInJlbW92ZUN1cnNvciIsImZpZWxkTmFtZSIsIl9yZWYiLCJwYXJhbXMiLCJfb2JqZWN0RGVzdHJ1Y3R1cmluZ0VtcHR5IiwiZm91bmQiLCJjcmVhdGVQYWdpbmF0ZWRTY2hlbWEiLCJjb2xsZWN0aW9uIiwibmV3U2NoZW1hIiwiRXJyb3IiLCJzdXAiLCJjYWxsIiwibmFtZSIsImdldFBhZ2UiLCJwYWdpbmF0aW9uRmllbGQiLCJwdXNoIiwicyIsInVuc2hpZnQiLCJyZW1vdmUiLCJtb3ZlIiwibW92ZVBhdGgiLCJwYXJzZSIsImUiXSwic291cmNlcyI6WyIuLi9zcmMvUmVzdEVuZHBvaW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVuZHBvaW50IH0gZnJvbSAnQGRhdGEtY2xpZW50L2VuZHBvaW50JztcblxuaW1wb3J0IGV4dHJhY3RDb2xsZWN0aW9uIGZyb20gJy4vZXh0cmFjdENvbGxlY3Rpb24uanMnO1xuaW1wb3J0IG1hcENvbGxlY3Rpb24gZnJvbSAnLi9tYXBDb2xsZWN0aW9uLmpzJztcbmltcG9ydCBOZXR3b3JrRXJyb3IgZnJvbSAnLi9OZXR3b3JrRXJyb3IuanMnO1xuaW1wb3J0IHsgY3JlYXRlUGFnaW5hdGlvblNjaGVtYSB9IGZyb20gJy4vcGFnaW5hdGVkQ29sbGVjdGlvbnMuanMnO1xuaW1wb3J0IHBhcmFtc1RvU3RyaW5nIGZyb20gJy4vcGFyYW1zVG9TdHJpbmcuanMnO1xuaW1wb3J0IHtcbiAgZ2V0VXJsQmFzZSxcbiAgZ2V0VXJsVG9rZW5zLFxuICBnZXRQYXRoUmVnZXgsXG4gIGlzUG9qbyxcbn0gZnJvbSAnLi9SZXN0SGVscGVycy5qcyc7XG5cbmNvbnN0IHRleHRMaWtlUmUgPVxuICAvXFxidGV4dFxcYnxcXGJ4bWxcXGJ8XFxiaHRtbFxcYnxcXGJqYXZhc2NyaXB0XFxifFxcYmNzc1xcYnxcXGJjc3ZcXGJ8XFxidXJsZW5jb2RlZFxcYi87XG5cbmZ1bmN0aW9uIGpzb25SZXNwb25zZShyZXNwb25zZSkge1xuICByZXR1cm4gcmVzcG9uc2UuanNvbigpLmNhdGNoKGVycm9yID0+IHtcbiAgICBlcnJvci5zdGF0dXMgPSA0MDA7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH0pO1xufVxuXG4vKiogU2ltcGxpZmllcyBlbmRwb2ludCBkZWZpbml0aW9ucyB0aGF0IGZvbGxvdyBSRVNUIHBhdHRlcm5zXG4gKlxuICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vcmVzdC9hcGkvUmVzdEVuZHBvaW50XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc3RFbmRwb2ludCBleHRlbmRzIEVuZHBvaW50IHtcbiAgI2hhc0JvZHk7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICBzdXBlcihcbiAgICAgIG9wdGlvbnMuZmV0Y2ggPz9cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICBjb25zdCB1cmxQYXJhbXMgPVxuICAgICAgICAgICAgdGhpcy4jaGFzQm9keSAmJiBhcmdzLmxlbmd0aCA8IDIgPyB7fSA6IGFyZ3NbMF0gfHwge307XG4gICAgICAgICAgY29uc3QgYm9keSA9IHRoaXMuI2hhc0JvZHkgPyBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hSZXNwb25zZShcbiAgICAgICAgICAgIHRoaXMudXJsKHVybFBhcmFtcyksXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmdldFJlcXVlc3RJbml0KGJvZHkpLFxuICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHRoaXMucGFyc2VSZXNwb25zZShyZXNwb25zZSkpXG4gICAgICAgICAgICAudGhlbihyZXMgPT4gdGhpcy5wcm9jZXNzKHJlcywgLi4uYXJncykpO1xuICAgICAgICB9LFxuICAgICAgb3B0aW9ucyxcbiAgICApO1xuICAgIC8vIHdlIHdhbnQgdG8gdXNlIHRoZSBwcm90b3R5cGUgY2hhaW4gaGVyZVxuICAgIGlmIChcbiAgICAgICEoJ3NpZGVFZmZlY3QnIGluIHRoaXMpIHx8XG4gICAgICAoJ21ldGhvZCcgaW4gb3B0aW9ucyAmJiAhKCdzaWRlRWZmZWN0JyBpbiBvcHRpb25zKSlcbiAgICApIHtcbiAgICAgIHRoaXMuc2lkZUVmZmVjdCA9XG4gICAgICAgIG9wdGlvbnMubWV0aG9kID09PSAnR0VUJyB8fCBvcHRpb25zLm1ldGhvZCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgOiB0cnVlO1xuICAgIH1cbiAgICBpZiAodGhpcy5tZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5tZXRob2QgPSB0aGlzLnNpZGVFZmZlY3QgPyAnUE9TVCcgOiAnR0VUJztcbiAgICB9XG4gICAgaWYgKHRoaXMudXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMudXJsUHJlZml4ID0gJyc7XG4gICAgfVxuICAgIHRoaXMuI2hhc0JvZHkgPVxuICAgICAgKCEoJ2JvZHknIGluIHRoaXMpIHx8IHRoaXMuYm9keSAhPT0gdW5kZWZpbmVkKSAmJlxuICAgICAgIVsnR0VUJywgJ0RFTEVURSddLmluY2x1ZGVzKHRoaXMubWV0aG9kKTtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5jb250ZW50ICYmXG4gICAgICAgIHRoaXMuY29udGVudCAhPT0gJ2pzb24nICYmXG4gICAgICAgIHRoaXMuc2NoZW1hICE9IG51bGwgJiZcbiAgICAgICAgdHlwZW9mIHRoaXMuc2NoZW1hICE9PSAnc3RyaW5nJyAmJlxuICAgICAgICB0eXBlb2YgdGhpcy5zY2hlbWEgIT09ICd1bmRlZmluZWQnXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgY29udGVudCAnJHt0aGlzLmNvbnRlbnR9JyBpcyBpbmNvbXBhdGlibGUgd2l0aCBzY2hlbWEuIEJpbmFyeS90ZXh0IHJlc3BvbnNlcyBjYW5ub3QgYmUgbm9ybWFsaXplZC4gVXNlIHNjaGVtYTogdW5kZWZpbmVkLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICduYW1lJywge1xuICAgICAgZ2V0KCkge1xuICAgICAgICAvLyB1c2luZyAnaW4nIHRvIGVuc3VyZSBpbmhlcml0YW5jZSBsb29rdXBcbiAgICAgICAgaWYgKCdfX25hbWUnIGluIHRoaXMpIHJldHVybiB0aGlzLl9fbmFtZTtcbiAgICAgICAgcmV0dXJuIHRoaXMudXJsUHJlZml4ICsgdGhpcy5wYXRoO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGtleSguLi5hcmdzKSB7XG4gICAgcmV0dXJuIGAke3RoaXMubWV0aG9kfSAke3RoaXMudXJsKFxuICAgICAgdGhpcy4jaGFzQm9keSAmJiBhcmdzLmxlbmd0aCA8IDIgPyB7fSA6IGFyZ3NbMF0gfHwge30sXG4gICAgKX1gO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgdXJsICovXG4gIHVybCh1cmxQYXJhbXMgPSB7fSkge1xuICAgIGNvbnN0IHRva2VucyA9IGdldFVybFRva2Vucyh0aGlzLnBhdGgpO1xuICAgIGNvbnN0IHBhdGhQYXJhbXMgPSB7fTtcbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSB7fTtcbiAgICBPYmplY3Qua2V5cyh1cmxQYXJhbXMpLmZvckVhY2goayA9PiB7XG4gICAgICBpZiAodG9rZW5zLmhhcyhrKSkge1xuICAgICAgICBpZiAodXJsUGFyYW1zW2tdICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgcGF0aFBhcmFtc1trXSA9XG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KHVybFBhcmFtc1trXSkgP1xuICAgICAgICAgICAgICB1cmxQYXJhbXNba10ubWFwKFN0cmluZylcbiAgICAgICAgICAgIDogU3RyaW5nKHVybFBhcmFtc1trXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWFyY2hQYXJhbXNba10gPSB1cmxQYXJhbXNba107XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgdXJsQmFzZSA9IGdldFVybEJhc2UodGhpcy5wYXRoKShwYXRoUGFyYW1zKTtcbiAgICBpZiAoT2JqZWN0LmtleXMoc2VhcmNoUGFyYW1zKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnVybFByZWZpeH0ke3VybEJhc2V9PyR7dGhpcy5zZWFyY2hUb1N0cmluZyhzZWFyY2hQYXJhbXMpfWA7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLnVybFByZWZpeH0ke3VybEJhc2V9YDtcbiAgfVxuXG4gIC8qKiBFbmNvZGUgdGhlIHVybCBzZWFyY2hQYXJhbXMgKi9cbiAgc2VhcmNoVG9TdHJpbmcoc2VhcmNoUGFyYW1zKSB7XG4gICAgcmV0dXJuIHBhcmFtc1RvU3RyaW5nKHNlYXJjaFBhcmFtcyk7XG4gIH1cblxuICBnZXRIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICByZXR1cm4gaGVhZGVycztcbiAgfVxuXG4gIC8qKiBJbml0IG9wdGlvbnMgZm9yIGZldGNoIC0gcnVuIGF0IGZldGNoICovXG4gIGFzeW5jIGdldFJlcXVlc3RJbml0KGJvZHkpIHtcbiAgICBjb25zdCBib2R5SXNQb2pvID0gaXNQb2pvKGJvZHkpO1xuICAgIGlmIChib2R5SXNQb2pvKSB7XG4gICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkoYm9keSk7XG4gICAgfVxuICAgIGNvbnN0IGluaXQgPSB7XG4gICAgICAuLi50aGlzLnJlcXVlc3RJbml0LFxuICAgICAgbWV0aG9kOiB0aGlzLm1ldGhvZCxcbiAgICAgIHNpZ25hbDogdGhpcy5zaWduYWwsXG4gICAgICBib2R5LFxuICAgIH07XG4gICAgaWYgKCFib2R5IHx8IGJvZHlJc1Bvam8pIHtcbiAgICAgIGluaXQuaGVhZGVycyA9IHtcbiAgICAgICAgLy8gZGVmYXVsdCB0byBhcHBsaWNhdGlvbi9qc29uIGJ1dCBhbGxvdyB1c2VyIGV4cGxpY2l0IG92ZXJyaWRlc1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAuLi5pbml0LmhlYWRlcnMsXG4gICAgICB9O1xuICAgIH1cbiAgICBpbml0LmhlYWRlcnMgPSBhd2FpdCB0aGlzLmdldEhlYWRlcnMoaW5pdC5oZWFkZXJzKTtcbiAgICByZXR1cm4gaW5pdDtcbiAgfVxuXG4gIC8qKiBQZXJmb3JtIG5ldHdvcmsgcmVxdWVzdCBhbmQgcmVzb2x2ZSB3aXRoIEhUVFAgUmVzcG9uc2UgKi9cbiAgZmV0Y2hSZXNwb25zZShpbnB1dCwgaW5pdCkge1xuICAgIHJldHVybiBmZXRjaChpbnB1dCwgaW5pdClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgIHRocm93IG5ldyBOZXR3b3JrRXJyb3IocmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvLyBlbnN1cmUgQ09SUywgbmV0d29yayBkb3duLCBhbmQgcGFyc2UgZXJyb3JzIGFyZSBzdGlsbCBjYXVnaHQgYnkgTmV0d29ya0Vycm9yQm91bmRhcnlcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVHlwZUVycm9yKSB7XG4gICAgICAgICAgZXJyb3Iuc3RhdHVzID0gNTAwO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gIH1cblxuICBwYXJzZVJlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0KSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmNvbnRlbnQgIT09ICdqc29uJyAmJlxuICAgICAgICAgIHRoaXMuc2NoZW1hICE9IG51bGwgJiZcbiAgICAgICAgICB0eXBlb2YgdGhpcy5zY2hlbWEgIT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgdHlwZW9mIHRoaXMuc2NoZW1hICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBOZXR3b3JrRXJyb3IocmVzcG9uc2UpO1xuICAgICAgICAgIGVycm9yLnN0YXR1cyA9IDQwMDtcbiAgICAgICAgICBlcnJvci5tZXNzYWdlID0gYGNvbnRlbnQgJyR7dGhpcy5jb250ZW50fScgaXMgaW5jb21wYXRpYmxlIHdpdGggc2NoZW1hLiBCaW5hcnkvdGV4dCByZXNwb25zZXMgY2Fubm90IGJlIG5vcm1hbGl6ZWQuIFVzZSBzY2hlbWE6IHVuZGVmaW5lZC5gO1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jb250ZW50ID09PSAnc3RyZWFtJykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZS5ib2R5KTtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQgPT09ICdqc29uJyA/XG4gICAgICAgICAganNvblJlc3BvbnNlKHJlc3BvbnNlKVxuICAgICAgICA6IHJlc3BvbnNlW3RoaXMuY29udGVudF0oKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50VHlwZSA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKTtcbiAgICBpZiAoY29udGVudFR5cGU/LmluY2x1ZGVzKCdqc29uJykpIHJldHVybiBqc29uUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gICAgY29uc3QgaXNCaW5hcnkgPSBjb250ZW50VHlwZSAmJiAhdGV4dExpa2VSZS50ZXN0KGNvbnRlbnRUeXBlKTtcblxuICAgIGlmIChcbiAgICAgIHR5cGVvZiB0aGlzLnNjaGVtYSA9PT0gJ3N0cmluZycgfHxcbiAgICAgIHR5cGVvZiB0aGlzLnNjaGVtYSA9PT0gJ3VuZGVmaW5lZCcgfHxcbiAgICAgIHRoaXMuc2NoZW1hID09PSBudWxsIHx8XG4gICAgICB0aGlzLnByb2Nlc3MgIT09IFJlc3RFbmRwb2ludC5wcm90b3R5cGUucHJvY2Vzc1xuICAgIClcbiAgICAgIHJldHVybiBpc0JpbmFyeSA/IHJlc3BvbnNlLmJsb2IoKSA6IHJlc3BvbnNlLnRleHQoKTtcblxuICAgIGlmIChpc0JpbmFyeSkge1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgTmV0d29ya0Vycm9yKHJlc3BvbnNlKTtcbiAgICAgIGVycm9yLnN0YXR1cyA9IDQwMDtcbiAgICAgIGVycm9yLm1lc3NhZ2UgPSBgVW5leHBlY3RlZCBiaW5hcnkgY29udGVudC10eXBlIGZvciBzY2hlbWEgJHt0aGlzLnNjaGVtYX1gO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGVycm9yLm1lc3NhZ2UgPSBgVW5leHBlY3RlZCBiaW5hcnkgY29udGVudC10eXBlIFwiJHtjb250ZW50VHlwZX1cIiBmb3Igc2NoZW1hICR7dGhpcy5zY2hlbWF9LiBCaW5hcnkgcmVzcG9uc2VzIGNhbm5vdCBiZSBub3JtYWxpemVkLiBVc2Ugc2NoZW1hOiB1bmRlZmluZWQgb3Igc2V0IGNvbnRlbnQ6ICdibG9iJy5gO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKS50aGVuKHRleHQgPT4ge1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgTmV0d29ya0Vycm9yKHJlc3BvbnNlKTtcbiAgICAgIGVycm9yLnN0YXR1cyA9IDQwNDtcbiAgICAgIGVycm9yLm1lc3NhZ2UgPSBgVW5leHBlY3RlZCB0ZXh0IHJlc3BvbnNlIGZvciBzY2hlbWEgJHt0aGlzLnNjaGVtYX1gO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhKGNvbnRlbnRUeXBlPy5pbmNsdWRlcygnaHRtbCcpIHx8IHRleHQuc3RhcnRzV2l0aCgnPCFkb2N0eXBlIGh0bWw+JykpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmICh0cnlQYXJzZSh0ZXh0KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gYFwiY29udGVudC10eXBlXCIgaGVhZGVyIGRvZXMgbm90IGluY2x1ZGUgXCJqc29uXCIsIGJ1dCBKU09OIHJlc3BvbnNlIGZvdW5kLlxuU2VlIGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmM0NjI3IGZvciBpbmZvcm1hdGlvbiBvbiBKU09OIHJlc3BvbnNlc1xuXG5Vc2luZyBwYXJzZWQgSlNPTi5cbklmIHRleHQgY29udGVudCB3YXMgZXhwZWN0ZWQgc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9SZXN0RW5kcG9pbnQjcGFyc2VSZXNwb25zZWA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVycm9yLm1lc3NhZ2UgPSBgVW5leHBlY3RlZCBodG1sIHJlc3BvbnNlIGZvciBzY2hlbWEgJHt0aGlzLnNjaGVtYX1cblRoaXMgbGlrZWx5IG1lYW5zIG5vIEFQSSBlbmRwb2ludCB3YXMgY29uZmlndXJlZCBmb3IgdGhpcyByZXF1ZXN0LCByZXN1bHRpbmcgaW4gYW4gSFRNTCBmYWxsYmFjay5cblxuUmVzcG9uc2UgKGZpcnN0IDMwMCBjaGFyYWN0ZXJzKTogJHt0ZXh0LnN1YnN0cmluZygwLCAzMDApfWA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuICB9XG5cbiAgcHJvY2Vzcyh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGVycm9yUG9saWN5KGVycm9yKSB7XG4gICAgcmV0dXJuIGVycm9yLnN0YXR1cyA+PSA1MDAgPyAnc29mdCcgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBnZXQgcGF0aFJlZ2V4KCkge1xuICAgIHJldHVybiBnZXRQYXRoUmVnZXgodGhpcy5wYXRoKTtcbiAgfVxuXG4gIHRlc3RLZXkoa2V5KSB7XG4gICAgY29uc3QgcHJlZml4ID0gdGhpcy5tZXRob2QgKyAnICcgKyB0aGlzLnVybFByZWZpeDtcbiAgICBpZiAoIWtleS5zdGFydHNXaXRoKHByZWZpeCkpIHJldHVybiBmYWxzZTtcbiAgICBsZXQgbGFzdFF1ZXN0aW9uID0ga2V5Lmxhc3RJbmRleE9mKCc/Jyk7XG4gICAgaWYgKGxhc3RRdWVzdGlvbiA9PT0gLTEpIGxhc3RRdWVzdGlvbiA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdGhpcy5wYXRoUmVnZXgudGVzdChrZXkuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgsIGxhc3RRdWVzdGlvbikpO1xuICB9XG5cbiAgZXh0ZW5kKG9wdGlvbnMpIHtcbiAgICAvLyBtYWtlIGEgY29uc3RydWN0b3IvcHJvdG90eXBlIGJhc2VkIG9mZiB0aGlzXG4gICAgLy8gZXh0ZW5kIGZyb20gaXQgYW5kIGluaXQgd2l0aCBvcHRpb25zIHNlbnRcbiAgICBjbGFzcyBFIGV4dGVuZHMgdGhpcy5jb25zdHJ1Y3RvciB7fVxuXG4gICAgT2JqZWN0LmFzc2lnbihFLnByb3RvdHlwZSwgdGhpcyk7XG5cbiAgICByZXR1cm4gbmV3IEUoXG4gICAgICAvLyAgZmV0Y2ggZ2V0IG92ZXJyaWRkZW4gYnkgZnVuY3Rpb24gcHJvdG90eXBlLCBzbyB3ZSBtdXN0IHNldCBpdCBleHBsaWNpdGx5IGV2ZXJ5IHRpbWVcbiAgICAgIHsgZmV0Y2g6IHRoaXMuZmV0Y2gsIC4uLm9wdGlvbnMgfSxcbiAgICApO1xuICB9XG5cbiAgcGFnaW5hdGVkKHJlbW92ZUN1cnNvcikge1xuICAgIGlmICh0eXBlb2YgcmVtb3ZlQ3Vyc29yID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZmllbGROYW1lID0gcmVtb3ZlQ3Vyc29yO1xuICAgICAgcmVtb3ZlQ3Vyc29yID0gKHsgLi4ucGFyYW1zIH0pID0+IHtcbiAgICAgICAgZGVsZXRlIHBhcmFtc1tmaWVsZE5hbWVdO1xuICAgICAgICByZXR1cm4gW3BhcmFtc107XG4gICAgICB9O1xuICAgIH1cbiAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICBjb25zdCBjcmVhdGVQYWdpbmF0ZWRTY2hlbWEgPSBjb2xsZWN0aW9uID0+IHtcbiAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgIHJldHVybiBjcmVhdGVQYWdpbmF0aW9uU2NoZW1hKHJlbW92ZUN1cnNvciwgY29sbGVjdGlvbik7XG4gICAgfTtcbiAgICBjb25zdCBuZXdTY2hlbWEgPSBtYXBDb2xsZWN0aW9uKHRoaXMuc2NoZW1hLCBjcmVhdGVQYWdpbmF0ZWRTY2hlbWEpO1xuXG4gICAgaWYgKCFmb3VuZCkgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIENvbGxlY3Rpb24nKTtcbiAgICBjb25zdCBzdXAgPSB0aGlzO1xuXG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5kKHtcbiAgICAgIHNjaGVtYTogbmV3U2NoZW1hLFxuICAgICAga2V5KC4uLmFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHN1cC5rZXkuY2FsbCh0aGlzLCAuLi5yZW1vdmVDdXJzb3IoLi4uYXJncykpO1xuICAgICAgfSxcbiAgICAgIG5hbWU6IHRoaXMubmFtZSArICcuZ2V0UGFnZScsXG4gICAgfSk7XG4gIH1cblxuICBnZXQgZ2V0UGFnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYWdpbmF0ZWQodGhpcy5wYWdpbmF0aW9uRmllbGQpO1xuICB9XG5cbiAgZ2V0IHB1c2goKSB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5kKHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgc2NoZW1hOiBleHRyYWN0Q29sbGVjdGlvbih0aGlzLnNjaGVtYSwgcyA9PiBzLnB1c2gpLFxuICAgICAgbmFtZTogdGhpcy5uYW1lICsgJy5jcmVhdGUnLFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHVuc2hpZnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5kKHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgc2NoZW1hOiBleHRyYWN0Q29sbGVjdGlvbih0aGlzLnNjaGVtYSwgcyA9PiBzLnVuc2hpZnQpLFxuICAgICAgbmFtZTogdGhpcy5uYW1lICsgJy5jcmVhdGUnLFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGFzc2lnbigpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbmQoe1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBzY2hlbWE6IGV4dHJhY3RDb2xsZWN0aW9uKHRoaXMuc2NoZW1hLCBzID0+IHMuYXNzaWduKSxcbiAgICAgIG5hbWU6IHRoaXMubmFtZSArICcuY3JlYXRlJyxcbiAgICB9KTtcbiAgfVxuXG4gIGdldCByZW1vdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5kKHtcbiAgICAgIG1ldGhvZDogJ1BBVENIJyxcbiAgICAgIHNjaGVtYTogZXh0cmFjdENvbGxlY3Rpb24odGhpcy5zY2hlbWEsIHMgPT4gcy5yZW1vdmUpLFxuICAgICAgbmFtZTogdGhpcy5uYW1lICsgJy5wYXJ0aWFsVXBkYXRlJyxcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBtb3ZlKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBtZXRob2Q6ICdQQVRDSCcsXG4gICAgICBzY2hlbWE6IGV4dHJhY3RDb2xsZWN0aW9uKHRoaXMuc2NoZW1hLCBzID0+IHMubW92ZSksXG4gICAgICBzZWFyY2hQYXJhbXM6IHVuZGVmaW5lZCxcbiAgICAgIG5hbWU6IHRoaXMubmFtZSArICcucGFydGlhbFVwZGF0ZScsXG4gICAgfTtcbiAgICBpZiAodGhpcy5tb3ZlUGF0aCkgb3B0aW9ucy5wYXRoID0gdGhpcy5tb3ZlUGF0aDtcbiAgICByZXR1cm4gdGhpcy5leHRlbmQob3B0aW9ucyk7XG4gIH1cbn1cblxuY29uc3QgdHJ5UGFyc2UgPSBpbnB1dCA9PiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoaW5wdXQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLFNBQVNBLFFBQVEsUUFBUSx1QkFBdUI7QUFFaEQsT0FBT0MsaUJBQWlCLE1BQU0sd0JBQXdCO0FBQ3RELE9BQU9DLGFBQWEsTUFBTSxvQkFBb0I7QUFDOUMsT0FBT0MsWUFBWSxNQUFNLG1CQUFtQjtBQUM1QyxTQUFTQyxzQkFBc0IsUUFBUSwyQkFBMkI7QUFDbEUsT0FBT0MsY0FBYyxNQUFNLHFCQUFxQjtBQUNoRCxTQUNFQyxVQUFVLEVBQ1ZDLFlBQVksRUFDWkMsWUFBWSxFQUNaQyxNQUFNLFFBQ0Qsa0JBQWtCO0FBRXpCLE1BQU1DLFVBQVUsR0FDZCx5RUFBeUU7QUFFM0UsU0FBU0MsWUFBWUEsQ0FBQ0MsUUFBUSxFQUFFO0VBQzlCLE9BQU9BLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxDQUFDQyxLQUFLLElBQUk7SUFDcENBLEtBQUssQ0FBQ0MsTUFBTSxHQUFHLEdBQUc7SUFDbEIsTUFBTUQsS0FBSztFQUNiLENBQUMsQ0FBQztBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSEEsSUFBQUUsUUFBQSxn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