UNPKG

@rudderstack/integrations-lib

Version:
218 lines 27.6 kB
"use strict"; 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