@orbit/jsonapi
Version:
JSON:API support for Orbit.
260 lines • 37.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONAPIURLBuilder = void 0;
const core_1 = require("@orbit/core");
const data_1 = require("@orbit/data");
const utils_1 = require("@orbit/utils");
const query_params_1 = require("./lib/query-params");
const jsonapi_serializers_1 = require("./serializers/jsonapi-serializers");
const { deprecate } = core_1.Orbit;
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(jsonapi_serializers_1.JSONAPISerializers.ResourceTypePath);
resourceType = resourceTypeSerializer.serialize(type);
if (id) {
const resourceIdentitySerializer = this.serializerFor(jsonapi_serializers_1.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 data_1.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 data_1.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 data_1.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 data_1.QueryExpressionParseError(`Sort specifier not recognized for JSONAPISource.`);
}
buildPageParam(pageSpecifier,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
request) {
let pageParam = (0, utils_1.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(jsonapi_serializers_1.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 = (0, query_params_1.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(jsonapi_serializers_1.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(jsonapi_serializers_1.JSONAPISerializers.ResourceFieldPath);
return serializer.serialize(relationship, { type });
}
}
}
exports.JSONAPIURLBuilder = JSONAPIURLBuilder;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbmFwaS11cmwtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9qc29uYXBpLXVybC1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNDQUFvQztBQUNwQyxzQ0FBd0Q7QUFXeEQsd0NBQTJDO0FBRTNDLHFEQUF1RDtBQUV2RCwyRUFBdUU7QUFPdkUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLFlBQUssQ0FBQztBQVU1QixNQUFhLGlCQUFpQjtJQU81QixZQUFZLFFBQW1DO1FBQzdDLElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDcEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDO1FBQzVDLElBQUksUUFBUSxDQUFDLFVBQVUsRUFBRTtZQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUM7WUFDdEMsU0FBUyxDQUNQLHFHQUFxRyxDQUN0RyxDQUFDO1NBQ0g7UUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDaEMsQ0FBQztJQUVELGdFQUFnRTtJQUNoRSxpQkFBaUIsQ0FBQyxJQUFhO1FBQzdCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLFlBQVksQ0FBQyxJQUFhO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRUQsV0FBVyxDQUFDLElBQVksRUFBRSxFQUFXO1FBQ25DLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLElBQUksR0FBRyxHQUFh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J0BvcmJpdC9jb3JlJztcbmltcG9ydCB7IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IgfSBmcm9tICdAb3JiaXQvZGF0YSc7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVGaWx0ZXJTcGVjaWZpZXIsXG4gIEF0dHJpYnV0ZVNvcnRTcGVjaWZpZXIsXG4gIEZpbHRlclNwZWNpZmllcixcbiAgUmVjb3JkS2V5TWFwLFxuICBQYWdlU3BlY2lmaWVyLFxuICBSZWxhdGVkUmVjb3JkRmlsdGVyU3BlY2lmaWVyLFxuICBSZWxhdGVkUmVjb3Jkc0ZpbHRlclNwZWNpZmllcixcbiAgU29ydFNwZWNpZmllclxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBjbG9uZSwgRGljdCB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBKU09OQVBJU2VyaWFsaXplciB9IGZyb20gJy4vanNvbmFwaS1zZXJpYWxpemVyJztcbmltcG9ydCB7IGFwcGVuZFF1ZXJ5UGFyYW1zIH0gZnJvbSAnLi9saWIvcXVlcnktcGFyYW1zJztcbmltcG9ydCB7IFNlcmlhbGl6ZXJGb3JGbiwgU3RyaW5nU2VyaWFsaXplciB9IGZyb20gJ0BvcmJpdC9zZXJpYWxpemVycyc7XG5pbXBvcnQgeyBKU09OQVBJU2VyaWFsaXplcnMgfSBmcm9tICcuL3NlcmlhbGl6ZXJzL2pzb25hcGktc2VyaWFsaXplcnMnO1xuaW1wb3J0IHsgUmVzb3VyY2VJZGVudGl0eSB9IGZyb20gJy4vcmVzb3VyY2UtZG9jdW1lbnQnO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlSWRlbnRpdHlTZXJpYWxpemVyIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWlkZW50aXR5LXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlRmllbGRTZXJpYWxpemVyIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWZpZWxkLXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgUmVjb3JkUXVlcnlSZXF1ZXN0IH0gZnJvbSAnLi9saWIvcXVlcnktcmVxdWVzdHMnO1xuaW1wb3J0IHsgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB9IGZyb20gJy4vbGliL3RyYW5zZm9ybS1yZXF1ZXN0cyc7XG5cbmNvbnN0IHsgZGVwcmVjYXRlIH0gPSBPcmJpdDtcblxuZXhwb3J0IGludGVyZmFjZSBKU09OQVBJVVJMQnVpbGRlclNldHRpbmdzIHtcbiAgaG9zdD86IHN0cmluZztcbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xuICBzZXJpYWxpemVyPzogSlNPTkFQSVNlcmlhbGl6ZXI7XG4gIHNlcmlhbGl6ZXJGb3I6IFNlcmlhbGl6ZXJGb3JGbjtcbiAga2V5TWFwPzogUmVjb3JkS2V5TWFwO1xufVxuXG5leHBvcnQgY2xhc3MgSlNPTkFQSVVSTEJ1aWxkZXIge1xuICBob3N0Pzogc3RyaW5nO1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gIHNlcmlhbGl6ZXJGb3I6IFNlcmlhbGl6ZXJGb3JGbjtcbiAgc2VyaWFsaXplcj86IEpTT05BUElTZXJpYWxpemVyO1xuICBrZXlNYXA/OiBSZWNvcmRLZXlNYXA7XG5cbiAgY29uc3RydWN0b3Ioc2V0dGluZ3M6IEpTT05BUElVUkxCdWlsZGVyU2V0dGluZ3MpIHtcbiAgICB0aGlzLmhvc3QgPSBzZXR0aW5ncy5ob3N0O1xuICAgIHRoaXMubmFtZXNwYWNlID0gc2V0dGluZ3MubmFtZXNwYWNlO1xuICAgIHRoaXMuc2VyaWFsaXplckZvciA9IHNldHRpbmdzLnNlcmlhbGl6ZXJGb3I7XG4gICAgaWYgKHNldHRpbmdzLnNlcmlhbGl6ZXIpIHtcbiAgICAgIHRoaXMuc2VyaWFsaXplciA9IHNldHRpbmdzLnNlcmlhbGl6ZXI7XG4gICAgICBkZXByZWNhdGUoXG4gICAgICAgIFwiVGhlICdzZXJpYWxpemVyJyBzZXR0aW5nIGZvciAnSlNPTkFQSVVSTEJ1aWxkZXInIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBhc3MgJ3NlcmlhbGl6ZXJGb3InIGluc3RlYWQuXCJcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMua2V5TWFwID0gc2V0dGluZ3Mua2V5TWFwO1xuICB9XG5cbiAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuICByZXNvdXJjZU5hbWVzcGFjZSh0eXBlPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5uYW1lc3BhY2U7XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXG4gIHJlc291cmNlSG9zdCh0eXBlPzogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5ob3N0O1xuICB9XG5cbiAgcmVzb3VyY2VVUkwodHlwZTogc3RyaW5nLCBpZD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IGhvc3QgPSB0aGlzLnJlc291cmNlSG9zdCh0eXBlKTtcbiAgICBsZXQgbmFtZXNwYWNlID0gdGhpcy5yZXNvdXJjZU5hbWVzcGFjZSh0eXBlKTtcbiAgICBsZXQgdXJsOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIHVybC5wdXNoKGhvc3QpO1xuICAgIH1cbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICB1cmwucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cbiAgICB1cmwucHVzaCh0aGlzLnJlc291cmNlUGF0aCh0eXBlLCBpZCkpO1xuXG4gICAgaWYgKCFob3N0KSB7XG4gICAgICB1cmwudW5zaGlmdCgnJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybC5qb2luKCcvJyk7XG4gIH1cblxuICByZXNvdXJjZVBhdGgodHlwZTogc3RyaW5nLCBpZD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHJlc291cmNlVHlwZSwgcmVzb3VyY2VJZDtcbiAgICBpZiAodGhpcy5zZXJpYWxpemVyKSB7XG4gICAgICByZXNvdXJjZVR5cGUgPSB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VUeXBlKHR5cGUpO1xuICAgICAgaWYgKGlkKSB7XG4gICAgICAgIHJlc291cmNlSWQgPSB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VJZCh0eXBlLCBpZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlc291cmNlVHlwZVNlcmlhbGl6ZXIgPSB0aGlzLnNlcmlhbGl6ZXJGb3IoXG4gICAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZVR5cGVQYXRoXG4gICAgICApIGFzIFN0cmluZ1NlcmlhbGl6ZXI7XG4gICAgICByZXNvdXJjZVR5cGUgPSByZXNvdXJjZVR5cGVTZXJpYWxpemVyLnNlcmlhbGl6ZSh0eXBlKTtcbiAgICAgIGlmIChpZCkge1xuICAgICAgICBjb25zdCByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplciA9IHRoaXMuc2VyaWFsaXplckZvcihcbiAgICAgICAgICBKU09OQVBJU2VyaWFsaXplcnMuUmVzb3VyY2VJZGVudGl0eVxuICAgICAgICApIGFzIEpTT05BUElSZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplcjtcbiAgICAgICAgY29uc3QgaWRlbnRpdHkgPSByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplci5zZXJpYWxpemUoe1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgaWRcbiAgICAgICAgfSkgYXMgUmVzb3VyY2VJZGVudGl0eTtcbiAgICAgICAgcmVzb3VyY2VJZCA9IGlkZW50aXR5LmlkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBwYXRoID0gW3Jlc291cmNlVHlwZV07XG4gICAgaWYgKHJlc291cmNlSWQpIHtcbiAgICAgIHBhdGgucHVzaChyZXNvdXJjZUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGguam9pbignLycpO1xuICB9XG5cbiAgcmVzb3VyY2VSZWxhdGlvbnNoaXBVUkwoXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmdcbiAgKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5yZXNvdXJjZVVSTCh0eXBlLCBpZCksXG4gICAgICAncmVsYXRpb25zaGlwcycsXG4gICAgICB0aGlzLnNlcmlhbGl6ZVJlbGF0aW9uc2hpcEluUGF0aCh0eXBlLCByZWxhdGlvbnNoaXApXG4gICAgXS5qb2luKCcvJyk7XG4gIH1cblxuICByZWxhdGVkUmVzb3VyY2VVUkwodHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCByZWxhdGlvbnNoaXA6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMucmVzb3VyY2VVUkwodHlwZSwgaWQpLFxuICAgICAgdGhpcy5zZXJpYWxpemVSZWxhdGlvbnNoaXBJblBhdGgodHlwZSwgcmVsYXRpb25zaGlwKVxuICAgIF0uam9pbignLycpO1xuICB9XG5cbiAgYnVpbGRGaWx0ZXJQYXJhbShcbiAgICBmaWx0ZXJzOiBGaWx0ZXJTcGVjaWZpZXJbXSB8IERpY3Q8dW5rbm93biB8IHVua25vd25bXT4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHJlcXVlc3Q/OiBSZWNvcmRRdWVyeVJlcXVlc3QgfCBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IERpY3Q8dW5rbm93bj5bXSB7XG4gICAgY29uc3QgcGFyYW1zOiBEaWN0PHVua25vd24+W10gPSBbXTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGZpbHRlcnMpKSB7XG4gICAgICBmb3IgKGxldCBmaWx0ZXJTcGVjaWZpZXIgb2YgZmlsdGVycykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmlsdGVyU3BlY2lmaWVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnICYmXG4gICAgICAgICAgZmlsdGVyU3BlY2lmaWVyLm9wID09PSAnZXF1YWwnXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZUZpbHRlciA9IGZpbHRlclNwZWNpZmllciBhcyBBdHRyaWJ1dGVGaWx0ZXJTcGVjaWZpZXI7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnNlcmlhbGl6ZUZpZWxkUGFyYW0oYXR0cmlidXRlRmlsdGVyLmF0dHJpYnV0ZSwge1xuICAgICAgICAgICAga2luZDogJ2F0dHJpYnV0ZSdcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJhbXMucHVzaCh7XG4gICAgICAgICAgICBbZmllbGRdOiBhdHRyaWJ1dGVGaWx0ZXIudmFsdWUgPz8gbnVsbFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbHRlclNwZWNpZmllci5raW5kID09PSAncmVsYXRlZFJlY29yZCcpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkUmVjb3JkRmlsdGVyID0gZmlsdGVyU3BlY2lmaWVyIGFzIFJlbGF0ZWRSZWNvcmRGaWx0ZXJTcGVjaWZpZXI7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRSZWNvcmRGaWx0ZXIub3AgIT09ICdlcXVhbCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgICBgRmlsdGVyIG9wZXJhdGlvbiAnJHtyZWxhdGVkUmVjb3JkRmlsdGVyLm9wfScgbm90IHJlY29nbml6ZWQgYnkgSlNPTkFQSVVSTEJ1aWxkZXIjYnVpbGRGaWx0ZXJQYXJhbSBmb3IgcmVsYXRlZFJlY29yZCBmaWx0ZXJpbmcuIE92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUgYSBjdXN0b20gaGFuZGxlci5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShyZWxhdGVkUmVjb3JkRmlsdGVyLnJlbGF0aW9uLCB7XG4gICAgICAgICAgICBraW5kOiAncmVsYXRpb25zaGlwJ1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlbGF0ZWRSZWNvcmRGaWx0ZXIucmVjb3JkKSkge1xuICAgICAgICAgICAgcGFyYW1zLnB1c2goe1xuICAgICAgICAgICAgICBbZmllbGRdOiByZWxhdGVkUmVjb3JkRmlsdGVyLnJlY29yZFxuICAgICAgICAgICAgICAgIC5tYXAoKGUpID0+IGU/LmlkID8/IG51bGwpXG4gICAgICAgICAgICAgICAgLmpvaW4oJywnKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcmFtcy5wdXNoKHtcbiAgICAgICAgICAgICAgW2ZpZWxkXTogcmVsYXRlZFJlY29yZEZpbHRlcj8ucmVjb3JkPy5pZCA/PyBudWxsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmlsdGVyU3BlY2lmaWVyLmtpbmQgPT09ICdyZWxhdGVkUmVjb3JkcycpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkUmVjb3Jkc0ZpbHRlciA9IGZpbHRlclNwZWNpZmllciBhcyBSZWxhdGVkUmVjb3Jkc0ZpbHRlclNwZWNpZmllcjtcbiAgICAgICAgICBpZiAocmVsYXRlZFJlY29yZHNGaWx0ZXIub3AgIT09ICdlcXVhbCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgICBgRmlsdGVyIG9wZXJhdGlvbiAnJHtyZWxhdGVkUmVjb3Jkc0ZpbHRlci5vcH0nIG5vdCByZWNvZ25pemVkIGJ5IEpTT05BUElVUkxCdWlsZGVyI2J1aWxkRmlsdGVyUGFyYW0gZm9yIHJlbGF0ZWRSZWNvcmRzIGZpbHRlcmluZy4gT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZSBhIGN1c3RvbSBoYW5kbGVyLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpZWxkID0gdGhpcy5zZXJpYWxpemVGaWVsZFBhcmFtKFxuICAgICAgICAgICAgcmVsYXRlZFJlY29yZHNGaWx0ZXIucmVsYXRpb24sXG4gICAgICAgICAgICB7IGtpbmQ6ICdyZWxhdGlvbnNoaXAnIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHBhcmFtcy5wdXNoKHtcbiAgICAgICAgICAgIFtmaWVsZF06IHJlbGF0ZWRSZWNvcmRzRmlsdGVyLnJlY29yZHNcbiAgICAgICAgICAgICAgLm1hcCgoZSkgPT4gZT8uaWQgPz8gbnVsbClcbiAgICAgICAgICAgICAgLmpvaW4oJywnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICAgYEZpbHRlciBvcGVyYXRpb24gJyR7ZmlsdGVyU3BlY2lmaWVyLm9wfScgbm90IHJlY29nbml6ZWQgYnkgSlNPTkFQSVVSTEJ1aWxkZXIjYnVpbGRGaWx0ZXJQYXJhbS4gT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcHJvdmlkZSBhIGN1c3RvbSBoYW5kbGVyLmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGtleSBpbiBmaWx0ZXJzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZmlsdGVyc1trZXldO1xuICAgICAgICBjb25zdCBmaWVsZFBhcmFtID0gdGhpcy5zZXJpYWxpemVGaWVsZFBhcmFtKGtleSk7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgZm9yIChsZXQgdiBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgcGFyYW1zLnB1c2goeyBbZmllbGRQYXJhbV06IHYgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcmFtcy5wdXNoKHsgW2ZpZWxkUGFyYW1dOiB2YWx1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICBidWlsZFNvcnRQYXJhbShcbiAgICBzb3J0U3BlY2lmaWVyczogKFNvcnRTcGVjaWZpZXIgfCBzdHJpbmcpW10gfCBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHJlcXVlc3Q/OiBSZWNvcmRRdWVyeVJlcXVlc3QgfCBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IHN0cmluZyB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydFNwZWNpZmllcnMpKSB7XG4gICAgICByZXR1cm4gc29ydFNwZWNpZmllcnNcbiAgICAgICAgLm1hcCgoc29ydFNwZWNpZmllcikgPT4ge1xuICAgICAgICAgIGxldCBkZXNjZW5kaW5nO1xuICAgICAgICAgIGxldCBmaWVsZE5hbWU7XG4gICAgICAgICAgaWYgKHR5cGVvZiBzb3J0U3BlY2lmaWVyID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZGVzY2VuZGluZyA9IHNvcnRTcGVjaWZpZXIuY2hhckF0KDApID09PSAnLSc7XG4gICAgICAgICAgICBmaWVsZE5hbWUgPSBkZXNjZW5kaW5nID8gc29ydFNwZWNpZmllci5zdWJzdHJpbmcoMSkgOiBzb3J0U3BlY2lmaWVyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc29ydFNwZWNpZmllci5raW5kID09PSAnYXR0cmlidXRlJykge1xuICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlU29ydCA9IHNvcnRTcGVjaWZpZXIgYXMgQXR0cmlidXRlU29ydFNwZWNpZmllcjtcbiAgICAgICAgICAgIGRlc2NlbmRpbmcgPSBhdHRyaWJ1dGVTb3J0Lm9yZGVyID09PSAnZGVzY2VuZGluZyc7XG4gICAgICAgICAgICBmaWVsZE5hbWUgPSBhdHRyaWJ1dGVTb3J0LmF0dHJpYnV0ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZmllbGROYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShmaWVsZE5hbWUsIHtcbiAgICAgICAgICAgICAga2luZDogJ2F0dHJpYnV0ZSdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGAke2Rlc2NlbmRpbmcgPyAnLScgOiAnJ30ke2ZpZWxkfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuam9pbignLCcpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNvcnRTcGVjaWZpZXJzID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNvcnRTcGVjaWZpZXJzO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgYFNvcnQgc3BlY2lmaWVyIG5vdCByZWNvZ25pemVkIGZvciBKU09OQVBJU291cmNlLmBcbiAgICApO1xuICB9XG5cbiAgYnVpbGRQYWdlUGFyYW0oXG4gICAgcGFnZVNwZWNpZmllcjogUGFnZVNwZWNpZmllcixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgcmVxdWVzdD86IFJlY29yZFF1ZXJ5UmVxdWVzdCB8IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogRGljdDx1bmtub3duPiB7XG4gICAgbGV0IHBhZ2VQYXJhbSA9IGNsb25lKHBhZ2VTcGVjaWZpZXIpO1xuICAgIGRlbGV0ZSBwYWdlUGFyYW0ua2luZDtcbiAgICByZXR1cm4gcGFnZVBhcmFtO1xuICB9XG5cbiAgYnVpbGRJbmNsdWRlUGFyYW0oXG4gICAgaW5jbHVkZVNwZWNpZmllcjogc3RyaW5nIHwgc3RyaW5nW10gfCBzdHJpbmdbXVtdLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICByZXF1ZXN0PzogUmVjb3JkUXVlcnlSZXF1ZXN0IHwgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFxuICApOiBzdHJpbmcge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGluY2x1ZGVTcGVjaWZpZXIpKSB7XG4gICAgICByZXR1cm4gaW5jbHVkZVNwZWNpZmllclxuICAgICAgICAubWFwKChzKSA9PiB7XG4gICAgICAgICAgY29uc3QgcGF0aHMgPSBBcnJheS5pc0FycmF5KHMpID8gcyA6IHMuc3BsaXQoJy4nKTtcbiAgICAgICAgICByZXR1cm4gcGF0aHNcbiAgICAgICAgICAgIC5tYXAoKHApID0+IHRoaXMuc2VyaWFsaXplRmllbGRQYXJhbShwLCB7IGtpbmQ6ICdyZWxhdGlvbnNoaXAnIH0pKVxuICAgICAgICAgICAgLmpvaW4oJy4nKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJywnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGluY2x1ZGVTcGVjaWZpZXI7XG4gICAgfVxuICB9XG5cbiAgYnVpbGRGaWVsZHNQYXJhbShcbiAgICBmaWVsZHNTcGVjaWZpZXI6IERpY3Q8c3RyaW5nIHwgc3RyaW5nW10+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICByZXF1ZXN0PzogUmVjb3JkUXVlcnlSZXF1ZXN0IHwgUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFxuICApOiBEaWN0PHN0cmluZz4ge1xuICAgIGNvbnN0IHBhcmFtczogRGljdDxzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCB0eXBlIGluIGZpZWxkc1NwZWNpZmllcikge1xuICAgICAgY29uc3QgdmFsdWUgPSBmaWVsZHNTcGVjaWZpZXJbdHlwZV07XG5cbiAgICAgIGNvbnN0IHNlcmlhbGl6ZXIgPSB0aGlzLnNlcmlhbGl6ZXJGb3IoXG4gICAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZVR5cGVQYXJhbVxuICAgICAgKSBhcyBTdHJpbmdTZXJpYWxpemVyO1xuICAgICAgY29uc3QgdHlwZVBhcmFtID0gc2VyaWFsaXplci5zZXJpYWxpemUodHlwZSk7XG5cbiAgICAgIGNvbnN0IGZpZWxkcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiB2YWx1ZS5zcGxpdCgnLCcpO1xuICAgICAgcGFyYW1zW3R5cGVQYXJhbV0gPSBmaWVsZHNcbiAgICAgICAgLm1hcCgoZjogc3RyaW5nKSA9PiB0aGlzLnNlcmlhbGl6ZUZpZWxkUGFyYW0oZikpXG4gICAgICAgIC5qb2luKCcsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcmFtcztcbiAgfVxuXG4gIGFwcGVuZFF1ZXJ5UGFyYW1zKHVybDogc3RyaW5nLCBwYXJhbXM6IERpY3Q8c3RyaW5nPik6IHN0cmluZyB7XG4gICAgbGV0IGZ1bGxVcmwgPSB1cmw7XG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgZnVsbFVybCA9IGFwcGVuZFF1ZXJ5UGFyYW1zKGZ1bGxVcmwsIHBhcmFtcyk7XG4gICAgfVxuICAgIHJldHVybiBmdWxsVXJsO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNlcmlhbGl6ZUZpZWxkUGFyYW0oXG4gICAgZmllbGQ6IHN0cmluZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgdHlwZT86IHN0cmluZztcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBraW5kIHBhcmFtIHdoZW4gZGVwcmVjYXRlZCBzZXJpYWxpemVyIGlzIHJlbW92ZWRcbiAgICAgIGtpbmQ/OiAnYXR0cmlidXRlJyB8ICdyZWxhdGlvbnNoaXAnO1xuICAgIH1cbiAgKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5zZXJpYWxpemVyKSB7XG4gICAgICBpZiAob3B0aW9ucz8ua2luZCA9PT0gJ2F0dHJpYnV0ZScpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VyaWFsaXplci5yZXNvdXJjZUF0dHJpYnV0ZShvcHRpb25zPy50eXBlLCBmaWVsZCk7XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnM/LmtpbmQgPT09ICdyZWxhdGlvbnNoaXAnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VSZWxhdGlvbnNoaXAob3B0aW9ucz8udHlwZSwgZmllbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVyID0gdGhpcy5zZXJpYWxpemVyRm9yKFxuICAgICAgICBKU09OQVBJU2VyaWFsaXplcnMuUmVzb3VyY2VGaWVsZFBhcmFtXG4gICAgICApIGFzIEpTT05BUElSZXNvdXJjZUZpZWxkU2VyaWFsaXplcjtcbiAgICAgIHJldHVybiBzZXJpYWxpemVyLnNlcmlhbGl6ZShmaWVsZCwgeyB0eXBlOiBvcHRpb25zPy50eXBlIH0pIGFzIHN0cmluZztcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VyaWFsaXplUmVsYXRpb25zaGlwSW5QYXRoKFxuICAgIHR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZ1xuICApOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnNlcmlhbGl6ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIucmVzb3VyY2VSZWxhdGlvbnNoaXAodHlwZSwgcmVsYXRpb25zaGlwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc2VyaWFsaXplciA9IHRoaXMuc2VyaWFsaXplckZvcihcbiAgICAgICAgSlNPTkFQSVNlcmlhbGl6ZXJzLlJlc291cmNlRmllbGRQYXRoXG4gICAgICApIGFzIEpTT05BUElSZXNvdXJjZUZpZWxkU2VyaWFsaXplcjtcbiAgICAgIHJldHVybiBzZXJpYWxpemVyLnNlcmlhbGl6ZShyZWxhdGlvbnNoaXAsIHsgdHlwZSB9KSBhcyBzdHJpbmc7XG4gICAgfVxuICB9XG59XG4iXX0=