@orbit/jsonapi
Version:
JSON:API support for Orbit.
256 lines • 37.2 kB
JavaScript
import { Orbit } from '@orbit/core';
import { QueryExpressionParseError } from '@orbit/data';
import { clone } from '@orbit/utils';
import { appendQueryParams } from './lib/query-params';
import { JSONAPISerializers } from './serializers/jsonapi-serializers';
const { deprecate } = Orbit;
export class JSONAPIURLBuilder {
constructor(settings) {
this.host = settings.host;
this.namespace = settings.namespace;
this.serializerFor = settings.serializerFor;
if (settings.serializer) {
this.serializer = settings.serializer;
deprecate("The 'serializer' setting for 'JSONAPIURLBuilder' has been deprecated. Pass 'serializerFor' instead.");
}
this.keyMap = settings.keyMap;
}
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
resourceNamespace(type) {
return this.namespace;
}
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
resourceHost(type) {
return this.host;
}
resourceURL(type, id) {
let host = this.resourceHost(type);
let namespace = this.resourceNamespace(type);
let url = [];
if (host) {
url.push(host);
}
if (namespace) {
url.push(namespace);
}
url.push(this.resourcePath(type, id));
if (!host) {
url.unshift('');
}
return url.join('/');
}
resourcePath(type, id) {
let resourceType, resourceId;
if (this.serializer) {
resourceType = this.serializer.resourceType(type);
if (id) {
resourceId = this.serializer.resourceId(type, id);
}
}
else {
const resourceTypeSerializer = this.serializerFor(JSONAPISerializers.ResourceTypePath);
resourceType = resourceTypeSerializer.serialize(type);
if (id) {
const resourceIdentitySerializer = this.serializerFor(JSONAPISerializers.ResourceIdentity);
const identity = resourceIdentitySerializer.serialize({
type,
id
});
resourceId = identity.id;
}
}
let path = [resourceType];
if (resourceId) {
path.push(resourceId);
}
return path.join('/');
}
resourceRelationshipURL(type, id, relationship) {
return [
this.resourceURL(type, id),
'relationships',
this.serializeRelationshipInPath(type, relationship)
].join('/');
}
relatedResourceURL(type, id, relationship) {
return [
this.resourceURL(type, id),
this.serializeRelationshipInPath(type, relationship)
].join('/');
}
buildFilterParam(filters,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
var _a, _b, _c;
const params = [];
if (Array.isArray(filters)) {
for (let filterSpecifier of filters) {
if (filterSpecifier.kind === 'attribute' &&
filterSpecifier.op === 'equal') {
const attributeFilter = filterSpecifier;
const field = this.serializeFieldParam(attributeFilter.attribute, {
kind: 'attribute'
});
params.push({
[field]: (_a = attributeFilter.value) !== null && _a !== void 0 ? _a : null
});
}
else if (filterSpecifier.kind === 'relatedRecord') {
const relatedRecordFilter = filterSpecifier;
if (relatedRecordFilter.op !== 'equal') {
throw new QueryExpressionParseError(`Filter operation '${relatedRecordFilter.op}' not recognized by JSONAPIURLBuilder#buildFilterParam for relatedRecord filtering. Override this method to provide a custom handler.`);
}
const field = this.serializeFieldParam(relatedRecordFilter.relation, {
kind: 'relationship'
});
if (Array.isArray(relatedRecordFilter.record)) {
params.push({
[field]: relatedRecordFilter.record
.map((e) => { var _a; return (_a = e === null || e === void 0 ? void 0 : e.id) !== null && _a !== void 0 ? _a : null; })
.join(',')
});
}
else {
params.push({
[field]: (_c = (_b = relatedRecordFilter === null || relatedRecordFilter === void 0 ? void 0 : relatedRecordFilter.record) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : null
});
}
}
else if (filterSpecifier.kind === 'relatedRecords') {
const relatedRecordsFilter = filterSpecifier;
if (relatedRecordsFilter.op !== 'equal') {
throw new QueryExpressionParseError(`Filter operation '${relatedRecordsFilter.op}' not recognized by JSONAPIURLBuilder#buildFilterParam for relatedRecords filtering. Override this method to provide a custom handler.`);
}
const field = this.serializeFieldParam(relatedRecordsFilter.relation, { kind: 'relationship' });
params.push({
[field]: relatedRecordsFilter.records
.map((e) => { var _a; return (_a = e === null || e === void 0 ? void 0 : e.id) !== null && _a !== void 0 ? _a : null; })
.join(',')
});
}
else {
throw new QueryExpressionParseError(`Filter operation '${filterSpecifier.op}' not recognized by JSONAPIURLBuilder#buildFilterParam. Override this method to provide a custom handler.`);
}
}
}
else {
for (let key in filters) {
const value = filters[key];
const fieldParam = this.serializeFieldParam(key);
if (Array.isArray(value)) {
for (let v of value) {
params.push({ [fieldParam]: v });
}
}
else {
params.push({ [fieldParam]: value });
}
}
}
return params;
}
buildSortParam(sortSpecifiers,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
if (Array.isArray(sortSpecifiers)) {
return sortSpecifiers
.map((sortSpecifier) => {
let descending;
let fieldName;
if (typeof sortSpecifier === 'string') {
descending = sortSpecifier.charAt(0) === '-';
fieldName = descending ? sortSpecifier.substring(1) : sortSpecifier;
}
else if (sortSpecifier.kind === 'attribute') {
const attributeSort = sortSpecifier;
descending = attributeSort.order === 'descending';
fieldName = attributeSort.attribute;
}
if (fieldName) {
const field = this.serializeFieldParam(fieldName, {
kind: 'attribute'
});
return `${descending ? '-' : ''}${field}`;
}
})
.join(',');
}
else if (typeof sortSpecifiers === 'string') {
return sortSpecifiers;
}
throw new QueryExpressionParseError(`Sort specifier not recognized for JSONAPISource.`);
}
buildPageParam(pageSpecifier,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
let pageParam = clone(pageSpecifier);
delete pageParam.kind;
return pageParam;
}
buildIncludeParam(includeSpecifier,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
if (Array.isArray(includeSpecifier)) {
return includeSpecifier
.map((s) => {
const paths = Array.isArray(s) ? s : s.split('.');
return paths
.map((p) => this.serializeFieldParam(p, { kind: 'relationship' }))
.join('.');
})
.join(',');
}
else {
return includeSpecifier;
}
}
buildFieldsParam(fieldsSpecifier,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
const params = {};
for (let type in fieldsSpecifier) {
const value = fieldsSpecifier[type];
const serializer = this.serializerFor(JSONAPISerializers.ResourceTypeParam);
const typeParam = serializer.serialize(type);
const fields = Array.isArray(value) ? value : value.split(',');
params[typeParam] = fields
.map((f) => this.serializeFieldParam(f))
.join(',');
}
return params;
}
appendQueryParams(url, params) {
let fullUrl = url;
if (params) {
fullUrl = appendQueryParams(fullUrl, params);
}
return fullUrl;
}
serializeFieldParam(field, options) {
if (this.serializer) {
if ((options === null || options === void 0 ? void 0 : options.kind) === 'attribute') {
return this.serializer.resourceAttribute(options === null || options === void 0 ? void 0 : options.type, field);
}
else if ((options === null || options === void 0 ? void 0 : options.kind) === 'relationship') {
return this.serializer.resourceRelationship(options === null || options === void 0 ? void 0 : options.type, field);
}
else {
return field;
}
}
else {
const serializer = this.serializerFor(JSONAPISerializers.ResourceFieldParam);
return serializer.serialize(field, { type: options === null || options === void 0 ? void 0 : options.type });
}
}
serializeRelationshipInPath(type, relationship) {
if (this.serializer) {
return this.serializer.resourceRelationship(type, relationship);
}
else {
const serializer = this.serializerFor(JSONAPISerializers.ResourceFieldPath);
return serializer.serialize(relationship, { type });
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbmFwaS11cmwtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9qc29uYXBpLXVybC1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDcEMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBV3hELE9BQU8sRUFBRSxLQUFLLEVBQVEsTUFBTSxjQUFjLENBQUM7QUFFM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFPdkUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLEtBQUssQ0FBQztBQVU1QixNQUFNLE9BQU8saUJBQWlCO0lBTzVCLFlBQVksUUFBbUM7UUFDN0MsSUFBSSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztRQUNwQyxJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUM7UUFDNUMsSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQztZQUN0QyxTQUFTLENBQ1AscUdBQXFHLENBQ3RHLENBQUM7U0FDSDtRQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLGlCQUFpQixDQUFDLElBQWE7UUFDN0IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsWUFBWSxDQUFDLElBQWE7UUFDeEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFRCxXQUFXLENB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WUFDcEMsT0FBTyxVQUFVLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxDQUFXLENBQUM7U0FDL0Q7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcmJpdCB9IGZyb20gJ0BvcmJpdC9jb3JlJztcbmltcG9ydCB7IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IgfSBmcm9tICdAb3JiaXQvZGF0YSc7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVGaWx0ZXJTcGVjaWZpZXIsXG4gIEF0dHJpYnV0ZVNvcnRTcGVjaWZpZXIsXG4gIEZpbHRlclNwZWNpZmllcixcbiAgUmVjb3JkS2V5TWFwLFxuICBQYWdlU3BlY2lmaWVyLFxuICBSZWxhdGVkUmVjb3JkRmlsdGVyU3BlY2lmaWVyLFxuICBSZWxhdGVkUmVjb3Jkc0ZpbHRlclNwZWNpZmllcixcbiAgU29ydFNwZWNpZmllclxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBjbG9uZSwgRGljdCB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBKU09OQVBJU2VyaWFsaXplciB9IGZyb20gJy4vanNvbmFwaS1zZXJpYWxpemVyJztcbmltcG9ydCB7IGFwcGVuZFF1ZXJ5UGFyYW1zIH0gZnJvbSAnLi9saWIvcXVlcnktcGFyYW1zJztcbmltcG9ydCB7IFNlcmlhbGl6ZXJGb3JGbiwgU3RyaW5nU2VyaWFsaXplciB9IGZyb20gJ0BvcmJpdC9zZXJpYWxpemVycyc7XG5pbXBvcnQgeyBKU09OQVBJU2VyaWFsaXplcnMgfSBmcm9tICcuL3NlcmlhbGl6ZXJzL2pzb25hcGktc2VyaWFsaXplcnMnO1xuaW1wb3J0IHsgUmVzb3VyY2VJZGVudGl0eSB9IGZyb20gJy4vcmVzb3VyY2UtZG9jdW1lbnQnO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlSWRlbnRpdHlTZXJpYWxpemVyIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWlkZW50aXR5LXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlRmllbGRTZXJpYWxpemVyIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWZpZWxkLXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgUmVjb3JkUXVlcnlSZXF1ZXN0IH0gZnJvbSAnLi9saWIvcXVlcnktcmVxdWVzdHMnO1xuaW1wb3J0IHsgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB9IGZyb20gJy4vbGliL3RyYW5zZm9ybS1yZXF1ZXN0cyc7XG5cbmNvbnN0IHsgZGVwcmVjYXRlIH0gPSBPcmJpdDtcblxuZXhwb3J0IGludGVyZmFjZSBKU09OQVBJVVJMQnVpbGRlclNldHRpbmdzIHtcbiAgaG9zdD86IHN0cmluZztcbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xuICBzZXJpYWxpemVyPzogSlNPTkFQSVNlcmlhbGl6ZXI7XG4gIHNlcmlhbGl6ZXJGb3I6IFNlcmlhbGl6ZXJGb3JGbjtcbiAga2V5TWFwPzogUmVjb3JkS2V5TWFwO1xufVxuXG5leHBvcnQgY2xhc3MgSlNPTkFQSVVSTEJ1aWxkZXIge1xuICBob3N0Pzogc3RyaW5nO1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gIHNlcmlhbGl6ZXJGb3I6IFNlcmlhbGl6ZXJGb3JGbjtcbiAgc2VyaWFsaXplcj86IEpTT05BUElTZXJpYWxpemVyO1xuICBrZXlNYXA/OiBSZWNvcmRLZXlNYXA7XG5cbiAgY29uc3RydWN0b3Ioc2V0dGluZ3M6IEpTT05BUElVUkxCdWlsZGVyU2V0dGluZ3MpIHtcbiAgICB0aGlzLmhvc3QgPSBzZXR0aW5ncy5ob3N0O1xuICAgIHRoaXMubmFtZXNwYWNlID0gc2V0dGluZ3MubmFtZXNwYWNlO1xuICAgIHRoaXMuc2VyaWFsaXplckZvciA9IHNldHRpbmdzLnNlcmlhbGl6ZXJGb3I7XG4gICAgaWYgKHNldHRpbmdzLnNlcmlhbGl6ZXIpIHtcbiAgICAgIHRoaXMuc2VyaWFsaXplciA9IHNldHRpbmdzLnNlcmlhbGl6ZXI7XG4gICAgICBkZXByZWNhdGUoXG4gICAgICAgIFwiVGhlICdzZXJpYWxpemVyJyBzZXR0aW5nIGZvciAnSlNPTkFQSVVSTEJ1aWxkZXInIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBhc3MgJ3NlcmlhbGl6ZXJGb3InIGluc3RlYWQuXCJcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMua2V5TWFwID0gc2V0dGluZ3Mua2V5TWFwO1xuICB9XG5cbiAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuICByZXNvdXJjZU5hbWVzcGFjZSh0eXBlPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5uYW1lc3BhY2U7XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXG4gIHJlc291cmNlSG9zdCh0eXBlPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5ob3N0O1xuICB9XG5cbiAgcmVzb3VyY2VVUkwodHlwZTogc3RyaW5nLCBpZD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IGhvc3QgPSB0aGlzLnJlc291cmNlSG9zdCh0eXBlKTtcbiAgICBsZXQgbmFtZXNwYWNlID0gdGhpcy5yZXNvdXJjZU5hbWVzcGFjZSh0eXBlKTtcbiAgICBsZXQgdXJsOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIHVybC5wdXNoKGhvc3QpO1xuICAgIH1cbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICB1cmwucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cbiAgICB1cmwucHVzaCh0aGlzLnJlc291cmNlUGF0aCh0eXBlLCBpZCkpO1xuXG4gICAgaWYgKCFob3N0KSB7XG4gICAgICB1cmwudW5zaGlmdCgnJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybC5qb2luKCcvJyk7XG4gIH1cblxuICByZXNvdXJjZVBhdGgodHlwZTogc3RyaW5nLCBpZD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHJlc291cmNlVHlwZSwgcmVzb3VyY2VJZDtcbiAgICBpZiAodGhpcy5zZXJpYWxpemVyKSB7XG4gICAgICByZXNvdXJjZVR5cGUgPSB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VUeXBlKHR5cGUpO1xuICAgICAgaWYgKGlkKSB7XG4gICAgICAgIHJlc291cmNlSWQgPSB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VJZCh0eXBlLCBpZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlc291cmNlVHlwZVNlcmlhbGl6ZXIgPSB0aGlzLnNlcmlhbGl6ZXJGb3IoXG4gICAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZVR5cGVQYXRoXG4gICAgICApIGFzIFN0cmluZ1NlcmlhbGl6ZXI7XG4gICAgICByZXNvdXJjZVR5cGUgPSByZXNvdXJjZVR5cGVTZXJpYWxpemVyLnNlcmlhbGl6ZSh0eXBlKTtcbiAgICAgIGlmIChpZCkge1xuICAgICAgICBjb25zdCByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplciA9IHRoaXMuc2VyaWFsaXplckZvcihcbiAgICAgICAgICBKU09OQVBJU2VyaWFsaXplcnMuUmVzb3VyY2VJZGVudGl0eVxuICAgICAgICApIGFzIEpTT05BUElSZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplcjtcbiAgICAgICAgY29uc3QgaWRlbnRpdHkgPSByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplci5zZXJpYWxpemUoe1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgaWRcbiAgICAgICAgfSkgYXMgUmVzb3VyY2VJZGVudGl0eTtcbiAgICAgICAgcmVzb3VyY2VJZCA9IGlkZW50aXR5LmlkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBwYXRoID0gW3Jlc291cmNlVHlwZV07XG4gICAgaWYgKHJlc291cmNlSWQpIHtcbiAgICAgIHBhdGgucHVzaChyZXNvdXJjZUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGguam9pbignLycpO1xuICB9XG5cbiAgcmVzb3VyY2VSZWxhdGlvbnNoaXBVUkwoXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmdcbiAgKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5yZXNvdXJjZVVSTCh0eXBlLCBpZCksXG4gICAgICAncmVsYXRpb25zaGlwcycsXG4gICAgICB0aGlzLnNlcmlhbGl6ZVJlbGF0aW9uc2hpcEluUGF0aCh0eXBlLCByZWxhdGlvbnNoaXApXG4gICAgXS5qb2luKCcvJyk7XG4gIH1cblxuICByZWxhdGVkUmVzb3VyY2VVUkwodHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCByZWxhdGlvbnNoaXA6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMucmVzb3VyY2VVUkwodHlwZSwgaWQpLFxuICAgICAgdGhpcy5zZXJpYWxpemVSZWxhdGlvbnNoaXBJblBhdGgodHlwZSwgcmVsYXRpb25zaGlwKVxuICAgIF0uam9pbignLycpO1xuICB9XG5cbiAgYnVpbGRGaWx0ZXJQYXJhbShcbiAgICBmaWx0ZXJzOiBGaWx0ZXJTcGVjaWZpZXJbXSB8IERpY3Q8dW5rbm93biB8IHVua25vd25bXT4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHJlcXVlc3Q/OiBSZWNvcmRRdWVyeVJlcXVlc3QgfCBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IERpY3Q8dW5rbm93bj5bXSB7XG4gICAgY29uc3QgcGFyYW1zOiBEaWN0PHVua25vd24+W10gPSBbXTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGZpbHRlcnMpKSB7XG4gICAgICBmb3IgKGxldCBmaWx0ZXJTcGVjaWZpZXIgb2YgZmlsdGVycykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmlsdGVyU3BlY2lmaWVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnICYmXG4gICAgICAgICAgZmlsdGVyU3BlY2lmaWVyLm9wID09PSAnZXF1YWwnXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZUZpbHRlciA9IGZpbHRlclNwZWNpZmllciBhcyBBdHRyaWJ1dGVGaWx0ZXJTcGVjaWZpZXI7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnNlcmlhbGl6ZUZpZWxkUGFyYW0oYXR0cmlidXRlRmlsdGVyLmF0dHJpYnV0ZSwge1xuICAgICAgICAgICAga2luZDogJ2F0dHJpYnV0ZSdcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJhbXMucHVzaCh7XG4gICAgICAgICAgICBbZmllbGRdOiBhdHRyaWJ1dGVGaWx0ZXIudmFsdWUgPz8gbnVsbFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbHRlclNwZWNpZmllci5raW5kID09PSAncmVsYXRlZFJlY29yZCcpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkUmVjb3JkRmlsdGVyID0gZmlsdGVyU3BlY2lmaWVyIGFzIFJlbGF0ZWRSZWNvcmRGaWx0ZXJTcGVjaWZpZXI7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRSZWNvcmRGaWx0ZXIub3AgIT09ICdlcXVhbCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgICBgRmlsdGVyIG9wZXJhdGlvbiAnJHtyZWxhdGVkUmVjb3JkRmlsdGVyLm9wfScgbm90IHJlY29nbml6ZWQgYnkgSlNPTkFQSVVSTEJ1aWxkZXIjYnVpbGRGaWx0ZXJQYXJhbSBmb3IgcmVsYXRlZFJlY29yZCBmaWx0ZXJpbmcuIE92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUgYSBjdXN0b20gaGFuZGxlci5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShyZWxhdGVkUmVjb3JkRmlsdGVyLnJlbGF0aW9uLCB7XG4gICAgICAgICAgICBraW5kOiAncmVsYXRpb25zaGlwJ1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlbGF0ZWRSZWNvcmRGaWx0ZXIucmVjb3JkKSkge1xuICAgICAgICAgICAgcGFyYW1zLnB1c2goe1xuICAgICAgICAgICAgICBbZmllbGRdOiByZWxhdGVkUmVjb3JkRmlsdGVyLnJlY29yZFxuICAgICAgICAgICAgICAgIC5tYXAoKGUpID0+IGU/LmlkID8/IG51bGwpXG4gICAgICAgICAgICAgICAgLmpvaW4oJywnKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcmFtcy5wdXNoKHtcbiAgICAgICAgICAgICAgW2ZpZWxkXTogcmVsYXRlZFJlY29yZEZpbHRlcj8ucmVjb3JkPy5pZCA/PyBudWxsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmlsdGVyU3BlY2lmaWVyLmtpbmQgPT09ICdyZWxhdGVkUmVjb3JkcycpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkUmVjb3Jkc0ZpbHRlciA9IGZpbHRlclNwZWNpZmllciBhcyBSZWxhdGVkUmVjb3Jkc0ZpbHRlclNwZWNpZmllcjtcbiAgICAgICAgICBpZiAocmVsYXRlZFJlY29yZHNGaWx0ZXIub3AgIT09ICdlcXVhbCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgICBgRmlsdGVyIG9wZXJhdGlvbiAnJHtyZWxhdGVkUmVjb3Jkc0ZpbHRlci5vcH0nIG5vdCByZWNvZ25pemVkIGJ5IEpTT05BUElVUkxCdWlsZGVyI2J1aWxkRmlsdGVyUGFyYW0gZm9yIHJlbGF0ZWRSZWNvcmRzIGZpbHRlcmluZy4gT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZSBhIGN1c3RvbSBoYW5kbGVyLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpZWxkID0gdGhpcy5zZXJpYWxpemVGaWVsZFBhcmFtKFxuICAgICAgICAgICAgcmVsYXRlZFJlY29yZHNGaWx0ZXIucmVsYXRpb24sXG4gICAgICAgICAgICB7IGtpbmQ6ICdyZWxhdGlvbnNoaXAnIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHBhcmFtcy5wdXNoKHtcbiAgICAgICAgICAgIFtmaWVsZF06IHJlbGF0ZWRSZWNvcmRzRmlsdGVyLnJlY29yZHNcbiAgICAgICAgICAgICAgLm1hcCgoZSkgPT4gZT8uaWQgPz8gbnVsbClcbiAgICAgICAgICAgICAgLmpvaW4oJywnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgYEZpbHRlciBvcGVyYXRpb24gJyR7ZmlsdGVyU3BlY2lmaWVyLm9wfScgbm90IHJlY29nbml6ZWQgYnkgSlNPTkFQSVVSTEJ1aWxkZXIjYnVpbGRGaWx0ZXJQYXJhbS4gT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZSBhIGN1c3RvbSBoYW5kbGVyLmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGtleSBpbiBmaWx0ZXJzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZmlsdGVyc1trZXldO1xuICAgICAgICBjb25zdCBmaWVsZFBhcmFtID0gdGhpcy5zZXJpYWxpemVGaWVsZFBhcmFtKGtleSk7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgZm9yIChsZXQgdiBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgcGFyYW1zLnB1c2goeyBbZmllbGRQYXJhbV06IHYgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcmFtcy5wdXNoKHsgW2ZpZWxkUGFyYW1dOiB2YWx1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICBidWlsZFNvcnRQYXJhbShcbiAgICBzb3J0U3BlY2lmaWVyczogKFNvcnRTcGVjaWZpZXIgfCBzdHJpbmcpW10gfCBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHJlcXVlc3Q/OiBSZWNvcmRRdWVyeVJlcXVlc3QgfCBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IHN0cmluZyB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydFNwZWNpZmllcnMpKSB7XG4gICAgICByZXR1cm4gc29ydFNwZWNpZmllcnNcbiAgICAgICAgLm1hcCgoc29ydFNwZWNpZmllcikgPT4ge1xuICAgICAgICAgIGxldCBkZXNjZW5kaW5nO1xuICAgICAgICAgIGxldCBmaWVsZE5hbWU7XG4gICAgICAgICAgaWYgKHR5cGVvZiBzb3J0U3BlY2lmaWVyID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZGVzY2VuZGluZyA9IHNvcnRTcGVjaWZpZXIuY2hhckF0KDApID09PSAnLSc7XG4gICAgICAgICAgICBmaWVsZE5hbWUgPSBkZXNjZW5kaW5nID8gc29ydFNwZWNpZmllci5zdWJzdHJpbmcoMSkgOiBzb3J0U3BlY2lmaWVyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc29ydFNwZWNpZmllci5raW5kID09PSAnYXR0cmlidXRlJykge1xuICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlU29ydCA9IHNvcnRTcGVjaWZpZXIgYXMgQXR0cmlidXRlU29ydFNwZWNpZmllcjtcbiAgICAgICAgICAgIGRlc2NlbmRpbmcgPSBhdHRyaWJ1dGVTb3J0Lm9yZGVyID09PSAnZGVzY2VuZGluZyc7XG4gICAgICAgICAgICBmaWVsZE5hbWUgPSBhdHRyaWJ1dGVTb3J0LmF0dHJpYnV0ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZmllbGROYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShmaWVsZE5hbWUsIHtcbiAgICAgICAgICAgICAga2luZDogJ2F0dHJpYnV0ZSdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGAke2Rlc2NlbmRpbmcgPyAnLScgOiAnJ30ke2ZpZWxkfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuam9pbignLCcpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNvcnRTcGVjaWZpZXJzID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNvcnRTcGVjaWZpZXJzO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgYFNvcnQgc3BlY2lmaWVyIG5vdCByZWNvZ25pemVkIGZvciBKU09OQVBJU291cmNlLmBcbiAgICApO1xuICB9XG5cbiAgYnVpbGRQYWdlUGFyYW0oXG4gICAgcGFnZVNwZWNpZmllcjogUGFnZVNwZWNpZmllcixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgcmVxdWVzdD86IFJlY29yZFF1ZXJ5UmVxdWVzdCB8IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogRGljdDx1bmtub3duPiB7XG4gICAgbGV0IHBhZ2VQYXJhbSA9IGNsb25lKHBhZ2VTcGVjaWZpZXIpO1xuICAgIGRlbGV0ZSBwYWdlUGFyYW0ua2luZDtcbiAgICByZXR1cm4gcGFnZVBhcmFtO1xuICB9XG5cbiAgYnVpbGRJbmNsdWRlUGFyYW0oXG4gICAgaW5jbHVkZVNwZWNpZmllcjogc3RyaW5nIHwgc3RyaW5nW10gfCBzdHJpbmdbXVtdLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICByZXF1ZXN0PzogUmVjb3JkUXVlcnlSZXF1ZXN0IHwgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFxuICApOiBzdHJpbmcge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGluY2x1ZGVTcGVjaWZpZXIpKSB7XG4gICAgICByZXR1cm4gaW5jbHVkZVNwZWNpZmllclxuICAgICAgICAubWFwKChzKSA9PiB7XG4gICAgICAgICAgY29uc3QgcGF0aHMgPSBBcnJheS5pc0FycmF5KHMpID8gcyA6IHMuc3BsaXQoJy4nKTtcbiAgICAgICAgICByZXR1cm4gcGF0aHNcbiAgICAgICAgICAgIC5tYXAoKHApID0+IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShwLCB7IGtpbmQ6ICdyZWxhdGlvbnNoaXAnIH0pKVxuICAgICAgICAgICAgLmpvaW4oJy4nKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJywnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGluY2x1ZGVTcGVjaWZpZXI7XG4gICAgfVxuICB9XG5cbiAgYnVpbGRGaWVsZHNQYXJhbShcbiAgICBmaWVsZHNTcGVjaWZpZXI6IERpY3Q8c3RyaW5nIHwgc3RyaW5nW10+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICByZXF1ZXN0PzogUmVjb3JkUXVlcnlSZXF1ZXN0IHwgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFxuICApOiBEaWN0PHN0cmluZz4ge1xuICAgIGNvbnN0IHBhcmFtczogRGljdDxzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCB0eXBlIGluIGZpZWxkc1NwZWNpZmllcikge1xuICAgICAgY29uc3QgdmFsdWUgPSBmaWVsZHNTcGVjaWZpZXJbdHlwZV07XG5cbiAgICAgIGNvbnN0IHNlcmlhbGl6ZXIgPSB0aGlzLnNlcmlhbGl6ZXJGb3IoXG4gICAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZVR5cGVQYXJhbVxuICAgICAgKSBhcyBTdHJpbmdTZXJpYWxpemVyO1xuICAgICAgY29uc3QgdHlwZVBhcmFtID0gc2VyaWFsaXplci5zZXJpYWxpemUodHlwZSk7XG5cbiAgICAgIGNvbnN0IGZpZWxkcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiB2YWx1ZS5zcGxpdCgnLCcpO1xuICAgICAgcGFyYW1zW3R5cGVQYXJhbV0gPSBmaWVsZHNcbiAgICAgICAgLm1hcCgoZjogc3RyaW5nKSA9PiB0aGlzLnNlcmlhbGl6ZUZpZWxkUGFyYW0oZikpXG4gICAgICAgIC5qb2luKCcsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcmFtcztcbiAgfVxuXG4gIGFwcGVuZFF1ZXJ5UGFyYW1zKHVybDogc3RyaW5nLCBwYXJhbXM6IERpY3Q8c3RyaW5nPik6IHN0cmluZyB7XG4gICAgbGV0IGZ1bGxVcmwgPSB1cmw7XG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgZnVsbFVybCA9IGFwcGVuZFF1ZXJ5UGFyYW1zKGZ1bGxVcmwsIHBhcmFtcyk7XG4gICAgfVxuICAgIHJldHVybiBmdWxsVXJsO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNlcmlhbGl6ZUZpZWxkUGFyYW0oXG4gICAgZmllbGQ6IHN0cmluZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgdHlwZT86IHN0cmluZztcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBraW5kIHBhcmFtIHdoZW4gZGVwcmVjYXRlZCBzZXJpYWxpemVyIGlzIHJlbW92ZWRcbiAgICAgIGtpbmQ/OiAnYXR0cmlidXRlJyB8ICdyZWxhdGlvbnNoaXAnO1xuICAgIH1cbiAgKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5zZXJpYWxpemVyKSB7XG4gICAgICBpZiAob3B0aW9ucz8ua2luZCA9PT0gJ2F0dHJpYnV0ZScpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VyaWFsaXplci5yZXNvdXJjZUF0dHJpYnV0ZShvcHRpb25zPy50eXBlLCBmaWVsZCk7XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnM/LmtpbmQgPT09ICdyZWxhdGlvbnNoaXAnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VSZWxhdGlvbnNoaXAob3B0aW9ucz8udHlwZSwgZmllbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVyID0gdGhpcy5zZXJpYWxpemVyRm9yKFxuICAgICAgICBKU09OQVBJU2VyaWFsaXplcnMuUmVzb3VyY2VGaWVsZFBhcmFtXG4gICAgICApIGFzIEpTT05BUElSZXNvdXJjZUZpZWxkU2VyaWFsaXplcjtcbiAgICAgIHJldHVybiBzZXJpYWxpemVyLnNlcmlhbGl6ZShmaWVsZCwgeyB0eXBlOiBvcHRpb25zPy50eXBlIH0pIGFzIHN0cmluZztcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VyaWFsaXplUmVsYXRpb25zaGlwSW5QYXRoKFxuICAgIHR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZ1xuICApOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnNlcmlhbGl6ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VSZWxhdGlvbnNoaXAodHlwZSwgcmVsYXRpb25zaGlwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc2VyaWFsaXplciA9IHRoaXMuc2VyaWFsaXplckZvcihcbiAgICAgICAgSlNPTkFQSVNlcmlhbGl6ZXJzLlJlc291cmNlRmllbGRQYXRoXG4gICAgICApIGFzIEpTT05BUElSZXNvdXJjZUZpZWxkU2VyaWFsaXplcjtcbiAgICAgIHJldHVybiBzZXJpYWxpemVyLnNlcmlhbGl6ZShyZWxhdGlvbnNoaXAsIHsgdHlwZSB9KSBhcyBzdHJpbmc7XG4gICAgfVxuICB9XG59XG4iXX0=