@decorators/server
Version:
node decorators - decorators for express library
180 lines • 26 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SwaggerDocument = exports.DEFAULT_METHOD = exports.DEFAULT_STATUS = void 0;
const di_1 = require("@decorators/di");
const core_1 = require("../../../../core");
const http_1 = require("../../../http");
const sockets_1 = require("../../../sockets");
const constants_1 = require("../constants");
const utils_1 = require("./utils");
exports.DEFAULT_STATUS = 200;
exports.DEFAULT_METHOD = http_1.HttpMethodType.POST;
let SwaggerDocument = exports.SwaggerDocument = class SwaggerDocument {
constructor(appVersion, config, metadataScanner, reflector) {
this.appVersion = appVersion;
this.config = config;
this.metadataScanner = metadataScanner;
this.reflector = reflector;
this.paths = {};
this.schemas = {};
this.securitySchemas = {};
}
generate() {
this.processMetadata();
return {
components: {
schemas: this.schemas,
securitySchemes: this.securitySchemas,
},
info: {
description: this.config.description,
title: this.config.title,
version: this.appVersion,
},
openapi: '3.0.3',
paths: this.paths,
};
}
addSchema(type) {
if (type && !(0, utils_1.isStandardType)(type) && !this.schemas[type.name]) {
this.schemas[type.name] = this.getSchema(type);
}
}
getPath(route) {
const simpleMeta = this.reflector.getMetadata(constants_1.METHOD_API_RESPONSE_METADATA, route.controller.prototype[route.methodName]);
const detailedMeta = this.reflector.getMetadata(constants_1.METHOD_API_RESPONSES_METADATA, route.controller.prototype[route.methodName]);
const operationMeta = this.reflector.getMetadata(constants_1.METHOD_API_OPERATION_METADATA, route.controller.prototype[route.methodName]);
const ctrlMethod = `${route.controller.name}.${route.methodName}`;
const bodyParam = route.params.find(param => param.paramType === http_1.ParameterType.BODY);
const parameters = route.params
.filter(param => param.paramType)
.map(param => ({
in: param.paramType,
name: param.argName,
required: param.paramType !== http_1.ParameterType.BODY,
schema: this.getRefType(param.argType),
}));
const body = parameters.find(param => param.in === http_1.ParameterType.BODY);
let requestBody;
if (body) {
parameters.splice(parameters.indexOf(body), 1);
requestBody = {
content: {
[(0, utils_1.typeToContentType)(bodyParam.argType)]: (0, utils_1.pick)(body, 'schema'),
},
};
}
const preResponses = {
[route.status || exports.DEFAULT_STATUS]: { type: route.returnType, ...simpleMeta },
...detailedMeta,
};
const responses = Object.keys(preResponses).reduce((acc, status) => ({
...acc, [status]: this.toResponse(preResponses[status], route.methodName),
}), {});
const security = this.securitySchemas[ctrlMethod] ? [{ [ctrlMethod]: [] }] : [];
const tag = route.source === sockets_1.SOURCE_TYPE
? `Sockets :: ${route.controller.name}`
: route.controller.name;
return {
...operationMeta,
parameters,
requestBody,
responses,
security,
tags: [tag],
};
}
getRefType(type) {
const typeName = type === null || type === void 0 ? void 0 : type.name;
return this.schemas[typeName]
? { $ref: `#/components/schemas/${typeName}` }
: { type: typeName === null || typeName === void 0 ? void 0 : typeName.toLowerCase() };
}
getSchema(type) {
const schema = {
properties: {},
required: [],
title: type.name,
};
const meta = (0, utils_1.getValidationMeta)(type);
if (!meta.length) {
return schema;
}
const keys = new Set(meta.map(({ propertyName }) => propertyName));
for (const key of [...keys]) {
const validators = meta.filter(({ propertyName }) => propertyName === key);
const parameterMeta = this.reflector.getMetadata(constants_1.PROPERTY_API_PARAMETER_METADATA, type.prototype, key);
// applied validators
const typeValidator = validators.find(({ name }) => name === null || name === void 0 ? void 0 : name.startsWith('is'));
const minimum = validators.find(({ name }) => name === 'min');
const maximum = validators.find(({ name }) => name === 'max');
if (!validators.some(({ type }) => type.startsWith('conditional'))) {
schema.required.push(key);
}
schema.properties[key] = {
...parameterMeta,
maximum: maximum === null || maximum === void 0 ? void 0 : maximum.constraints[0],
minimum: minimum === null || minimum === void 0 ? void 0 : minimum.constraints[0],
type: typeValidator === null || typeValidator === void 0 ? void 0 : typeValidator.name.toLowerCase().replace('is', ''),
};
}
return schema;
}
processMetadata() {
var _a;
const routeMetadata = this.metadataScanner.scan();
for (const route of routeMetadata) {
for (const param of route.params) {
this.addSchema(param.argType);
}
this.addSchema(route.returnType);
const meta = this.reflector.getMetadata(constants_1.METHOD_API_SECURITY_METADATA, route.controller.prototype[route.methodName]);
if (meta) {
this.securitySchemas[`${route.controller.name}.${route.methodName}`] = meta;
}
const rawUrl = (0, utils_1.replaceUrlParameters)(route.url);
const url = route.source === sockets_1.SOURCE_TYPE
? `${rawUrl} => ${route.type}` + (route['event'] ? ` => ${route['event']}` : '')
: rawUrl;
const methodType = route.source === sockets_1.SOURCE_TYPE
? exports.DEFAULT_METHOD
: route.type;
this.paths[url] = {
...((_a = this.paths[url]) !== null && _a !== void 0 ? _a : {}),
[methodType]: this.getPath(route),
};
}
}
toResponse(response, description) {
var _a;
return {
content: {
[(0, utils_1.typeToContentType)(response.type)]: {
schema: this.getRefType(response.type),
},
},
description: (_a = response.description) !== null && _a !== void 0 ? _a : description,
};
}
};
exports.SwaggerDocument = SwaggerDocument = __decorate([
(0, di_1.Injectable)(),
__param(0, (0, di_1.Inject)(core_1.APP_VERSION)),
__param(0, (0, di_1.Optional)()),
__param(1, (0, di_1.Inject)(constants_1.SWAGGER_CONFIG)),
__metadata("design:paramtypes", [String, Object, core_1.MetadataScanner,
core_1.Reflector])
], SwaggerDocument);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3dhZ2dlci1kb2N1bWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wbGF0Zm9ybXMvc3dhZ2dlci9oZWxwZXJzL3N3YWdnZXItdWkvc3dhZ2dlci1kb2N1bWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBOEQ7QUFHOUQsMkNBQXNHO0FBQ3RHLHdDQUE2RTtBQUM3RSw4Q0FBc0U7QUFFdEUsNENBQXlNO0FBQ3pNLG1DQUEyRztBQUU5RixRQUFBLGNBQWMsR0FBRyxHQUFHLENBQUM7QUFDckIsUUFBQSxjQUFjLEdBQUcscUJBQWMsQ0FBQyxJQUFJLENBQUM7QUFHM0MsSUFBTSxlQUFlLDZCQUFyQixNQUFNLGVBQWU7SUFLMUIsWUFDbUMsVUFBMEIsRUFDbkMsTUFBNkIsRUFDN0MsZUFBZ0MsRUFDaEMsU0FBb0I7UUFIYSxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQzNCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDN0Msb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFSdEIsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLFlBQU8sR0FBRyxFQUFFLENBQUM7UUFDYixvQkFBZSxHQUFHLEVBQUUsQ0FBQztJQU96QixDQUFDO0lBRUwsUUFBUTtRQUNOLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV2QixPQUFPO1lBQ0wsVUFBVSxFQUFFO2dCQUNWLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztnQkFDckIsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO2FBQ3RDO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7Z0JBQ3BDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7Z0JBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVTthQUN6QjtZQUNELE9BQU8sRUFB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QUMsV0FBVyxtQ0FBSSxXQUFXO1NBQ25CLENBQUM7SUFDbEMsQ0FBQztDQUNGLENBQUE7MEJBbk1ZLGVBQWU7SUFEM0IsSUFBQSxlQUFVLEdBQUU7SUFPUixXQUFBLElBQUEsV0FBTSxFQUFDLGtCQUFXLENBQUMsQ0FBQTtJQUFFLFdBQUEsSUFBQSxhQUFRLEdBQUUsQ0FBQTtJQUMvQixXQUFBLElBQUEsV0FBTSxFQUFDLDBCQUFjLENBQUMsQ0FBQTtxREFDRSxzQkFBZTtRQUNyQixnQkFBUztHQVRuQixlQUFlLENBbU0zQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgT3B0aW9uYWwgfSBmcm9tICdAZGVjb3JhdG9ycy9kaSc7XG5pbXBvcnQgeyBPcGVuQVBJVjNfMSB9IGZyb20gJ29wZW5hcGktdHlwZXMnO1xuXG5pbXBvcnQgeyBBUFBfVkVSU0lPTiwgQ2xhc3NDb25zdHJ1Y3RvciwgSGFuZGxlciwgTWV0YWRhdGFTY2FubmVyLCBSZWZsZWN0b3IgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlJztcbmltcG9ydCB7IEh0dHBNZXRob2RUeXBlLCBQYXJhbWV0ZXJUeXBlLCBSb3V0ZU1ldGFkYXRhIH0gZnJvbSAnLi4vLi4vLi4vaHR0cCc7XG5pbXBvcnQgeyBTT1VSQ0VfVFlQRSBhcyBTT0NLRVRTX1NPVVJDRV9UWVBFIH0gZnJvbSAnLi4vLi4vLi4vc29ja2V0cyc7XG5pbXBvcnQgeyBBcGlSZXNwb25zZSwgU3dhZ2dlckNvbmZpZyB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IE1FVEhPRF9BUElfT1BFUkFUSU9OX01FVEFEQVRBLCBNRVRIT0RfQVBJX1JFU1BPTlNFX01FVEFEQVRBLCBNRVRIT0RfQVBJX1JFU1BPTlNFU19NRVRBREFUQSwgTUVUSE9EX0FQSV9TRUNVUklUWV9NRVRBREFUQSwgUFJPUEVSVFlfQVBJX1BBUkFNRVRFUl9NRVRBREFUQSwgU1dBR0dFUl9DT05GSUcgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgZ2V0VmFsaWRhdGlvbk1ldGEsIGlzU3RhbmRhcmRUeXBlLCBwaWNrLCByZXBsYWNlVXJsUGFyYW1ldGVycywgdHlwZVRvQ29udGVudFR5cGUgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU1RBVFVTID0gMjAwO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUVUSE9EID0gSHR0cE1ldGhvZFR5cGUuUE9TVDtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFN3YWdnZXJEb2N1bWVudCB7XG4gIHByaXZhdGUgcGF0aHMgPSB7fTtcbiAgcHJpdmF0ZSBzY2hlbWFzID0ge307XG4gIHByaXZhdGUgc2VjdXJpdHlTY2hlbWFzID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChBUFBfVkVSU0lPTikgQE9wdGlvbmFsKCkgcHJpdmF0ZSBhcHBWZXJzaW9uOiBzdHJpbmcsXG4gICAgQEluamVjdChTV0FHR0VSX0NPTkZJRykgcHJpdmF0ZSBjb25maWc6IFN3YWdnZXJDb25maWcsXG4gICAgcHJpdmF0ZSBtZXRhZGF0YVNjYW5uZXI6IE1ldGFkYXRhU2Nhbm5lcixcbiAgICBwcml2YXRlIHJlZmxlY3RvcjogUmVmbGVjdG9yLFxuICApIHsgfVxuXG4gIGdlbmVyYXRlKCkge1xuICAgIHRoaXMucHJvY2Vzc01ldGFkYXRhKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcG9uZW50czoge1xuICAgICAgICBzY2hlbWFzOiB0aGlzLnNjaGVtYXMsXG4gICAgICAgIHNlY3VyaXR5U2NoZW1lczogdGhpcy5zZWN1cml0eVNjaGVtYXMsXG4gICAgICB9LFxuICAgICAgaW5mbzoge1xuICAgICAgICBkZXNjcmlwdGlvbjogdGhpcy5jb25maWcuZGVzY3JpcHRpb24sXG4gICAgICAgIHRpdGxlOiB0aGlzLmNvbmZpZy50aXRsZSxcbiAgICAgICAgdmVyc2lvbjogdGhpcy5hcHBWZXJzaW9uLFxuICAgICAgfSxcbiAgICAgIG9wZW5hcGk6ICczLjAuMycsXG4gICAgICBwYXRoczogdGhpcy5wYXRocyxcbiAgICB9IGFzIE9wZW5BUElWM18xLkRvY3VtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRTY2hlbWEodHlwZT86IEhhbmRsZXIgfCBDbGFzc0NvbnN0cnVjdG9yKSB7XG4gICAgaWYgKHR5cGUgJiYgIWlzU3RhbmRhcmRUeXBlKHR5cGUpICYmICF0aGlzLnNjaGVtYXNbdHlwZS5uYW1lXSkge1xuICAgICAgdGhpcy5zY2hlbWFzW3R5cGUubmFtZV0gPSB0aGlzLmdldFNjaGVtYSh0eXBlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFBhdGgocm91dGU6IFJvdXRlTWV0YWRhdGEpIHtcbiAgICBjb25zdCBzaW1wbGVNZXRhID0gdGhpcy5yZWZsZWN0b3IuZ2V0TWV0YWRhdGEoXG4gICAgICBNRVRIT0RfQVBJX1JFU1BPTlNFX01FVEFEQVRBLFxuICAgICAgcm91dGUuY29udHJvbGxlci5wcm90b3R5cGVbcm91dGUubWV0aG9kTmFtZV0sXG4gICAgKTtcbiAgICBjb25zdCBkZXRhaWxlZE1ldGEgPSB0aGlzLnJlZmxlY3Rvci5nZXRNZXRhZGF0YShcbiAgICAgIE1FVEhPRF9BUElfUkVTUE9OU0VTX01FVEFEQVRBLFxuICAgICAgcm91dGUuY29udHJvbGxlci5wcm90b3R5cGVbcm91dGUubWV0aG9kTmFtZV0sXG4gICAgKTtcbiAgICBjb25zdCBvcGVyYXRpb25NZXRhID0gdGhpcy5yZWZsZWN0b3IuZ2V0TWV0YWRhdGEoXG4gICAgICBNRVRIT0RfQVBJX09QRVJBVElPTl9NRVRBREFUQSxcbiAgICAgIHJvdXRlLmNvbnRyb2xsZXIucHJvdG90eXBlW3JvdXRlLm1ldGhvZE5hbWVdLFxuICAgICk7XG5cbiAgICBjb25zdCBjdHJsTWV0aG9kID0gYCR7cm91dGUuY29udHJvbGxlci5uYW1lfS4ke3JvdXRlLm1ldGhvZE5hbWV9YDtcblxuICAgIGNvbnN0IGJvZHlQYXJhbSA9IHJvdXRlLnBhcmFtcy5maW5kKHBhcmFtID0+IHBhcmFtLnBhcmFtVHlwZSA9PT0gUGFyYW1ldGVyVHlwZS5CT0RZKTtcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gcm91dGUucGFyYW1zXG4gICAgICAuZmlsdGVyKHBhcmFtID0+IHBhcmFtLnBhcmFtVHlwZSlcbiAgICAgIC5tYXAocGFyYW0gPT4gKHtcbiAgICAgICAgaW46IHBhcmFtLnBhcmFtVHlwZSxcbiAgICAgICAgbmFtZTogcGFyYW0uYXJnTmFtZSxcbiAgICAgICAgcmVxdWlyZWQ6IHBhcmFtLnBhcmFtVHlwZSAhPT0gUGFyYW1ldGVyVHlwZS5CT0RZLFxuICAgICAgICBzY2hlbWE6IHRoaXMuZ2V0UmVmVHlwZShwYXJhbS5hcmdUeXBlKSxcbiAgICAgIH0gYXMgT3BlbkFQSVYzXzEuUGFyYW1ldGVyT2JqZWN0KSk7XG5cbiAgICBjb25zdCBib2R5ID0gcGFyYW1ldGVycy5maW5kKHBhcmFtID0+IHBhcmFtLmluID09PSBQYXJhbWV0ZXJUeXBlLkJPRFkpO1xuICAgIGxldCByZXF1ZXN0Qm9keTogT3BlbkFQSVYzXzEuUmVxdWVzdEJvZHlPYmplY3Q7XG5cbiAgICBpZiAoYm9keSkge1xuICAgICAgcGFyYW1ldGVycy5zcGxpY2UocGFyYW1ldGVycy5pbmRleE9mKGJvZHkpLCAxKTtcblxuICAgICAgcmVxdWVzdEJvZHkgPSB7XG4gICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICBbdHlwZVRvQ29udGVudFR5cGUoYm9keVBhcmFtLmFyZ1R5cGUpXTogcGljayhib2R5LCAnc2NoZW1hJyksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHByZVJlc3BvbnNlcyA9IHtcbiAgICAgIFtyb3V0ZS5zdGF0dXMgfHwgREVGQVVMVF9TVEFUVVNdOiB7IHR5cGU6IHJvdXRlLnJldHVyblR5cGUsIC4uLnNpbXBsZU1ldGEgfSxcbiAgICAgIC4uLmRldGFpbGVkTWV0YSxcbiAgICB9O1xuICAgIGNvbnN0IHJlc3BvbnNlcyA9IE9iamVjdC5rZXlzKHByZVJlc3BvbnNlcykucmVkdWNlKChhY2MsIHN0YXR1cykgPT4gKHtcbiAgICAgIC4uLmFjYywgW3N0YXR1c106IHRoaXMudG9SZXNwb25zZShwcmVSZXNwb25zZXNbc3RhdHVzXSwgcm91dGUubWV0aG9kTmFtZSksXG4gICAgfSksIHt9KTtcblxuICAgIGNvbnN0IHNlY3VyaXR5ID0gdGhpcy5zZWN1cml0eVNjaGVtYXNbY3RybE1ldGhvZF0gPyBbeyBbY3RybE1ldGhvZF06IFtdIH1dIDogW107XG5cbiAgICBjb25zdCB0YWcgPSByb3V0ZS5zb3VyY2UgPT09IFNPQ0tFVFNfU09VUkNFX1RZUEVcbiAgICAgID8gYFNvY2tldHMgOjogJHtyb3V0ZS5jb250cm9sbGVyLm5hbWV9YFxuICAgICAgOiByb3V0ZS5jb250cm9sbGVyLm5hbWU7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ub3BlcmF0aW9uTWV0YSxcbiAgICAgIHBhcmFtZXRlcnMsXG4gICAgICByZXF1ZXN0Qm9keSxcbiAgICAgIHJlc3BvbnNlcyxcbiAgICAgIHNlY3VyaXR5LFxuICAgICAgdGFnczogW3RhZ10sXG4gICAgfSBhcyBPcGVuQVBJVjNfMS5PcGVyYXRpb25PYmplY3Q7XG4gIH1cblxuICBwcml2YXRlIGdldFJlZlR5cGUodHlwZT86IEhhbmRsZXIgfCBDbGFzc0NvbnN0cnVjdG9yKSB7XG4gICAgY29uc3QgdHlwZU5hbWUgPSB0eXBlPy5uYW1lO1xuXG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hc1t0eXBlTmFtZV1cbiAgICAgID8geyAkcmVmOiBgIy9jb21wb25lbnRzL3NjaGVtYXMvJHt0eXBlTmFtZX1gIH1cbiAgICAgIDogeyB0eXBlOiB0eXBlTmFtZT8udG9Mb3dlckNhc2UoKSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTY2hlbWEodHlwZTogSGFuZGxlciB8IENsYXNzQ29uc3RydWN0b3IpIHtcbiAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICBwcm9wZXJ0aWVzOiB7fSxcbiAgICAgIHJlcXVpcmVkOiBbXSxcbiAgICAgIHRpdGxlOiB0eXBlLm5hbWUsXG4gICAgfSBhcyBPcGVuQVBJVjNfMS5TY2hlbWFPYmplY3Q7XG5cbiAgICBjb25zdCBtZXRhID0gZ2V0VmFsaWRhdGlvbk1ldGEodHlwZSk7XG5cbiAgICBpZiAoIW1ldGEubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc2NoZW1hO1xuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KG1ldGEubWFwKCh7IHByb3BlcnR5TmFtZSB9KSA9PiBwcm9wZXJ0eU5hbWUpKTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIFsuLi5rZXlzXSkge1xuICAgICAgY29uc3QgdmFsaWRhdG9ycyA9IG1ldGEuZmlsdGVyKCh7IHByb3BlcnR5TmFtZSB9KSA9PiBwcm9wZXJ0eU5hbWUgPT09IGtleSk7XG4gICAgICBjb25zdCBwYXJhbWV0ZXJNZXRhID0gdGhpcy5yZWZsZWN0b3IuZ2V0TWV0YWRhdGEoXG4gICAgICAgIFBST1BFUlRZX0FQSV9QQVJBTUVURVJfTUVUQURBVEEsXG4gICAgICAgIHR5cGUucHJvdG90eXBlLFxuICAgICAgICBrZXksXG4gICAgICApO1xuXG4gICAgICAvLyBhcHBsaWVkIHZhbGlkYXRvcnNcbiAgICAgIGNvbnN0IHR5cGVWYWxpZGF0b3IgPSB2YWxpZGF0b3JzLmZpbmQoKHsgbmFtZSB9KSA9PiBuYW1lPy5zdGFydHNXaXRoKCdpcycpKTtcbiAgICAgIGNvbnN0IG1pbmltdW0gPSB2YWxpZGF0b3JzLmZpbmQoKHsgbmFtZSB9KSA9PiBuYW1lID09PSAnbWluJyk7XG4gICAgICBjb25zdCBtYXhpbXVtID0gdmFsaWRhdG9ycy5maW5kKCh7IG5hbWUgfSkgPT4gbmFtZSA9PT0gJ21heCcpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRvcnMuc29tZSgoeyB0eXBlIH0pID0+IHR5cGUuc3RhcnRzV2l0aCgnY29uZGl0aW9uYWwnKSkpIHtcbiAgICAgICAgc2NoZW1hLnJlcXVpcmVkLnB1c2goa2V5KTtcbiAgICAgIH1cblxuICAgICAgc2NoZW1hLnByb3BlcnRpZXNba2V5XSA9IHtcbiAgICAgICAgLi4ucGFyYW1ldGVyTWV0YSxcbiAgICAgICAgbWF4aW11bTogbWF4aW11bT8uY29uc3RyYWludHNbMF0sXG4gICAgICAgIG1pbmltdW06IG1pbmltdW0/LmNvbnN0cmFpbnRzWzBdLFxuICAgICAgICB0eXBlOiB0eXBlVmFsaWRhdG9yPy5uYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgnaXMnLCAnJyksXG4gICAgICB9IGFzIE9wZW5BUElWM18xLlNjaGVtYU9iamVjdDtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTWV0YWRhdGEoKSB7XG4gICAgY29uc3Qgcm91dGVNZXRhZGF0YSA9IHRoaXMubWV0YWRhdGFTY2FubmVyLnNjYW4oKTtcblxuICAgIGZvciAoY29uc3Qgcm91dGUgb2Ygcm91dGVNZXRhZGF0YSkge1xuICAgICAgZm9yIChjb25zdCBwYXJhbSBvZiByb3V0ZS5wYXJhbXMpIHtcbiAgICAgICAgdGhpcy5hZGRTY2hlbWEocGFyYW0uYXJnVHlwZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWRkU2NoZW1hKHJvdXRlLnJldHVyblR5cGUpO1xuXG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5yZWZsZWN0b3IuZ2V0TWV0YWRhdGEoXG4gICAgICAgIE1FVEhPRF9BUElfU0VDVVJJVFlfTUVUQURBVEEsXG4gICAgICAgIHJvdXRlLmNvbnRyb2xsZXIucHJvdG90eXBlW3JvdXRlLm1ldGhvZE5hbWVdLFxuICAgICAgKTtcblxuICAgICAgaWYgKG1ldGEpIHtcbiAgICAgICAgdGhpcy5zZWN1cml0eVNjaGVtYXNbYCR7cm91dGUuY29udHJvbGxlci5uYW1lfS4ke3JvdXRlLm1ldGhvZE5hbWV9YF0gPSBtZXRhO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByYXdVcmwgPSByZXBsYWNlVXJsUGFyYW1ldGVycyhyb3V0ZS51cmwpO1xuICAgICAgY29uc3QgdXJsID0gcm91dGUuc291cmNlID09PSBTT0NLRVRTX1NPVVJDRV9UWVBFXG4gICAgICAgID8gYCR7cmF3VXJsfSA9PiAke3JvdXRlLnR5cGV9YCArIChyb3V0ZVsnZXZlbnQnXSA/IGAgPT4gJHtyb3V0ZVsnZXZlbnQnXX1gIDogJycpXG4gICAgICAgIDogcmF3VXJsO1xuXG4gICAgICBjb25zdCBtZXRob2RUeXBlID0gcm91dGUuc291cmNlID09PSBTT0NLRVRTX1NPVVJDRV9UWVBFXG4gICAgICAgID8gREVGQVVMVF9NRVRIT0RcbiAgICAgICAgOiByb3V0ZS50eXBlO1xuXG4gICAgICB0aGlzLnBhdGhzW3VybF0gPSB7XG4gICAgICAgIC4uLih0aGlzLnBhdGhzW3VybF0gPz8ge30pLFxuICAgICAgICBbbWV0aG9kVHlwZV06IHRoaXMuZ2V0UGF0aChyb3V0ZSksXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdG9SZXNwb25zZShyZXNwb25zZTogQXBpUmVzcG9uc2UsIGRlc2NyaXB0aW9uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDoge1xuICAgICAgICBbdHlwZVRvQ29udGVudFR5cGUocmVzcG9uc2UudHlwZSldOiB7XG4gICAgICAgICAgc2NoZW1hOiB0aGlzLmdldFJlZlR5cGUocmVzcG9uc2UudHlwZSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgZGVzY3JpcHRpb246IHJlc3BvbnNlLmRlc2NyaXB0aW9uID8/IGRlc2NyaXB0aW9uLFxuICAgIH0gYXMgT3BlbkFQSVYzXzEuUmVzcG9uc2VPYmplY3Q7XG4gIH1cbn1cbiJdfQ==