@energica-city/shared-amplify-utils
Version:
Shared utilities for AWS Amplify projects
362 lines • 41.7 kB
JavaScript
import { describe, it, expect } from 'vitest';
import { sanitizeObject } from './sanitization';
describe('Sanitization Utility', () => {
describe('sanitizeObject', () => {
describe('primitive values', () => {
it('should return primitive values unchanged', () => {
expect(sanitizeObject('test string')).toBe('test string');
expect(sanitizeObject(123)).toBe(123);
expect(sanitizeObject(true)).toBe(true);
expect(sanitizeObject(false)).toBe(false);
});
it('should handle null and undefined', () => {
expect(sanitizeObject(null)).toBe(null);
expect(sanitizeObject(undefined)).toBe(undefined);
});
});
describe('sensitive field detection', () => {
it('should redact password fields', () => {
const input = {
username: 'testuser',
password: 'secret123',
email: 'test@example.com',
};
const expected = {
username: 'testuser',
password: '[REDACTED]',
email: 'test@example.com',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should redact token fields', () => {
const input = {
accessToken: 'abc123',
refreshToken: 'def456',
userToken: 'ghi789',
};
const expected = {
accessToken: '[REDACTED]',
refreshToken: '[REDACTED]',
userToken: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should redact secret fields', () => {
const input = {
apiSecret: 'secret123',
clientSecret: 'secret456',
secretKey: 'secret789',
};
const expected = {
apiSecret: '[REDACTED]',
clientSecret: '[REDACTED]',
secretKey: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should redact key fields', () => {
const input = {
apiKey: 'key123',
privateKey: 'key456',
encryptionKey: 'key789',
};
const expected = {
apiKey: '[REDACTED]',
privateKey: '[REDACTED]',
encryptionKey: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should redact auth fields', () => {
const input = {
authorization: 'Bearer token123',
authHeader: 'Basic dXNlcjpwYXNz',
authToken: 'token456',
};
const expected = {
authorization: '[REDACTED]',
authHeader: '[REDACTED]',
authToken: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should handle case-insensitive field detection', () => {
const input = {
PASSWORD: 'secret123',
AccessToken: 'token123',
API_SECRET: 'secret456',
private_key: 'key123',
Authorization: 'Bearer token',
};
const expected = {
PASSWORD: '[REDACTED]',
AccessToken: '[REDACTED]',
API_SECRET: '[REDACTED]',
private_key: '[REDACTED]',
Authorization: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
});
describe('excludeFields configuration', () => {
it('should redact explicitly excluded fields', () => {
const input = {
username: 'testuser',
email: 'test@example.com',
phone: '123-456-7890',
};
const config = {
excludeFields: ['email', 'phone'],
};
const expected = {
username: 'testuser',
email: '[REDACTED]',
phone: '[REDACTED]',
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
it('should combine excludeFields with sensitive field detection', () => {
const input = {
username: 'testuser',
password: 'secret123',
email: 'test@example.com',
phone: '123-456-7890',
};
const config = {
excludeFields: ['email'],
};
const expected = {
username: 'testuser',
password: '[REDACTED]',
email: '[REDACTED]',
phone: '123-456-7890',
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
});
describe('maxDepth configuration', () => {
it('should respect maxDepth limit', () => {
const input = {
level1: {
level2: {
level3: {
level4: 'too deep',
},
},
},
};
const config = {
maxDepth: 2,
};
const expected = {
level1: {
level2: '[Object: max depth reached]',
},
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
it('should use default maxDepth of 3', () => {
const input = {
level1: {
level2: {
level3: {
level4: 'too deep',
},
},
},
};
const expected = {
level1: {
level2: {
level3: '[Object: max depth reached]',
},
},
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should handle maxDepth of 0', () => {
const input = {
level1: {
level2: 'nested',
},
};
const config = {
maxDepth: 0,
};
const expected = '[Object: max depth reached]';
expect(sanitizeObject(input, config)).toBe(expected);
});
});
describe('array handling', () => {
it('should sanitize array elements', () => {
const input = [
{ username: 'user1', password: 'pass1' },
{ username: 'user2', password: 'pass2' },
];
const expected = [
{ username: 'user1', password: '[REDACTED]' },
{ username: 'user2', password: '[REDACTED]' },
];
expect(sanitizeObject(input)).toEqual(expected);
});
it('should handle nested arrays with depth limits', () => {
const input = {
users: [
{
profile: {
details: {
secret: 'hidden',
},
},
},
],
};
const config = {
maxDepth: 2,
};
const expected = {
users: ['[Object: max depth reached]'],
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
it('should handle mixed array content', () => {
const input = ['string', 123, { password: 'secret' }, [1, 2, 3]];
const expected = ['string', 123, { password: '[REDACTED]' }, [1, 2, 3]];
expect(sanitizeObject(input)).toEqual(expected);
});
});
describe('complex nested structures', () => {
it('should handle deeply nested objects with sensitive data', () => {
const input = {
user: {
profile: {
personal: {
email: 'test@example.com',
password: 'secret123',
},
preferences: {
theme: 'dark',
},
},
tokens: {
access: 'token123',
refresh: 'token456',
},
},
};
const expected = {
user: {
profile: {
personal: '[Object: max depth reached]',
preferences: '[Object: max depth reached]',
},
tokens: '[REDACTED]',
},
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should handle objects with non-sensitive nested fields', () => {
const input = {
request: {
headers: {
'content-type': 'application/json',
authorization: 'Bearer token123',
},
body: {
data: {
name: 'John Doe',
age: 30,
},
},
},
};
const expected = {
request: {
headers: {
'content-type': '[Object: max depth reached]',
authorization: '[REDACTED]',
},
body: {
data: '[Object: max depth reached]',
},
},
};
expect(sanitizeObject(input)).toEqual(expected);
});
});
describe('edge cases', () => {
it('should handle empty objects', () => {
expect(sanitizeObject({})).toEqual({});
});
it('should handle empty arrays', () => {
expect(sanitizeObject([])).toEqual([]);
});
it('should handle objects with only sensitive fields', () => {
const input = {
password: 'secret123',
token: 'abc123',
};
const expected = {
password: '[REDACTED]',
token: '[REDACTED]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
it('should handle objects with only excluded fields', () => {
const input = {
email: 'test@example.com',
phone: '123-456-7890',
};
const config = {
excludeFields: ['email', 'phone'],
};
const expected = {
email: '[REDACTED]',
phone: '[REDACTED]',
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
it('should handle unknown types', () => {
const input = {
func: () => 'test',
symbol: Symbol('test'),
};
const expected = {
func: '[Unknown type]',
symbol: '[Unknown type]',
};
expect(sanitizeObject(input)).toEqual(expected);
});
});
describe('configuration combinations', () => {
it('should handle all configuration options together', () => {
const input = {
user: {
profile: {
email: 'test@example.com',
password: 'secret123',
phone: '123-456-7890',
details: {
address: {
street: '123 Main St',
city: 'Anytown',
},
},
},
},
};
const config = {
excludeFields: ['phone'],
maxDepth: 2,
};
const expected = {
user: {
profile: '[Object: max depth reached]',
},
};
expect(sanitizeObject(input, config)).toEqual(expected);
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuaXRpemF0aW9uLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9taWRkbGV3YXJlL3V0aWxzL3Nhbml0aXphdGlvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUEyQixNQUFNLGdCQUFnQixDQUFDO0FBRXpFLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxHQUFHLEVBQUU7SUFDcEMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtRQUM5QixRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO1lBQ2hDLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xELE1BQU0sQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQzFELE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO2dCQUMxQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3BELENBQUMs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dUI7b0JBQ2pDLGFBQWEsRUFBRSxDQUFDLE9BQU8sQ0FBQztvQkFDeEIsUUFBUSxFQUFFLENBQUM7aUJBQ1osQ0FBQztnQkFDRixNQUFNLFFBQVEsR0FBRztvQkFDZixJQUFJLEVBQUU7d0JBQ0osT0FBTyxFQUFFLDZCQUE2QjtxQkFDdkM7aUJBQ0YsQ0FBQztnQkFDRixNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBpdCwgZXhwZWN0IH0gZnJvbSAndml0ZXN0JztcbmltcG9ydCB7IHNhbml0aXplT2JqZWN0LCB0eXBlIFNhbml0aXphdGlvbkNvbmZpZyB9IGZyb20gJy4vc2FuaXRpemF0aW9uJztcblxuZGVzY3JpYmUoJ1Nhbml0aXphdGlvbiBVdGlsaXR5JywgKCkgPT4ge1xuICBkZXNjcmliZSgnc2FuaXRpemVPYmplY3QnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ3ByaW1pdGl2ZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBwcmltaXRpdmUgdmFsdWVzIHVuY2hhbmdlZCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KCd0ZXN0IHN0cmluZycpKS50b0JlKCd0ZXN0IHN0cmluZycpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoMTIzKSkudG9CZSgxMjMpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QodHJ1ZSkpLnRvQmUodHJ1ZSk7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChmYWxzZSkpLnRvQmUoZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG51bGwgYW5kIHVuZGVmaW5lZCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KG51bGwpKS50b0JlKG51bGwpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QodW5kZWZpbmVkKSkudG9CZSh1bmRlZmluZWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2Vuc2l0aXZlIGZpZWxkIGRldGVjdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IHBhc3N3b3JkIGZpZWxkcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcm5hbWU6ICd0ZXN0dXNlcicsXG4gICAgICAgICAgcGFzc3dvcmQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgIGVtYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXJuYW1lOiAndGVzdHVzZXInLFxuICAgICAgICAgIHBhc3N3b3JkOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgZW1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWRhY3QgdG9rZW4gZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ2FiYzEyMycsXG4gICAgICAgICAgcmVmcmVzaFRva2VuOiAnZGVmNDU2JyxcbiAgICAgICAgICB1c2VyVG9rZW46ICdnaGk3ODknLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHJlZnJlc2hUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHVzZXJUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlZGFjdCBzZWNyZXQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhcGlTZWNyZXQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgIGNsaWVudFNlY3JldDogJ3NlY3JldDQ1NicsXG4gICAgICAgICAgc2VjcmV0S2V5OiAnc2VjcmV0Nzg5JyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgYXBpU2VjcmV0OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgY2xpZW50U2VjcmV0OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgc2VjcmV0S2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGtleSBmaWVsZHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIGFwaUtleTogJ2tleTEyMycsXG4gICAgICAgICAgcHJpdmF0ZUtleTogJ2tleTQ1NicsXG4gICAgICAgICAgZW5jcnlwdGlvbktleTogJ2tleTc4OScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGFwaUtleTogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHByaXZhdGVLZXk6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBlbmNyeXB0aW9uS2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGF1dGggZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiAnQmVhcmVyIHRva2VuMTIzJyxcbiAgICAgICAgICBhdXRoSGVhZGVyOiAnQmFzaWMgZFhObGNqcHdZWE56JyxcbiAgICAgICAgICBhdXRoVG9rZW46ICd0b2tlbjQ1NicsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBhdXRoSGVhZGVyOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgYXV0aFRva2VuOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGNhc2UtaW5zZW5zaXRpdmUgZmllbGQgZGV0ZWN0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBQQVNTV09SRDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgQWNjZXNzVG9rZW46ICd0b2tlbjEyMycsXG4gICAgICAgICAgQVBJX1NFQ1JFVDogJ3NlY3JldDQ1NicsXG4gICAgICAgICAgcHJpdmF0ZV9rZXk6ICdrZXkxMjMnLFxuICAgICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgdG9rZW4nLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBQQVNTV09SRDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIEFjY2Vzc1Rva2VuOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgQVBJX1NFQ1JFVDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHByaXZhdGVfa2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgQXV0aG9yaXphdGlvbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2V4Y2x1ZGVGaWVsZHMgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGV4cGxpY2l0bHkgZXhjbHVkZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgZXhjbHVkZUZpZWxkczogWydlbWFpbCcsICdwaG9uZSddLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjb21iaW5lIGV4Y2x1ZGVGaWVsZHMgd2l0aCBzZW5zaXRpdmUgZmllbGQgZGV0ZWN0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBwYXNzd29yZDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgZW1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwaG9uZTogJzEyMy00NTYtNzg5MCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNvbmZpZzogU2FuaXRpemF0aW9uQ29uZmlnID0ge1xuICAgICAgICAgIGV4Y2x1ZGVGaWVsZHM6IFsnZW1haWwnXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgdXNlcm5hbWU6ICd0ZXN0dXNlcicsXG4gICAgICAgICAgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0LCBjb25maWcpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ21heERlcHRoIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHJlc3BlY3QgbWF4RGVwdGggbGltaXQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIGxldmVsMToge1xuICAgICAgICAgICAgbGV2ZWwyOiB7XG4gICAgICAgICAgICAgIGxldmVsMzoge1xuICAgICAgICAgICAgICAgIGxldmVsNDogJ3RvbyBkZWVwJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGxldmVsMToge1xuICAgICAgICAgICAgbGV2ZWwyOiAnW09iamVjdDogbWF4IGRlcHRoIHJlYWNoZWRdJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQsIGNvbmZpZykpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgbWF4RGVwdGggb2YgMycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgbGV2ZWwxOiB7XG4gICAgICAgICAgICBsZXZlbDI6IHtcbiAgICAgICAgICAgICAgbGV2ZWwzOiB7XG4gICAgICAgICAgICAgICAgbGV2ZWw0OiAndG9vIGRlZXAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBsZXZlbDE6IHtcbiAgICAgICAgICAgIGxldmVsMjoge1xuICAgICAgICAgICAgICBsZXZlbDM6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBtYXhEZXB0aCBvZiAwJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBsZXZlbDE6IHtcbiAgICAgICAgICAgIGxldmVsMjogJ25lc3RlZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDAsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXSc7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9CZShleHBlY3RlZCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdhcnJheSBoYW5kbGluZycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgc2FuaXRpemUgYXJyYXkgZWxlbWVudHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gW1xuICAgICAgICAgIHsgdXNlcm5hbWU6ICd1c2VyMScsIHBhc3N3b3JkOiAncGFzczEnIH0sXG4gICAgICAgICAgeyB1c2VybmFtZTogJ3VzZXIyJywgcGFzc3dvcmQ6ICdwYXNzMicgfSxcbiAgICAgICAgXTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSBbXG4gICAgICAgICAgeyB1c2VybmFtZTogJ3VzZXIxJywgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyB9LFxuICAgICAgICAgIHsgdXNlcm5hbWU6ICd1c2VyMicsIHBhc3N3b3JkOiAnW1JFREFDVEVEXScgfSxcbiAgICAgICAgXTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbmVzdGVkIGFycmF5cyB3aXRoIGRlcHRoIGxpbWl0cycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgICAgIHNlY3JldDogJ2hpZGRlbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXJzOiBbJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXSddLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQsIGNvbmZpZykpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG1peGVkIGFycmF5IGNvbnRlbnQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gWydzdHJpbmcnLCAxMjMsIHsgcGFzc3dvcmQ6ICdzZWNyZXQnIH0sIFsxLCAyLCAzXV07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gWydzdHJpbmcnLCAxMjMsIHsgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyB9LCBbMSwgMiwgM11dO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbXBsZXggbmVzdGVkIHN0cnVjdHVyZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBkZWVwbHkgbmVzdGVkIG9iamVjdHMgd2l0aCBzZW5zaXRpdmUgZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBwZXJzb25hbDoge1xuICAgICAgICAgICAgICAgIGVtYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICAgICAgcGFzc3dvcmQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwcmVmZXJlbmNlczoge1xuICAgICAgICAgICAgICAgIHRoZW1lOiAnZGFyaycsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9rZW5zOiB7XG4gICAgICAgICAgICAgIGFjY2VzczogJ3Rva2VuMTIzJyxcbiAgICAgICAgICAgICAgcmVmcmVzaDogJ3Rva2VuNDU2JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBwZXJzb25hbDogJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXScsXG4gICAgICAgICAgICAgIHByZWZlcmVuY2VzOiAnW09iamVjdDogbWF4IGRlcHRoIHJlYWNoZWRdJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b2tlbnM6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBvYmplY3RzIHdpdGggbm9uLXNlbnNpdGl2ZSBuZXN0ZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICByZXF1ZXN0OiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgIGF1dGhvcml6YXRpb246ICdCZWFyZXIgdG9rZW4xMjMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IHtcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIG5hbWU6ICdKb2huIERvZScsXG4gICAgICAgICAgICAgICAgYWdlOiAzMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgcmVxdWVzdDoge1xuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnY29udGVudC10eXBlJzogJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXScsXG4gICAgICAgICAgICAgIGF1dGhvcml6YXRpb246ICdbUkVEQUNURURdJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIGRhdGE6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2VkZ2UgY2FzZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBvYmplY3RzJywgKCkgPT4ge1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3Qoe30pKS50b0VxdWFsKHt9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBhcnJheXMnLCAoKSA9PiB7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChbXSkpLnRvRXF1YWwoW10pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG9iamVjdHMgd2l0aCBvbmx5IHNlbnNpdGl2ZSBmaWVsZHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIHBhc3N3b3JkOiAnc2VjcmV0MTIzJyxcbiAgICAgICAgICB0b2tlbjogJ2FiYzEyMycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHBhc3N3b3JkOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgdG9rZW46ICdbUkVEQUNURURdJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgb2JqZWN0cyB3aXRoIG9ubHkgZXhjbHVkZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgZXhjbHVkZUZpZWxkczogWydlbWFpbCcsICdwaG9uZSddLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgdW5rbm93biB0eXBlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgZnVuYzogKCkgPT4gJ3Rlc3QnLFxuICAgICAgICAgIHN5bWJvbDogU3ltYm9sKCd0ZXN0JyksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGZ1bmM6ICdbVW5rbm93biB0eXBlXScsXG4gICAgICAgICAgc3ltYm9sOiAnW1Vua25vd24gdHlwZV0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbmZpZ3VyYXRpb24gY29tYmluYXRpb25zJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYWxsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0b2dldGhlcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgICAgICBwYXNzd29yZDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgICAgICAgICAgIHN0cmVldDogJzEyMyBNYWluIFN0JyxcbiAgICAgICAgICAgICAgICAgIGNpdHk6ICdBbnl0b3duJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjb25maWc6IFNhbml0aXphdGlvbkNvbmZpZyA9IHtcbiAgICAgICAgICBleGNsdWRlRmllbGRzOiBbJ3Bob25lJ10sXG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXI6IHtcbiAgICAgICAgICAgIHByb2ZpbGU6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==