@data-client/rest
Version:
Quickly define typed REST resources and endpoints
148 lines (145 loc) • 21 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
const _excluded = ["path", "schema", "Endpoint", "Collection", "nonFilterArgumentKeys", "optimistic", "paginationField"];
import { schema } from '@data-client/endpoint';
import RestEndpoint from './RestEndpoint.js';
import { shortenPath } from './RestHelpers.js';
const {
Invalidate,
Collection: BaseCollection
} = schema;
/** Creates collection of Endpoints for common operations on a given data/schema.
*
* @see https://dataclient.io/rest/api/resource
*/
export default function resource(_ref) {
let {
path,
schema,
Endpoint = RestEndpoint,
Collection = BaseCollection,
nonFilterArgumentKeys,
optimistic,
paginationField
} = _ref,
extraOptions = _objectWithoutPropertiesLoose(_ref, _excluded);
if (process.env.NODE_ENV !== 'production') {
// if they lowercase and it looks like they meant to use upper-case version
if ('endpoint' in extraOptions && Endpoint === RestEndpoint && typeof extraOptions['endpoint'] === 'function' && extraOptions['endpoint'] && Object.prototype.isPrototypeOf.call(RestEndpoint.prototype, extraOptions['endpoint'].prototype)) {
console.warn(`You passed 'endpoint' option; did you mean to use Endpoint?
https://dataclient.io/rest/api/resource#endpoint
This parameter must be capitalized.
This warning will not show in production.`);
}
// if they lowercase and it looks like they meant to use upper-case version
if ('collection' in extraOptions && Collection === BaseCollection && typeof extraOptions['collection'] === 'function' && extraOptions['collection'] && Object.prototype.isPrototypeOf.call(BaseCollection.prototype, extraOptions['collection'].prototype)) {
console.warn(`You passed 'collection' option; did you mean to use Collection?
https://dataclient.io/rest/api/resource#collection
This parameter must be capitalized.
This warning will not show in production.`);
}
}
const shortenedPath = shortenPath(path);
const getName = name => `${schema == null ? void 0 : schema.name}.${name}`;
// this accounts for derivative endpoints
function extendMember(extended, key, options) {
extended[key] = extended[key].extend(options);
}
const extraMutateOptions = _extends({}, extraOptions);
const extraPartialOptions = _extends({}, extraOptions);
const get = new Endpoint(_extends({}, extraOptions, {
path,
schema,
name: getName('get')
}));
if (optimistic) {
extraMutateOptions.getOptimisticResponse = optimisticUpdate;
// TODO: Check that schema is a queryable, otherwise this doesn't make sense
extraPartialOptions.getOptimisticResponse = optimisticPartial(schema);
}
const getList = new Endpoint(_extends({}, extraMutateOptions, {
paginationField: paginationField,
movePath: path,
path: shortenedPath,
schema: new Collection([schema], nonFilterArgumentKeys === undefined ? undefined : {
nonFilterArgumentKeys
}),
name: getName('getList')
}));
const ret = {
get,
getList,
// TODO(deprecated): remove this once we remove creates
create: getList.push.extend({
name: getName('create')
}),
update: new Endpoint(_extends({}, extraMutateOptions, {
path,
schema,
method: 'PUT',
name: getName('update')
})),
// TODO(breaking): Move to getList.move
partialUpdate: new Endpoint(_extends({}, extraPartialOptions, {
path,
schema,
method: 'PATCH',
name: getName('partialUpdate')
})),
delete: new Endpoint(_extends({}, extraMutateOptions, {
path,
schema:
// Entity || Union
schema.process || schema._hoistable ? new Invalidate(schema) : schema,
method: 'DELETE',
name: getName('delete'),
process(res, params) {
return res && Object.keys(res).length ? res : params;
},
getOptimisticResponse: optimistic ? optimisticDelete : undefined
})),
extend(...args) {
if (typeof args[0] === 'string') {
const [key, options] = args;
if (key in this) {
const extended = _extends({}, this);
extendMember(extended, key, options);
return extended;
} else {
return _extends({}, this, {
[key]: this.get.extend(options)
});
}
} else if (typeof args[0] === 'function') {
const extended = args[0](this);
return _extends({}, this, extended);
}
const overrides = args[0];
const extended = _extends({}, this);
for (const key in overrides) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
extendMember(extended, key, overrides[key]);
}
return extended;
}
};
return ret;
}
function optimisticUpdate(snap, params, body) {
return _extends({}, params, ensurePojo(body));
}
function optimisticPartial(schema) {
return function (snap, params, body) {
const data = snap.get(schema, params);
if (!data) throw snap.abort;
return _extends({}, params, data, ensurePojo(body));
};
}
function optimisticDelete(snap, params) {
return params;
}
function ensurePojo(body) {
return body instanceof FormData ? Object.fromEntries(body.entries()) : body;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzY2hlbWEiLCJSZXN0RW5kcG9pbnQiLCJzaG9ydGVuUGF0aCIsIkludmFsaWRhdGUiLCJDb2xsZWN0aW9uIiwiQmFzZUNvbGxlY3Rpb24iLCJyZXNvdXJjZSIsIl9yZWYiLCJwYXRoIiwiRW5kcG9pbnQiLCJub25GaWx0ZXJBcmd1bWVudEtleXMiLCJvcHRpbWlzdGljIiwicGFnaW5hdGlvbkZpZWxkIiwiZXh0cmFPcHRpb25zIiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UiLCJfZXhjbHVkZWQiLCJwcm9jZXNzIiwiZW52IiwiTk9ERV9FTlYiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJpc1Byb3RvdHlwZU9mIiwiY2FsbCIsImNvbnNvbGUiLCJ3YXJuIiwic2hvcnRlbmVkUGF0aCIsImdldE5hbWUiLCJuYW1lIiwiZXh0ZW5kTWVtYmVyIiwiZXh0ZW5kZWQiLCJrZXkiLCJvcHRpb25zIiwiZXh0ZW5kIiwiZXh0cmFNdXRhdGVPcHRpb25zIiwiX2V4dGVuZHMiLCJleHRyYVBhcnRpYWxPcHRpb25zIiwiZ2V0IiwiZ2V0T3B0aW1pc3RpY1Jlc3BvbnNlIiwib3B0aW1pc3RpY1VwZGF0ZSIsIm9wdGltaXN0aWNQYXJ0aWFsIiwiZ2V0TGlzdCIsIm1vdmVQYXRoIiwidW5kZWZpbmVkIiwicmV0IiwiY3JlYXRlIiwicHVzaCIsInVwZGF0ZSIsIm1ldGhvZCIsInBhcnRpYWxVcGRhdGUiLCJkZWxldGUiLCJfaG9pc3RhYmxlIiwicmVzIiwicGFyYW1zIiwia2V5cyIsImxlbmd0aCIsIm9wdGltaXN0aWNEZWxldGUiLCJhcmdzIiwib3ZlcnJpZGVzIiwic25hcCIsImJvZHkiLCJlbnN1cmVQb2pvIiwiZGF0YSIsImFib3J0IiwiRm9ybURhdGEiLCJmcm9tRW50cmllcyIsImVudHJpZXMiXSwic291cmNlcyI6WyIuLi9zcmMvcmVzb3VyY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnQGRhdGEtY2xpZW50L2VuZHBvaW50JztcbmltcG9ydCB0eXBlIHsgU25hcHNob3RJbnRlcmZhY2UsIFF1ZXJ5YWJsZSB9IGZyb20gJ0BkYXRhLWNsaWVudC9lbmRwb2ludCc7XG5cbmltcG9ydCB7XG4gIFJlc291cmNlR2VuZXJpY3MsXG4gIFJlc291cmNlT3B0aW9ucyxcbiAgUmVzb3VyY2UsXG4gIFJlc291cmNlSW50ZXJmYWNlLFxufSBmcm9tICcuL3Jlc291cmNlVHlwZXMuanMnO1xuaW1wb3J0IFJlc3RFbmRwb2ludCwge1xuICBHZXRFbmRwb2ludCxcbiAgUGFydGlhbFJlc3RHZW5lcmljcyxcbiAgUmVzdEVuZHBvaW50T3B0aW9ucyxcbiAgUmVzdEluc3RhbmNlQmFzZSxcbn0gZnJvbSAnLi9SZXN0RW5kcG9pbnQuanMnO1xuaW1wb3J0IHsgc2hvcnRlblBhdGggfSBmcm9tICcuL1Jlc3RIZWxwZXJzLmpzJztcblxuY29uc3QgeyBJbnZhbGlkYXRlLCBDb2xsZWN0aW9uOiBCYXNlQ29sbGVjdGlvbiB9ID0gc2NoZW1hO1xuXG4vKiogQ3JlYXRlcyBjb2xsZWN0aW9uIG9mIEVuZHBvaW50cyBmb3IgY29tbW9uIG9wZXJhdGlvbnMgb24gYSBnaXZlbiBkYXRhL3NjaGVtYS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9yZXNvdXJjZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXNvdXJjZTxPIGV4dGVuZHMgUmVzb3VyY2VHZW5lcmljcz4oe1xuICBwYXRoLFxuICBzY2hlbWEsXG4gIEVuZHBvaW50ID0gUmVzdEVuZHBvaW50LFxuICBDb2xsZWN0aW9uID0gQmFzZUNvbGxlY3Rpb24sXG4gIG5vbkZpbHRlckFyZ3VtZW50S2V5cyxcbiAgb3B0aW1pc3RpYyxcbiAgcGFnaW5hdGlvbkZpZWxkLFxuICAuLi5leHRyYU9wdGlvbnNcbn06IFJlYWRvbmx5PE8+ICYgUmVzb3VyY2VPcHRpb25zKTogUmVzb3VyY2U8Tz4ge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIC8vIGlmIHRoZXkgbG93ZXJjYXNlIGFuZCBpdCBsb29rcyBsaWtlIHRoZXkgbWVhbnQgdG8gdXNlIHVwcGVyLWNhc2UgdmVyc2lvblxuICAgIGlmIChcbiAgICAgICdlbmRwb2ludCcgaW4gZXh0cmFPcHRpb25zICYmXG4gICAgICBFbmRwb2ludCA9PT0gUmVzdEVuZHBvaW50ICYmXG4gICAgICB0eXBlb2YgZXh0cmFPcHRpb25zWydlbmRwb2ludCddID09PSAnZnVuY3Rpb24nICYmXG4gICAgICBleHRyYU9wdGlvbnNbJ2VuZHBvaW50J10gJiZcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaXNQcm90b3R5cGVPZi5jYWxsKFxuICAgICAgICBSZXN0RW5kcG9pbnQucHJvdG90eXBlLFxuICAgICAgICAoZXh0cmFPcHRpb25zWydlbmRwb2ludCddIGFzIGFueSkucHJvdG90eXBlLFxuICAgICAgKVxuICAgICkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgWW91IHBhc3NlZCAnZW5kcG9pbnQnIG9wdGlvbjsgZGlkIHlvdSBtZWFuIHRvIHVzZSBFbmRwb2ludD9cbmh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9yZXNvdXJjZSNlbmRwb2ludFxuVGhpcyBwYXJhbWV0ZXIgbXVzdCBiZSBjYXBpdGFsaXplZC5cblxuVGhpcyB3YXJuaW5nIHdpbGwgbm90IHNob3cgaW4gcHJvZHVjdGlvbi5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gaWYgdGhleSBsb3dlcmNhc2UgYW5kIGl0IGxvb2tzIGxpa2UgdGhleSBtZWFudCB0byB1c2UgdXBwZXItY2FzZSB2ZXJzaW9uXG4gICAgaWYgKFxuICAgICAgJ2NvbGxlY3Rpb24nIGluIGV4dHJhT3B0aW9ucyAmJlxuICAgICAgQ29sbGVjdGlvbiA9PT0gQmFzZUNvbGxlY3Rpb24gJiZcbiAgICAgIHR5cGVvZiBleHRyYU9wdGlvbnNbJ2NvbGxlY3Rpb24nXSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgZXh0cmFPcHRpb25zWydjb2xsZWN0aW9uJ10gJiZcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaXNQcm90b3R5cGVPZi5jYWxsKFxuICAgICAgICBCYXNlQ29sbGVjdGlvbi5wcm90b3R5cGUsXG4gICAgICAgIChleHRyYU9wdGlvbnNbJ2NvbGxlY3Rpb24nXSBhcyBhbnkpLnByb3RvdHlwZSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFlvdSBwYXNzZWQgJ2NvbGxlY3Rpb24nIG9wdGlvbjsgZGlkIHlvdSBtZWFuIHRvIHVzZSBDb2xsZWN0aW9uP1xuaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL3Jlc291cmNlI2NvbGxlY3Rpb25cblRoaXMgcGFyYW1ldGVyIG11c3QgYmUgY2FwaXRhbGl6ZWQuXG5cblRoaXMgd2FybmluZyB3aWxsIG5vdCBzaG93IGluIHByb2R1Y3Rpb24uYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHNob3J0ZW5lZFBhdGggPSBzaG9ydGVuUGF0aChwYXRoKTtcbiAgY29uc3QgZ2V0TmFtZSA9IChuYW1lOiBzdHJpbmcpID0+IGAkeyhzY2hlbWEgYXMgYW55KT8ubmFtZX0uJHtuYW1lfWA7XG4gIC8vIHRoaXMgYWNjb3VudHMgZm9yIGRlcml2YXRpdmUgZW5kcG9pbnRzXG4gIGZ1bmN0aW9uIGV4dGVuZE1lbWJlcihleHRlbmRlZDogYW55LCBrZXk6IHN0cmluZywgb3B0aW9uczogYW55KSB7XG4gICAgZXh0ZW5kZWRba2V5XSA9IGV4dGVuZGVkW2tleV0uZXh0ZW5kKG9wdGlvbnMpO1xuICB9XG5cbiAgY29uc3QgZXh0cmFNdXRhdGVPcHRpb25zID0geyAuLi5leHRyYU9wdGlvbnMgfTtcbiAgY29uc3QgZXh0cmFQYXJ0aWFsT3B0aW9ucyA9IHsgLi4uZXh0cmFPcHRpb25zIH07XG4gIGNvbnN0IGdldDogR2V0RW5kcG9pbnQ8eyBwYXRoOiBPWydwYXRoJ107IHNjaGVtYTogT1snc2NoZW1hJ10gfT4gPVxuICAgIG5ldyBFbmRwb2ludCh7XG4gICAgICAuLi5leHRyYU9wdGlvbnMsXG4gICAgICBwYXRoLFxuICAgICAgc2NoZW1hLFxuICAgICAgbmFtZTogZ2V0TmFtZSgnZ2V0JyksXG4gICAgfSkgYXMgYW55O1xuICBpZiAob3B0aW1pc3RpYykge1xuICAgIChleHRyYU11dGF0ZU9wdGlvbnMgYXMgYW55KS5nZXRPcHRpbWlzdGljUmVzcG9uc2UgPSBvcHRpbWlzdGljVXBkYXRlO1xuICAgIC8vIFRPRE86IENoZWNrIHRoYXQgc2NoZW1hIGlzIGEgcXVlcnlhYmxlLCBvdGhlcndpc2UgdGhpcyBkb2Vzbid0IG1ha2Ugc2Vuc2VcbiAgICAoZXh0cmFQYXJ0aWFsT3B0aW9ucyBhcyBhbnkpLmdldE9wdGltaXN0aWNSZXNwb25zZSA9IG9wdGltaXN0aWNQYXJ0aWFsKFxuICAgICAgc2NoZW1hIGFzIGFueSxcbiAgICApO1xuICB9XG4gIGNvbnN0IGdldExpc3QgPSBuZXcgRW5kcG9pbnQoe1xuICAgIC4uLmV4dHJhTXV0YXRlT3B0aW9ucyxcbiAgICBwYWdpbmF0aW9uRmllbGQ6IHBhZ2luYXRpb25GaWVsZCBhcyBzdHJpbmcsXG4gICAgbW92ZVBhdGg6IHBhdGgsXG4gICAgcGF0aDogc2hvcnRlbmVkUGF0aCxcbiAgICBzY2hlbWE6IG5ldyBDb2xsZWN0aW9uKFxuICAgICAgW3NjaGVtYSBhcyBhbnldLFxuICAgICAgbm9uRmlsdGVyQXJndW1lbnRLZXlzID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiAoXG4gICAgICAgIHsgbm9uRmlsdGVyQXJndW1lbnRLZXlzIH1cbiAgICAgICksXG4gICAgKSxcbiAgICBuYW1lOiBnZXROYW1lKCdnZXRMaXN0JyksXG4gIH0pO1xuICBjb25zdCByZXQgPSB7XG4gICAgZ2V0LFxuICAgIGdldExpc3QsXG4gICAgLy8gVE9ETyhkZXByZWNhdGVkKTogcmVtb3ZlIHRoaXMgb25jZSB3ZSByZW1vdmUgY3JlYXRlc1xuICAgIGNyZWF0ZTogZ2V0TGlzdC5wdXNoLmV4dGVuZCh7IG5hbWU6IGdldE5hbWUoJ2NyZWF0ZScpIH0pLFxuICAgIHVwZGF0ZTogbmV3IEVuZHBvaW50KHtcbiAgICAgIC4uLmV4dHJhTXV0YXRlT3B0aW9ucyxcbiAgICAgIHBhdGgsXG4gICAgICBzY2hlbWEsXG4gICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgbmFtZTogZ2V0TmFtZSgndXBkYXRlJyksXG4gICAgfSksXG4gICAgLy8gVE9ETyhicmVha2luZyk6IE1vdmUgdG8gZ2V0TGlzdC5tb3ZlXG4gICAgcGFydGlhbFVwZGF0ZTogbmV3IEVuZHBvaW50KHtcbiAgICAgIC4uLmV4dHJhUGFydGlhbE9wdGlvbnMsXG4gICAgICBwYXRoLFxuICAgICAgc2NoZW1hLFxuICAgICAgbWV0aG9kOiAnUEFUQ0gnLFxuICAgICAgbmFtZTogZ2V0TmFtZSgncGFydGlhbFVwZGF0ZScpLFxuICAgIH0pLFxuICAgIGRlbGV0ZTogbmV3IEVuZHBvaW50KHtcbiAgICAgIC4uLmV4dHJhTXV0YXRlT3B0aW9ucyxcbiAgICAgIHBhdGgsXG4gICAgICBzY2hlbWE6XG4gICAgICAgIC8vIEVudGl0eSB8fCBVbmlvblxuICAgICAgICAoc2NoZW1hIGFzIGFueSkucHJvY2VzcyB8fCAoc2NoZW1hIGFzIGFueSkuX2hvaXN0YWJsZSA/XG4gICAgICAgICAgbmV3IEludmFsaWRhdGUoc2NoZW1hIGFzIGFueSlcbiAgICAgICAgOiBzY2hlbWEsXG4gICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgbmFtZTogZ2V0TmFtZSgnZGVsZXRlJyksXG4gICAgICBwcm9jZXNzKHJlczogYW55LCBwYXJhbXM6IGFueSkge1xuICAgICAgICByZXR1cm4gcmVzICYmIE9iamVjdC5rZXlzKHJlcykubGVuZ3RoID8gcmVzIDogcGFyYW1zO1xuICAgICAgfSxcbiAgICAgIGdldE9wdGltaXN0aWNSZXNwb25zZTogb3B0aW1pc3RpYyA/IChvcHRpbWlzdGljRGVsZXRlIGFzIGFueSkgOiB1bmRlZmluZWQsXG4gICAgfSksXG4gICAgZXh0ZW5kKFxuICAgICAgLi4uYXJnczpcbiAgICAgICAgfCBbc3RyaW5nLCBSZXN0RW5kcG9pbnRPcHRpb25zICYgUGFydGlhbFJlc3RHZW5lcmljc11cbiAgICAgICAgfCBbUmVzdEVuZHBvaW50T3B0aW9ucyAmIFBhcnRpYWxSZXN0R2VuZXJpY3NdXG4gICAgICAgIHwgW1xuICAgICAgICAgICAgKFxuICAgICAgICAgICAgICBiYXNlUmVzb3VyY2U6IFJlc291cmNlSW50ZXJmYWNlLFxuICAgICAgICAgICAgKSA9PiBSZWNvcmQ8c3RyaW5nLCBSZXN0SW5zdGFuY2VCYXNlPixcbiAgICAgICAgICBdXG4gICAgKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnN0IFtrZXksIG9wdGlvbnNdID0gYXJncztcbiAgICAgICAgaWYgKGtleSBpbiB0aGlzKSB7XG4gICAgICAgICAgY29uc3QgZXh0ZW5kZWQgPSB7IC4uLnRoaXMgfTtcbiAgICAgICAgICBleHRlbmRNZW1iZXIoZXh0ZW5kZWQsIGtleSwgb3B0aW9ucyk7XG4gICAgICAgICAgcmV0dXJuIGV4dGVuZGVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi50aGlzLFxuICAgICAgICAgICAgW2tleV06IHRoaXMuZ2V0LmV4dGVuZChvcHRpb25zKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IGV4dGVuZGVkID0gYXJnc1swXSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi50aGlzLFxuICAgICAgICAgIC4uLmV4dGVuZGVkLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgY29uc3Qgb3ZlcnJpZGVzID0gYXJnc1swXTtcbiAgICAgIGNvbnN0IGV4dGVuZGVkID0geyAuLi50aGlzIH07XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBvdmVycmlkZXMpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGV4dGVuZE1lbWJlcihleHRlbmRlZCwga2V5LCBvdmVycmlkZXNba2V5XSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZXh0ZW5kZWQ7XG4gICAgfSxcbiAgfSBhcyBhbnk7XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIG9wdGltaXN0aWNVcGRhdGUoc25hcDogU25hcHNob3RJbnRlcmZhY2UsIHBhcmFtczogYW55LCBib2R5OiBhbnkpIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5wYXJhbXMsXG4gICAgLi4uZW5zdXJlUG9qbyhib2R5KSxcbiAgfTtcbn1cbmZ1bmN0aW9uIG9wdGltaXN0aWNQYXJ0aWFsKHNjaGVtYTogUXVlcnlhYmxlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoc25hcDogU25hcHNob3RJbnRlcmZhY2UsIHBhcmFtczogYW55LCBib2R5OiBhbnkpIHtcbiAgICBjb25zdCBkYXRhID0gc25hcC5nZXQoc2NoZW1hLCBwYXJhbXMpO1xuICAgIGlmICghZGF0YSkgdGhyb3cgc25hcC5hYm9ydDtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ucGFyYW1zLFxuICAgICAgLi4uZGF0YSxcbiAgICAgIC8vIGV2ZW4gdGhvIHdlIGRvbid0IGFsd2F5cyBoYXZlIHR3byBhcmd1bWVudHMsIHRoZSBleHRyYSBvbmUgd2lsbCBzaW1wbHkgYmUgdW5kZWZpbmVkIHdoaWNoIHNwcmVhZHMgZmluZVxuICAgICAgLi4uZW5zdXJlUG9qbyhib2R5KSxcbiAgICB9O1xuICB9O1xufVxuZnVuY3Rpb24gb3B0aW1pc3RpY0RlbGV0ZShzbmFwOiBTbmFwc2hvdEludGVyZmFjZSwgcGFyYW1zOiBhbnkpIHtcbiAgcmV0dXJuIHBhcmFtcztcbn1cbmZ1bmN0aW9uIGVuc3VyZVBvam8oYm9keTogYW55KSB7XG4gIHJldHVybiBib2R5IGluc3RhbmNlb2YgRm9ybURhdGEgP1xuICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKChib2R5IGFzIGFueSkuZW50cmllcygpKVxuICAgIDogYm9keTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsU0FBU0EsTUFBTSxRQUFRLHVCQUF1QjtBQVM5QyxPQUFPQyxZQUFZLE1BS1osbUJBQW1CO0FBQzFCLFNBQVNDLFdBQVcsUUFBUSxrQkFBa0I7QUFFOUMsTUFBTTtFQUFFQyxVQUFVO0VBQUVDLFVBQVUsRUFBRUM7QUFBZSxDQUFDLEdBQUdMLE1BQU07O0FBRXpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTTSxRQUFRQSxDQUFBQyxJQUFBLEVBU2U7RUFBQSxJQVRjO01BQzNEQyxJQUFJO01BQ0pSLE1BQU07TUFDTlMsUUFBUSxHQUFHUixZQUFZO01BQ3ZCRyxVQUFVLEdBQUdDLGNBQWM7TUFDM0JLLHFCQUFxQjtNQUNyQkMsVUFBVTtNQUNWQztJQUU2QixDQUFDLEdBQUFMLElBQUE7SUFEM0JNLFlBQVksR0FBQUMsNkJBQUEsQ0FBQVAsSUFBQSxFQUFBUSxTQUFBO0VBRWYsSUFBSUMsT0FBTyxDQUFDQyxHQUFHLENBQUNDLFFBQVEsS0FBSyxZQUFZLEVBQUU7SUFDekM7SUFDQSxJQUNFLFVBQVUsSUFBSUwsWUFBWSxJQUMxQkosUUFBUSxLQUFLUixZQUFZLElBQ3pCLE9BQU9ZLFlBQVksQ0FBQyxVQUFVLENBQUMsS0FBSyxVQUFVLElBQzlDQSxZQUFZLENBQUMsVUFBVSxDQUFDLElBQ3hCTSxNQUFNLENBQUNDLFNBQVMsQ0FBQ0MsYUFBYSxDQUFDQyxJQUFJLENBQ2pDckIsWUFBWSxDQUFDbUIsU0FBUyxFQUNyQlAsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFTTyxTQUNwQyxDQUFDLEVBQ0Q7TUFDQUcsT0FBTyxDQUFDQyxJQUFJLENBQ1Y7QUFDUjtBQUNBO0FBQ0E7QUFDQSwwQ0FDTSxDQUFDO0lBQ0g7SUFDQTtJQUNBLElBQ0UsWUFB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