@rudderstack/integrations-lib
Version:
A comprehensive TypeScript library providing shared utilities, SDKs, and tools for RudderStack integrations and destinations.
218 lines • 27.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonSchemaGenerator = void 0;
/* eslint-disable no-plusplus */
const jsonschema_1 = require("jsonschema");
/**
* Utility for generating and validating JSON Schemas from data.
*/
class JsonSchemaGenerator {
/**
* Validates the provided data against the given JSON Schema.
*
* @param data - The data to validate.
* @param schema - The JSON Schema to use for validation.
* @throws Error if the validation fails.
*/
static validate(data, schema) {
const result = this.validator.validate(data, schema);
if (!result.valid) {
throw new Error(`Validation failed: ${result.errors.join(', ')}`);
}
}
/**
* Generates a JSON Schema for the given data.
*
* @param data - The data for which to generate a JSON Schema.
* @param options - Generation options.
* @returns The generated JSON Schema.
*/
static generate(data, options = {}) {
return this.buildSchema(data, options);
}
// ─── PRIVATE HELPERS ────────────────────────────────────────────
/**
* Determines the primitive type of a value.
*
* @param data - The data whose type is to be inferred.
* @returns A string representing the type.
*/
static inferType(data) {
if (data === null)
return 'null';
if (Array.isArray(data))
return 'array';
if (typeof data === 'object')
return 'object';
return typeof data;
}
/**
* Recursively builds a JSON Schema from the provided data.
*
* @param data - The data to interpret.
* @param options - Generation options.
* @returns A JSON Schema object.
*/
static buildSchema(data, options) {
const type = this.inferType(data);
switch (type) {
case 'null':
return { type: 'null' };
case 'array':
return this.buildArraySchema(data, options);
case 'object':
return this.buildObjectSchema(data, options);
default:
return { type };
}
}
/**
* Checks if all types in an array are one of the primitive types:
* string, number, or boolean.
*
* @param types - An array of type strings.
* @returns True if every type is primitive.
*/
static allTypesArePrimitive(types) {
return types.every((type) => ['string', 'number', 'boolean'].includes(type));
}
/**
* Generates a JSON Schema for an array.
*
* @param data - The array data.
* @param options - Generation options.
* @returns The JSON Schema corresponding to the array data.
*/
static buildArraySchema(data, options) {
if (data.length === 0) {
return { type: 'array', items: { type: 'any' } };
}
const types = data.map(this.inferType);
if (this.allTypesArePrimitive(types)) {
const uniqueTypes = Array.from(new Set(types));
if (uniqueTypes.length === 1) {
return {
type: 'array',
items: {
type: uniqueTypes[0],
...(uniqueTypes[0] === 'string' && options.detectEnums
? { enum: Array.from(new Set(data)) }
: {}),
},
};
}
return { type: 'array', items: { type: uniqueTypes } };
}
return this.buildMixedArraySchema(data, options);
}
/**
* Generates a JSON Schema for an array containing mixed types.
*
* @param data - The array data.
* @param options - Generation options.
* @returns The JSON Schema with an "anyOf" clause.
*/
static buildMixedArraySchema(data, options) {
const schemas = data.map((item) => this.buildSchema(item, options));
const uniqueSchemas = this.mergeSimilarSchemas(schemas);
return {
type: 'array',
items: uniqueSchemas.length === 1 ? uniqueSchemas[0] : { anyOf: uniqueSchemas },
};
}
/**
* Generates a JSON Schema for an object.
*
* @param data - The object data.
* @param options - Generation options.
* @returns The JSON Schema for the object.
*/
static buildObjectSchema(data, options) {
const properties = {};
const required = [];
const { requireAll = false } = options;
Object.entries(data).forEach(([key, value]) => {
properties[key] = this.buildSchema(value, options);
if (requireAll)
required.push(key);
});
return {
type: 'object',
properties,
...(required.length > 0 ? { required } : {}),
};
}
/**
* Attempts to merge two JSON Schemas. Merging is only successful if both schemas have the same type
* and there are no conflicts within defined properties.
*
* @param schemaA - The first JSON Schema.
* @param schemaB - The second JSON Schema.
* @returns The merged schema if successful; otherwise, null.
*/
static mergeTwoSchemas(schemaA, schemaB) {
if (schemaA.type !== schemaB.type)
return null;
const propsA = schemaA.properties || {};
const propsB = schemaB.properties || {};
const allKeys = Array.from(new Set([...Object.keys(propsA), ...Object.keys(propsB)]));
const hasConflict = allKeys.some((key) => key in propsA &&
key in propsB &&
JSON.stringify(propsA[key]) !== JSON.stringify(propsB[key]));
if (hasConflict)
return null;
const mergedProperties = allKeys.reduce((acc, key) => {
acc[key] = propsA[key] || propsB[key];
return acc;
}, {});
// A property is required in the merged schema only if it was required in both.
const requiredA = new Set(schemaA.required || []);
const requiredMerged = (schemaB.required || []).filter((field) => requiredA.has(field));
return {
...schemaA,
...schemaB,
type: schemaA.type,
...(Object.keys(mergedProperties).length > 0 ? { properties: mergedProperties } : {}),
...(requiredMerged.length > 0 ? { required: requiredMerged } : {}),
};
}
/**
* Merges an array of JSON Schemas. Schemas with the same type and non-conflicting
* definitions are merged together.
*
* @param schemas - The list of schemas to merge.
* @returns A deduplicated list of merged schemas.
*/
static mergeSimilarSchemas(schemas) {
if (schemas.length <= 1)
return [...schemas];
let mergedSchemas = [...schemas];
// Attempt one merge pass
const attemptMerge = (schemasList) => {
for (let i = 0; i < schemasList.length; i++) {
for (let j = i + 1; j < schemasList.length; j++) {
const merged = this.mergeTwoSchemas(schemasList[i], schemasList[j]);
if (merged) {
const newSchemas = [
...schemasList.slice(0, i),
merged,
...schemasList.slice(i + 1, j),
...schemasList.slice(j + 1),
];
return { schemas: newSchemas, merged: true };
}
}
}
return { schemas: schemasList, merged: false };
};
let result = attemptMerge(mergedSchemas);
while (result.merged) {
mergedSchemas = result.schemas;
result = attemptMerge(mergedSchemas);
}
return mergedSchemas;
}
}
exports.JsonSchemaGenerator = JsonSchemaGenerator;
JsonSchemaGenerator.validator = new jsonschema_1.Validator();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtZ2VuZXJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2pzb24tc2NoZW1hLWdlbmVyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxnQ0FBZ0M7QUFDaEMsMkNBQXVDO0FBd0J2Qzs7R0FFRztBQUNILE1BQWEsbUJBQW1CO0lBRzlCOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBYSxFQUFFLE1BQXNCO1FBQzFELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwRSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBYSxFQUFFLFVBQXNDLEVBQUU7UUFDNUUsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsbUVBQW1FO0lBRW5FOzs7OztPQUtHO0lBQ0ssTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFhO1FBQ3BDLElBQUksSUFBSSxLQUFLLElBQUk7WUFBRSxPQUFPLE1BQU0sQ0FBQztRQUNqQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFDeEMsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRO1lBQUUsT0FBTyxRQUFRLENBQUM7UUFDOUMsT0FBTyxPQUFPLElBQUksQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssTUFBTSxDQUFDLFdBQVcsQ0FB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LEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO3lCQUM1QixDQUFDO3dCQUNGLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztvQkFDL0MsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUNqRCxDQUFDLENBQUM7UUFFRixJQUFJLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDekMsT0FBTyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsYUFBYSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7WUFDL0IsTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQzs7QUFoUEgsa0RBaVBDO0FBaFBnQiw2QkFBUyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tcGx1c3BsdXMgKi9cbmltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gJ2pzb25zY2hlbWEnO1xuXG4vKipcbiAqIFR5cGUgZGVmaW5pdGlvbiBmb3IgYSBKU09OIFNjaGVtYS5cbiAqL1xuZXhwb3J0IHR5cGUgSlNPTlNjaGVtYVR5cGUgPSB7XG4gIHR5cGU/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgcHJvcGVydGllcz86IHsgW2tleTogc3RyaW5nXTogSlNPTlNjaGVtYVR5cGUgfTtcbiAgaXRlbXM/OiBKU09OU2NoZW1hVHlwZTtcbiAgcmVxdWlyZWQ/OiBzdHJpbmdbXTtcbiAgZW51bT86IGFueVtdO1xuICBhbnlPZj86IEpTT05TY2hlbWFUeXBlW107XG59O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGdlbmVyYXRpbmcgSlNPTiBTY2hlbWFzLlxuICovXG5leHBvcnQgdHlwZSBKc29uU2NoZW1hR2VuZXJhdG9yT3B0aW9ucyA9IHtcbiAgLyoqIElmIHRydWUsIG1hcmtzIGV2ZXJ5IHByb3BlcnR5IGluIGFuIG9iamVjdCBhcyByZXF1aXJlZCAqL1xuICByZXF1aXJlQWxsPzogYm9vbGVhbjtcbiAgLyoqIElmIHRydWUsIGF0dGVtcHRzIHRvIGRldGVjdCBhbmQgaW5jbHVkZSBlbnVtcyBmb3IgYXJyYXlzIG9mIHN0cmluZ3MgKi9cbiAgZGV0ZWN0RW51bXM/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBVdGlsaXR5IGZvciBnZW5lcmF0aW5nIGFuZCB2YWxpZGF0aW5nIEpTT04gU2NoZW1hcyBmcm9tIGRhdGEuXG4gKi9cbmV4cG9ydCBjbGFzcyBKc29uU2NoZW1hR2VuZXJhdG9yIHtcbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdG9yID0gbmV3IFZhbGlkYXRvcigpO1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIHByb3ZpZGVkIGRhdGEgYWdhaW5zdCB0aGUgZ2l2ZW4gSlNPTiBTY2hlbWEuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gVGhlIGRhdGEgdG8gdmFsaWRhdGUuXG4gICAqIEBwYXJhbSBzY2hlbWEgLSBUaGUgSlNPTiBTY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW9uLlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSB2YWxpZGF0aW9uIGZhaWxzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB2YWxpZGF0ZShkYXRhOiB1bmtub3duLCBzY2hlbWE6IEpTT05TY2hlbWFUeXBlKTogdm9pZCB7XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy52YWxpZGF0b3IudmFsaWRhdGUoZGF0YSwgc2NoZW1hKTtcbiAgICBpZiAoIXJlc3VsdC52YWxpZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBWYWxpZGF0aW9uIGZhaWxlZDogJHtyZXN1bHQuZXJyb3JzLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhIEpTT04gU2NoZW1hIGZvciB0aGUgZ2l2ZW4gZGF0YS5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgZGF0YSBmb3Igd2hpY2ggdG8gZ2VuZXJhdGUgYSBKU09OIFNjaGVtYS5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBHZW5lcmF0aW9uIG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIFRoZSBnZW5lcmF0ZWQgSlNPTiBTY2hlbWEuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdlbmVyYXRlKGRhdGE6IHVua25vd24sIG9wdGlvbnM6IEpzb25TY2hlbWFHZW5lcmF0b3JPcHRpb25zID0ge30pOiBKU09OU2NoZW1hVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGRTY2hlbWEoZGF0YSwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyDilIDilIDilIAgUFJJVkFURSBIRUxQRVJTIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBwcmltaXRpdmUgdHlwZSBvZiBhIHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBkYXRhIHdob3NlIHR5cGUgaXMgdG8gYmUgaW5mZXJyZWQuXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdHlwZS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGluZmVyVHlwZShkYXRhOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkgcmV0dXJuICdhcnJheSc7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JykgcmV0dXJuICdvYmplY3QnO1xuICAgIHJldHVybiB0eXBlb2YgZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWN1cnNpdmVseSBidWlsZHMgYSBKU09OIFNjaGVtYSBmcm9tIHRoZSBwcm92aWRlZCBkYXRhLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBkYXRhIHRvIGludGVycHJldC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBHZW5lcmF0aW9uIG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIEEgSlNPTiBTY2hlbWEgb2JqZWN0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgYnVpbGRTY2hlbWEoZGF0YTogdW5rbm93biwgb3B0aW9uczogSnNvblNjaGVtYUdlbmVyYXRvck9wdGlvbnMpOiBKU09OU2NoZW1hVHlwZSB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuaW5mZXJUeXBlKGRhdGEpO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnbnVsbCc6XG4gICAgICAgIHJldHVybiB7IHR5cGU6ICdudWxsJyB9O1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEFycmF5U2NoZW1hKGRhdGEgYXMgdW5rbm93bltdLCBvcHRpb25zKTtcbiAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkT2JqZWN0U2NoZW1hKGRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG9wdGlvbnMpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHsgdHlwZSB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYWxsIHR5cGVzIGluIGFuIGFycmF5IGFyZSBvbmUgb2YgdGhlIHByaW1pdGl2ZSB0eXBlczpcbiAgICogc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4uXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlcyAtIEFuIGFycmF5IG9mIHR5cGUgc3RyaW5ncy5cbiAgICogQHJldHVybnMgVHJ1ZSBpZiBldmVyeSB0eXBlIGlzIHByaW1pdGl2ZS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGFsbFR5cGVzQXJlUHJpbWl0aXZlKHR5cGVzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eXBlcy5ldmVyeSgodHlwZSkgPT4gWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXS5pbmNsdWRlcyh0eXBlKSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGEgSlNPTiBTY2hlbWEgZm9yIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBhcnJheSBkYXRhLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEdlbmVyYXRpb24gb3B0aW9ucy5cbiAgICogQHJldHVybnMgVGhlIEpTT04gU2NoZW1hIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGFycmF5IGRhdGEuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBidWlsZEFycmF5U2NoZW1hKFxuICAgIGRhdGE6IHVua25vd25bXSxcbiAgICBvcHRpb25zOiBKc29uU2NoZW1hR2VuZXJhdG9yT3B0aW9ucyxcbiAgKTogSlNPTlNjaGVtYVR5cGUge1xuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ2FycmF5JywgaXRlbXM6IHsgdHlwZTogJ2FueScgfSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGVzID0gZGF0YS5tYXAodGhpcy5pbmZlclR5cGUpO1xuICAgIGlmICh0aGlzLmFsbFR5cGVzQXJlUHJpbWl0aXZlKHR5cGVzKSkge1xuICAgICAgY29uc3QgdW5pcXVlVHlwZXMgPSBBcnJheS5mcm9tKG5ldyBTZXQodHlwZXMpKTtcbiAgICAgIGlmICh1bmlxdWVUeXBlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiB1bmlxdWVUeXBlc1swXSxcbiAgICAgICAgICAgIC4uLih1bmlxdWVUeXBlc1swXSA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5kZXRlY3RFbnVtc1xuICAgICAgICAgICAgICA/IHsgZW51bTogQXJyYXkuZnJvbShuZXcgU2V0KGRhdGEpKSB9XG4gICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4geyB0eXBlOiAnYXJyYXknLCBpdGVtczogeyB0eXBlOiB1bmlxdWVUeXBlcyB9IH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYnVpbGRNaXhlZEFycmF5U2NoZW1hKGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhIEpTT04gU2NoZW1hIGZvciBhbiBhcnJheSBjb250YWluaW5nIG1peGVkIHR5cGVzLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBhcnJheSBkYXRhLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEdlbmVyYXRpb24gb3B0aW9ucy5cbiAgICogQHJldHVybnMgVGhlIEpTT04gU2NoZW1hIHdpdGggYW4gXCJhbnlPZlwiIGNsYXVzZS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGJ1aWxkTWl4ZWRBcnJheVNjaGVtYShcbiAgICBkYXRhOiB1bmtub3duW10sXG4gICAgb3B0aW9uczogSnNvblNjaGVtYUdlbmVyYXRvck9wdGlvbnMsXG4gICk6IEpTT05TY2hlbWFUeXBlIHtcbiAgICBjb25zdCBzY2hlbWFzID0gZGF0YS5tYXAoKGl0ZW0pID0+IHRoaXMuYnVpbGRTY2hlbWEoaXRlbSwgb3B0aW9ucykpO1xuICAgIGNvbnN0IHVuaXF1ZVNjaGVtYXMgPSB0aGlzLm1lcmdlU2ltaWxhclNjaGVtYXMoc2NoZW1hcyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBpdGVtczogdW5pcXVlU2NoZW1hcy5sZW5ndGggPT09IDEgPyB1bmlxdWVTY2hlbWFzWzBdIDogeyBhbnlPZjogdW5pcXVlU2NoZW1hcyB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGEgSlNPTiBTY2hlbWEgZm9yIGFuIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgb2JqZWN0IGRhdGEuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gR2VuZXJhdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBUaGUgSlNPTiBTY2hlbWEgZm9yIHRoZSBvYmplY3QuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBidWlsZE9iamVjdFNjaGVtYShcbiAgICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICBvcHRpb25zOiBKc29uU2NoZW1hR2VuZXJhdG9yT3B0aW9ucyxcbiAgKTogSlNPTlNjaGVtYVR5cGUge1xuICAgIGNvbnN0IHByb3BlcnRpZXM6IHsgW2tleTogc3RyaW5nXTogSlNPTlNjaGVtYVR5cGUgfSA9IHt9O1xuICAgIGNvbnN0IHJlcXVpcmVkOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHsgcmVxdWlyZUFsbCA9IGZhbHNlIH0gPSBvcHRpb25zO1xuXG4gICAgT2JqZWN0LmVudHJpZXMoZGF0YSkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBwcm9wZXJ0aWVzW2tleV0gPSB0aGlzLmJ1aWxkU2NoZW1hKHZhbHVlLCBvcHRpb25zKTtcbiAgICAgIGlmIChyZXF1aXJlQWxsKSByZXF1aXJlZC5wdXNoKGtleSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzLFxuICAgICAgLi4uKHJlcXVpcmVkLmxlbmd0aCA+IDAgPyB7IHJlcXVpcmVkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0cyB0byBtZXJnZSB0d28gSlNPTiBTY2hlbWFzLiBNZXJnaW5nIGlzIG9ubHkgc3VjY2Vzc2Z1bCBpZiBib3RoIHNjaGVtYXMgaGF2ZSB0aGUgc2FtZSB0eXBlXG4gICAqIGFuZCB0aGVyZSBhcmUgbm8gY29uZmxpY3RzIHdpdGhpbiBkZWZpbmVkIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEBwYXJhbSBzY2hlbWFBIC0gVGhlIGZpcnN0IEpTT04gU2NoZW1hLlxuICAgKiBAcGFyYW0gc2NoZW1hQiAtIFRoZSBzZWNvbmQgSlNPTiBTY2hlbWEuXG4gICAqIEByZXR1cm5zIFRoZSBtZXJnZWQgc2NoZW1hIGlmIHN1Y2Nlc3NmdWw7IG90aGVyd2lzZSwgbnVsbC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIG1lcmdlVHdvU2NoZW1hcyhcbiAgICBzY2hlbWFBOiBKU09OU2NoZW1hVHlwZSxcbiAgICBzY2hlbWFCOiBKU09OU2NoZW1hVHlwZSxcbiAgKTogSlNPTlNjaGVtYVR5cGUgfCBudWxsIHtcbiAgICBpZiAoc2NoZW1hQS50eXBlICE9PSBzY2hlbWFCLnR5cGUpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgcHJvcHNBID0gc2NoZW1hQS5wcm9wZXJ0aWVzIHx8IHt9O1xuICAgIGNvbnN0IHByb3BzQiA9IHNjaGVtYUIucHJvcGVydGllcyB8fCB7fTtcbiAgICBjb25zdCBhbGxLZXlzID0gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi5PYmplY3Qua2V5cyhwcm9wc0EpLCAuLi5PYmplY3Qua2V5cyhwcm9wc0IpXSkpO1xuXG4gICAgY29uc3QgaGFzQ29uZmxpY3QgPSBhbGxLZXlzLnNvbWUoXG4gICAgICAoa2V5KSA9PlxuICAgICAgICBrZXkgaW4gcHJvcHNBICYmXG4gICAgICAgIGtleSBpbiBwcm9wc0IgJiZcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocHJvcHNBW2tleV0pICE9PSBKU09OLnN0cmluZ2lmeShwcm9wc0Jba2V5XSksXG4gICAgKTtcbiAgICBpZiAoaGFzQ29uZmxpY3QpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgbWVyZ2VkUHJvcGVydGllcyA9IGFsbEtleXMucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgYWNjW2tleV0gPSBwcm9wc0Fba2V5XSB8fCBwcm9wc0Jba2V5XTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgeyBba2V5OiBzdHJpbmddOiBKU09OU2NoZW1hVHlwZSB9KTtcblxuICAgIC8vIEEgcHJvcGVydHkgaXMgcmVxdWlyZWQgaW4gdGhlIG1lcmdlZCBzY2hlbWEgb25seSBpZiBpdCB3YXMgcmVxdWlyZWQgaW4gYm90aC5cbiAgICBjb25zdCByZXF1aXJlZEEgPSBuZXcgU2V0KHNjaGVtYUEucmVxdWlyZWQgfHwgW10pO1xuICAgIGNvbnN0IHJlcXVpcmVkTWVyZ2VkID0gKHNjaGVtYUIucmVxdWlyZWQgfHwgW10pLmZpbHRlcigoZmllbGQpID0+IHJlcXVpcmVkQS5oYXMoZmllbGQpKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5zY2hlbWFBLFxuICAgICAgLi4uc2NoZW1hQixcbiAgICAgIHR5cGU6IHNjaGVtYUEudHlwZSxcbiAgICAgIC4uLihPYmplY3Qua2V5cyhtZXJnZWRQcm9wZXJ0aWVzKS5sZW5ndGggPiAwID8geyBwcm9wZXJ0aWVzOiBtZXJnZWRQcm9wZXJ0aWVzIH0gOiB7fSksXG4gICAgICAuLi4ocmVxdWlyZWRNZXJnZWQubGVuZ3RoID4gMCA/IHsgcmVxdWlyZWQ6IHJlcXVpcmVkTWVyZ2VkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgYW4gYXJyYXkgb2YgSlNPTiBTY2hlbWFzLiBTY2hlbWFzIHdpdGggdGhlIHNhbWUgdHlwZSBhbmQgbm9uLWNvbmZsaWN0aW5nXG4gICAqIGRlZmluaXRpb25zIGFyZSBtZXJnZWQgdG9nZXRoZXIuXG4gICAqXG4gICAqIEBwYXJhbSBzY2hlbWFzIC0gVGhlIGxpc3Qgb2Ygc2NoZW1hcyB0byBtZXJnZS5cbiAgICogQHJldHVybnMgQSBkZWR1cGxpY2F0ZWQgbGlzdCBvZiBtZXJnZWQgc2NoZW1hcy5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIG1lcmdlU2ltaWxhclNjaGVtYXMoc2NoZW1hczogSlNPTlNjaGVtYVR5cGVbXSk6IEpTT05TY2hlbWFUeXBlW10ge1xuICAgIGlmIChzY2hlbWFzLmxlbmd0aCA8PSAxKSByZXR1cm4gWy4uLnNjaGVtYXNdO1xuXG4gICAgbGV0IG1lcmdlZFNjaGVtYXMgPSBbLi4uc2NoZW1hc107XG5cbiAgICAvLyBBdHRlbXB0IG9uZSBtZXJnZSBwYXNzXG4gICAgY29uc3QgYXR0ZW1wdE1lcmdlID0gKFxuICAgICAgc2NoZW1hc0xpc3Q6IEpTT05TY2hlbWFUeXBlW10sXG4gICAgKTogeyBzY2hlbWFzOiBKU09OU2NoZW1hVHlwZVtdOyBtZXJnZWQ6IGJvb2xlYW4gfSA9PiB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjaGVtYXNMaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHNjaGVtYXNMaXN0Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgbWVyZ2VkID0gdGhpcy5tZXJnZVR3b1NjaGVtYXMoc2NoZW1hc0xpc3RbaV0sIHNjaGVtYXNMaXN0W2pdKTtcbiAgICAgICAgICBpZiAobWVyZ2VkKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTY2hlbWFzID0gW1xuICAgICAgICAgICAgICAuLi5zY2hlbWFzTGlzdC5zbGljZSgwLCBpKSxcbiAgICAgICAgICAgICAgbWVyZ2VkLFxuICAgICAgICAgICAgICAuLi5zY2hlbWFzTGlzdC5zbGljZShpICsgMSwgaiksXG4gICAgICAgICAgICAgIC4uLnNjaGVtYXNMaXN0LnNsaWNlKGogKyAxKSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICByZXR1cm4geyBzY2hlbWFzOiBuZXdTY2hlbWFzLCBtZXJnZWQ6IHRydWUgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7IHNjaGVtYXM6IHNjaGVtYXNMaXN0LCBtZXJnZWQ6IGZhbHNlIH07XG4gICAgfTtcblxuICAgIGxldCByZXN1bHQgPSBhdHRlbXB0TWVyZ2UobWVyZ2VkU2NoZW1hcyk7XG4gICAgd2hpbGUgKHJlc3VsdC5tZXJnZWQpIHtcbiAgICAgIG1lcmdlZFNjaGVtYXMgPSByZXN1bHQuc2NoZW1hcztcbiAgICAgIHJlc3VsdCA9IGF0dGVtcHRNZXJnZShtZXJnZWRTY2hlbWFzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWVyZ2VkU2NoZW1hcztcbiAgfVxufVxuIl19