UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

196 lines 27.3 kB
import { describe, it, expect, beforeEach, vi } from 'vitest'; import { throwWebSocketError, WebSocketErrors, isWebSocketError, extractWebSocketErrorInfo, } from './websocket'; import { throwError, extractErrorMessage, createErrorContext } from './error'; vi.mock('./error', () => ({ throwError: vi.fn(), extractErrorMessage: vi.fn(error => error.message || 'Unknown error'), createErrorContext: vi.fn(context => ({ ...context, timestamp: 'mock-timestamp', })), })); describe('WebSocket Error Utilities', () => { beforeEach(() => { vi.clearAllMocks(); }); describe('throwWebSocketError', () => { it('should call throwError with correct parameters including context', () => { const context = { connectionId: 'conn-123' }; throwWebSocketError(400, 'BAD_REQUEST', 'Invalid request', context); expect(createErrorContext).toHaveBeenCalledWith({ ...context, statusCode: 400, code: 'BAD_REQUEST', originalError: undefined, }); expect(throwError).toHaveBeenCalledWith('Invalid request', { ...context, statusCode: 400, code: 'BAD_REQUEST', originalError: undefined, timestamp: 'mock-timestamp', }); }); it('should handle originalError correctly', () => { const originalError = new Error('Original cause'); const context = { connectionId: 'conn-456', originalError, }; throwWebSocketError(500, 'INTERNAL_SERVER_ERROR', 'Server failure', context); expect(createErrorContext).toHaveBeenCalledWith({ connectionId: 'conn-456', statusCode: 500, code: 'INTERNAL_SERVER_ERROR', originalError, }); expect(throwError).toHaveBeenCalledWith('Server failure', { connectionId: 'conn-456', statusCode: 500, code: 'INTERNAL_SERVER_ERROR', originalError, timestamp: 'mock-timestamp', }); }); it('should function without a context object', () => { throwWebSocketError(401, 'AUTHENTICATION_ERROR', 'Unauthorized'); expect(createErrorContext).toHaveBeenCalledWith({ statusCode: 401, code: 'AUTHENTICATION_ERROR', originalError: undefined, }); expect(throwError).toHaveBeenCalledWith('Unauthorized', { statusCode: 401, code: 'AUTHENTICATION_ERROR', originalError: undefined, timestamp: 'mock-timestamp', }); }); }); describe('WebSocketErrors', () => { const testCases = [ { name: 'validation', statusCode: 400, code: 'VALIDATION_ERROR' }, { name: 'authentication', statusCode: 401, code: 'AUTHENTICATION_ERROR' }, { name: 'authorization', statusCode: 403, code: 'AUTHORIZATION_ERROR' }, { name: 'connection', statusCode: 400, code: 'CONNECTION_ERROR' }, { name: 'messageTooLarge', statusCode: 413, code: 'MESSAGE_TOO_LARGE' }, { name: 'rateLimitExceeded', statusCode: 429, code: 'RATE_LIMIT_EXCEEDED', }, { name: 'badRequest', statusCode: 400, code: 'BAD_REQUEST' }, { name: 'serviceUnavailable', statusCode: 503, code: 'SERVICE_UNAVAILABLE', }, ]; for (const { name, statusCode, code } of testCases) { it(`WebSocketErrors.${name} should call throwError with correct parameters`, () => { const message = `${name} error message`; const context = { connectionId: 'test-conn-id' }; const originalError = new Error('Original test error'); WebSocketErrors[name](message, context, originalError); expect(throwError).toHaveBeenCalledWith(message, { statusCode, code, ...context, originalError, timestamp: 'mock-timestamp', }); }); } }); describe('isWebSocketError', () => { it('should return true for a valid WebSocketError object', () => { const error = { name: 'WebSocketError', message: 'A test error', statusCode: 400, code: 'BAD_REQUEST', context: { connectionId: '123' }, }; // The type guard relies on `instanceof Error` which may not work for plain objects. // We simulate an error object. const errorObject = Object.assign(new Error('A test error'), error); expect(isWebSocketError(errorObject)).toBe(true); }); it('should return false for a plain Error object', () => { const error = new Error('Plain error'); expect(isWebSocketError(error)).toBe(false); }); it('should return false if statusCode is missing', () => { const error = Object.assign(new Error(), { code: 'BAD_REQUEST', context: {}, }); expect(isWebSocketError(error)).toBe(false); }); it('should return false if code is not a string', () => { const error = Object.assign(new Error(), { statusCode: 400, code: 123, context: {}, }); expect(isWebSocketError(error)).toBe(false); }); it('should return false if context is missing', () => { const error = Object.assign(new Error(), { statusCode: 400, code: 'BAD_REQUEST', }); expect(isWebSocketError(error)).toBe(false); }); it('should return false for null or undefined', () => { expect(isWebSocketError(null)).toBe(false); expect(isWebSocketError(undefined)).toBe(false); }); }); describe('extractWebSocketErrorInfo', () => { it('should extract information from a valid WebSocketError', () => { const error = { name: 'Error', message: 'Detailed error message', statusCode: 403, code: 'AUTHORIZATION_ERROR', context: { connectionId: 'conn-789' }, }; extractErrorMessage.mockReturnValue('Detailed error message'); const result = extractWebSocketErrorInfo(error); expect(result).toEqual({ statusCode: 403, code: 'AUTHORIZATION_ERROR', message: 'Detailed error message', context: { connectionId: 'conn-789' }, }); }); it('should provide fallbacks for missing statusCode and code', () => { const malformedError = { name: 'Error', message: 'An incomplete error', }; // Cast to test fallback logic extractErrorMessage.mockReturnValue('An incomplete error'); const result = extractWebSocketErrorInfo(malformedError); expect(result).toEqual({ statusCode: 500, code: 'INTERNAL_SERVER_ERROR', message: 'An incomplete error', context: undefined, }); }); it('should extract message using extractErrorMessage', () => { const error = { name: 'Error', message: 'Original message', statusCode: 400, code: 'BAD_REQUEST', }; extractErrorMessage.mockReturnValue('Extracted message'); const result = extractWebSocketErrorInfo(error); expect(result.message).toBe('Extracted message'); expect(extractErrorMessage).toHaveBeenCalledWith(error); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9lcnJvci93ZWJzb2NrZXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBYSxNQUFNLFFBQVEsQ0FBQztBQUN6RSxPQUFPLEVBRUwsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIseUJBQXlCLEdBRzFCLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUN4QixVQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNuQixtQkFBbUIsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxlQUFlLENBQUM7SUFDckUsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEMsR0FBRyxPQUFPO1FBQ1YsU0FBUyxFQUFFLGdCQUFnQjtLQUM1QixDQUFDLENBQUM7Q0FDSixDQUFDLENBQUMsQ0FBQztBQUVKLFFBQVEsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7SUFDekMsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNyQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxHQUFHLEVBQUU7UUFDbkMsRUFBRSxDQUFDLGtFQUFrRSxFQUFFLEdBQUcsRUFBRTtZQUMxRSxNQUFNLE9BQU8sR0FBMEIsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFF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LENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkZXNjcmliZSwgaXQsIGV4cGVjdCwgYmVmb3JlRWFjaCwgdmksIHR5cGUgTW9jayB9IGZyb20gJ3ZpdGVzdCc7XG5pbXBvcnQge1xuICBXZWJTb2NrZXRFcnJvckNvZGVzLFxuICB0aHJvd1dlYlNvY2tldEVycm9yLFxuICBXZWJTb2NrZXRFcnJvcnMsXG4gIGlzV2ViU29ja2V0RXJyb3IsXG4gIGV4dHJhY3RXZWJTb2NrZXRFcnJvckluZm8sXG4gIHR5cGUgV2ViU29ja2V0RXJyb3IsXG4gIHR5cGUgV2ViU29ja2V0RXJyb3JDb250ZXh0LFxufSBmcm9tICcuL3dlYnNvY2tldCc7XG5pbXBvcnQgeyB0aHJvd0Vycm9yLCBleHRyYWN0RXJyb3JNZXNzYWdlLCBjcmVhdGVFcnJvckNvbnRleHQgfSBmcm9tICcuL2Vycm9yJztcblxudmkubW9jaygnLi9lcnJvcicsICgpID0+ICh7XG4gIHRocm93RXJyb3I6IHZpLmZuKCksXG4gIGV4dHJhY3RFcnJvck1lc3NhZ2U6IHZpLmZuKGVycm9yID0+IGVycm9yLm1lc3NhZ2UgfHwgJ1Vua25vd24gZXJyb3InKSxcbiAgY3JlYXRlRXJyb3JDb250ZXh0OiB2aS5mbihjb250ZXh0ID0+ICh7XG4gICAgLi4uY29udGV4dCxcbiAgICB0aW1lc3RhbXA6ICdtb2NrLXRpbWVzdGFtcCcsXG4gIH0pKSxcbn0pKTtcblxuZGVzY3JpYmUoJ1dlYlNvY2tldCBFcnJvciBVdGlsaXRpZXMnLCAoKSA9PiB7XG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIHZpLmNsZWFyQWxsTW9ja3MoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Rocm93V2ViU29ja2V0RXJyb3InLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIHRocm93RXJyb3Igd2l0aCBjb3JyZWN0IHBhcmFtZXRlcnMgaW5jbHVkaW5nIGNvbnRleHQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb250ZXh0OiBXZWJTb2NrZXRFcnJvckNvbnRleHQgPSB7IGNvbm5lY3Rpb25JZDogJ2Nvbm4tMTIzJyB9O1xuICAgICAgdGhyb3dXZWJTb2NrZXRFcnJvcig0MDAsICdCQURfUkVRVUVTVCcsICdJbnZhbGlkIHJlcXVlc3QnLCBjb250ZXh0KTtcblxuICAgICAgZXhwZWN0KGNyZWF0ZUVycm9yQ29udGV4dCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgICAuLi5jb250ZXh0LFxuICAgICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICAgIGNvZGU6ICdCQURfUkVRVUVTVCcsXG4gICAgICAgIG9yaWdpbmFsRXJyb3I6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QodGhyb3dFcnJvcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ0ludmFsaWQgcmVxdWVzdCcsIHtcbiAgICAgICAgLi4uY29udGV4dCxcbiAgICAgICAgc3RhdHVzQ29kZTogNDAwLFxuICAgICAgICBjb2RlOiAnQkFEX1JFUVVFU1QnLFxuICAgICAgICBvcmlnaW5hbEVycm9yOiB1bmRlZmluZWQsXG4gICAgICAgIHRpbWVzdGFtcDogJ21vY2stdGltZXN0YW1wJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgb3JpZ2luYWxFcnJvciBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbEVycm9yID0gbmV3IEVycm9yKCdPcmlnaW5hbCBjYXVzZScpO1xuICAgICAgY29uc3QgY29udGV4dDogV2ViU29ja2V0RXJyb3JDb250ZXh0ID0ge1xuICAgICAgICBjb25uZWN0aW9uSWQ6ICdjb25uLTQ1NicsXG4gICAgICAgIG9yaWdpbmFsRXJyb3IsXG4gICAgICB9O1xuICAgICAgdGhyb3dXZWJTb2NrZXRFcnJvcihcbiAgICAgICAgNTAwLFxuICAgICAgICAnSU5URVJOQUxfU0VSVkVSX0VSUk9SJyxcbiAgICAgICAgJ1NlcnZlciBmYWlsdXJlJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjcmVhdGVFcnJvckNvbnRleHQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgICAgY29ubmVjdGlvbklkOiAnY29ubi00NTYnLFxuICAgICAgICBzdGF0dXNDb2RlOiA1MDAsXG4gICAgICAgIGNvZGU6ICdJTlRFUk5BTF9TRVJWRVJfRVJST1InLFxuICAgICAgICBvcmlnaW5hbEVycm9yLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdCh0aHJvd0Vycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnU2VydmVyIGZhaWx1cmUnLCB7XG4gICAgICAgIGNvbm5lY3Rpb25JZDogJ2Nvbm4tNDU2JyxcbiAgICAgICAgc3RhdHVzQ29kZTogNTAwLFxuICAgICAgICBjb2RlOiAnSU5URVJOQUxfU0VSVkVSX0VSUk9SJyxcbiAgICAgICAgb3JpZ2luYWxFcnJvcixcbiAgICAgICAgdGltZXN0YW1wOiAnbW9jay10aW1lc3RhbXAnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZ1bmN0aW9uIHdpdGhvdXQgYSBjb250ZXh0IG9iamVjdCcsICgpID0+IHtcbiAgICAgIHRocm93V2ViU29ja2V0RXJyb3IoNDAxLCAnQVVUSEVOVElDQVRJT05fRVJST1InLCAnVW5hdXRob3JpemVkJyk7XG5cbiAgICAgIGV4cGVjdChjcmVhdGVFcnJvckNvbnRleHQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgICAgc3RhdHVzQ29kZTogNDAxLFxuICAgICAgICBjb2RlOiAnQVVUSEVOVElDQVRJT05fRVJST1InLFxuICAgICAgICBvcmlnaW5hbEVycm9yOiB1bmRlZmluZWQsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHRocm93RXJyb3IpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdVbmF1dGhvcml6ZWQnLCB7XG4gICAgICAgIHN0YXR1c0NvZGU6IDQwMSxcbiAgICAgICAgY29kZTogJ0FVVEhFTlRJQ0FUSU9OX0VSUk9SJyxcbiAgICAgICAgb3JpZ2luYWxFcnJvcjogdW5kZWZpbmVkLFxuICAgICAgICB0aW1lc3RhbXA6ICdtb2NrLXRpbWVzdGFtcCcsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1dlYlNvY2tldEVycm9ycycsICgpID0+IHtcbiAgICBjb25zdCB0ZXN0Q2FzZXM6IHtcbiAgICAgIG5hbWU6IGtleW9mIHR5cGVvZiBXZWJTb2NrZXRFcnJvcnM7XG4gICAgICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gICAgICBjb2RlOiBrZXlvZiB0eXBlb2YgV2ViU29ja2V0RXJyb3JDb2RlcztcbiAgICB9W10gPSBbXG4gICAgICB7IG5hbWU6ICd2YWxpZGF0aW9uJywgc3RhdHVzQ29kZTogNDAwLCBjb2RlOiAnVkFMSURBVElPTl9FUlJPUicgfSxcbiAgICAgIHsgbmFtZTogJ2F1dGhlbnRpY2F0aW9uJywgc3RhdHVzQ29kZTogNDAxLCBjb2RlOiAnQVVUSEVOVElDQVRJT05fRVJST1InIH0sXG4gICAgICB7IG5hbWU6ICdhdXRob3JpemF0aW9uJywgc3RhdHVzQ29kZTogNDAzLCBjb2RlOiAnQVVUSE9SSVpBVElPTl9FUlJPUicgfSxcbiAgICAgIHsgbmFtZTogJ2Nvbm5lY3Rpb24nLCBzdGF0dXNDb2RlOiA0MDAsIGNvZGU6ICdDT05ORUNUSU9OX0VSUk9SJyB9LFxuICAgICAgeyBuYW1lOiAnbWVzc2FnZVRvb0xhcmdlJywgc3RhdHVzQ29kZTogNDEzLCBjb2RlOiAnTUVTU0FHRV9UT09fTEFSR0UnIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdyYXRlTGltaXRFeGNlZWRlZCcsXG4gICAgICAgIHN0YXR1c0NvZGU6IDQyOSxcbiAgICAgICAgY29kZTogJ1JBVEVfTElNSVRfRVhDRUVERUQnLFxuICAgICAgfSxcbiAgICAgIHsgbmFtZTogJ2JhZFJlcXVlc3QnLCBzdGF0dXNDb2RlOiA0MDAsIGNvZGU6ICdCQURfUkVRVUVTVCcgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3NlcnZpY2VVbmF2YWlsYWJsZScsXG4gICAgICAgIHN0YXR1c0NvZGU6IDUwMyxcbiAgICAgICAgY29kZTogJ1NFUlZJQ0VfVU5BVkFJTEFCTEUnLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgZm9yIChjb25zdCB7IG5hbWUsIHN0YXR1c0NvZGUsIGNvZGUgfSBvZiB0ZXN0Q2FzZXMpIHtcbiAgICAgIGl0KGBXZWJTb2NrZXRFcnJvcnMuJHtuYW1lfSBzaG91bGQgY2FsbCB0aHJvd0Vycm9yIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzYCwgKCkgPT4ge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gYCR7bmFtZX0gZXJyb3IgbWVzc2FnZWA7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB7IGNvbm5lY3Rpb25JZDogJ3Rlc3QtY29ubi1pZCcgfTtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxFcnJvciA9IG5ldyBFcnJvcignT3JpZ2luYWwgdGVzdCBlcnJvcicpO1xuXG4gICAgICAgIFdlYlNvY2tldEVycm9yc1tuYW1lXShtZXNzYWdlLCBjb250ZXh0LCBvcmlnaW5hbEVycm9yKTtcblxuICAgICAgICBleHBlY3QodGhyb3dFcnJvcikudG9IYXZlQmVlbkNhbGxlZFdpdGgobWVzc2FnZSwge1xuICAgICAgICAgIHN0YXR1c0NvZGUsXG4gICAgICAgICAgY29kZSxcbiAgICAgICAgICAuLi5jb250ZXh0LFxuICAgICAgICAgIG9yaWdpbmFsRXJyb3IsXG4gICAgICAgICAgdGltZXN0YW1wOiAnbW9jay10aW1lc3RhbXAnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzV2ViU29ja2V0RXJyb3InLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYSB2YWxpZCBXZWJTb2NrZXRFcnJvciBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBlcnJvcjogV2ViU29ja2V0RXJyb3IgPSB7XG4gICAgICAgIG5hbWU6ICdXZWJTb2NrZXRFcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6ICdBIHRlc3QgZXJyb3InLFxuICAgICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICAgIGNvZGU6ICdCQURfUkVRVUVTVCcsXG4gICAgICAgIGNvbnRleHQ6IHsgY29ubmVjdGlvbklkOiAnMTIzJyB9LFxuICAgICAgfTtcbiAgICAgIC8vIFRoZSB0eXBlIGd1YXJkIHJlbGllcyBvbiBgaW5zdGFuY2VvZiBFcnJvcmAgd2hpY2ggbWF5IG5vdCB3b3JrIGZvciBwbGFpbiBvYmplY3RzLlxuICAgICAgLy8gV2Ugc2ltdWxhdGUgYW4gZXJyb3Igb2JqZWN0LlxuICAgICAgY29uc3QgZXJyb3JPYmplY3QgPSBPYmplY3QuYXNzaWduKG5ldyBFcnJvcignQSB0ZXN0IGVycm9yJyksIGVycm9yKTtcbiAgICAgIGV4cGVjdChpc1dlYlNvY2tldEVycm9yKGVycm9yT2JqZWN0KSkudG9CZSh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhIHBsYWluIEVycm9yIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCdQbGFpbiBlcnJvcicpO1xuICAgICAgZXhwZWN0KGlzV2ViU29ja2V0RXJyb3IoZXJyb3IpKS50b0JlKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGlmIHN0YXR1c0NvZGUgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yID0gT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoKSwge1xuICAgICAgICBjb2RlOiAnQkFEX1JFUVVFU1QnLFxuICAgICAgICBjb250ZXh0OiB7fSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGlzV2ViU29ja2V0RXJyb3IoZXJyb3IpKS50b0JlKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGlmIGNvZGUgaXMgbm90IGEgc3RyaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgZXJyb3IgPSBPYmplY3QuYXNzaWduKG5ldyBFcnJvcigpLCB7XG4gICAgICAgIHN0YXR1c0NvZGU6IDQwMCxcbiAgICAgICAgY29kZTogMTIzLFxuICAgICAgICBjb250ZXh0OiB7fSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGlzV2ViU29ja2V0RXJyb3IoZXJyb3IpKS50b0JlKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGlmIGNvbnRleHQgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yID0gT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoKSwge1xuICAgICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICAgIGNvZGU6ICdCQURfUkVRVUVTVCcsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChpc1dlYlNvY2tldEVycm9yKGVycm9yKSkudG9CZShmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgbnVsbCBvciB1bmRlZmluZWQnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoaXNXZWJTb2NrZXRFcnJvcihudWxsKSkudG9CZShmYWxzZSk7XG4gICAgICBleHBlY3QoaXNXZWJTb2NrZXRFcnJvcih1bmRlZmluZWQpKS50b0JlKGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2V4dHJhY3RXZWJTb2NrZXRFcnJvckluZm8nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHRyYWN0IGluZm9ybWF0aW9uIGZyb20gYSB2YWxpZCBXZWJTb2NrZXRFcnJvcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yOiBXZWJTb2NrZXRFcnJvciA9IHtcbiAgICAgICAgbmFtZTogJ0Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogJ0RldGFpbGVkIGVycm9yIG1lc3NhZ2UnLFxuICAgICAgICBzdGF0dXNDb2RlOiA0MDMsXG4gICAgICAgIGNvZGU6ICdBVVRIT1JJWkFUSU9OX0VSUk9SJyxcbiAgICAgICAgY29udGV4dDogeyBjb25uZWN0aW9uSWQ6ICdjb25uLTc4OScgfSxcbiAgICAgIH07XG4gICAgICAoZXh0cmFjdEVycm9yTWVzc2FnZSBhcyBNb2NrKS5tb2NrUmV0dXJuVmFsdWUoJ0RldGFpbGVkIGVycm9yIG1lc3NhZ2UnKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdFdlYlNvY2tldEVycm9ySW5mbyhlcnJvcik7XG5cbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoe1xuICAgICAgICBzdGF0dXNDb2RlOiA0MDMsXG4gICAgICAgIGNvZGU6ICdBVVRIT1JJWkFUSU9OX0VSUk9SJyxcbiAgICAgICAgbWVzc2FnZTogJ0RldGFpbGVkIGVycm9yIG1lc3NhZ2UnLFxuICAgICAgICBjb250ZXh0OiB7IGNvbm5lY3Rpb25JZDogJ2Nvbm4tNzg5JyB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3ZpZGUgZmFsbGJhY2tzIGZvciBtaXNzaW5nIHN0YXR1c0NvZGUgYW5kIGNvZGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtYWxmb3JtZWRFcnJvciA9IHtcbiAgICAgICAgbmFtZTogJ0Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogJ0FuIGluY29tcGxldGUgZXJyb3InLFxuICAgICAgfSBhcyBXZWJTb2NrZXRFcnJvcjsgLy8gQ2FzdCB0byB0ZXN0IGZhbGxiYWNrIGxvZ2ljXG4gICAgICAoZXh0cmFjdEVycm9yTWVzc2FnZSBhcyBNb2NrKS5tb2NrUmV0dXJuVmFsdWUoJ0FuIGluY29tcGxldGUgZXJyb3InKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdFdlYlNvY2tldEVycm9ySW5mbyhtYWxmb3JtZWRFcnJvcik7XG5cbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoe1xuICAgICAgICBzdGF0dXNDb2RlOiA1MDAsXG4gICAgICAgIGNvZGU6ICdJTlRFUk5BTF9TRVJWRVJfRVJST1InLFxuICAgICAgICBtZXNzYWdlOiAnQW4gaW5jb21wbGV0ZSBlcnJvcicsXG4gICAgICAgIGNvbnRleHQ6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHRyYWN0IG1lc3NhZ2UgdXNpbmcgZXh0cmFjdEVycm9yTWVzc2FnZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGVycm9yOiBXZWJTb2NrZXRFcnJvciA9IHtcbiAgICAgICAgbmFtZTogJ0Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogJ09yaWdpbmFsIG1lc3NhZ2UnLFxuICAgICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICAgIGNvZGU6ICdCQURfUkVRVUVTVCcsXG4gICAgICB9O1xuICAgICAgKGV4dHJhY3RFcnJvck1lc3NhZ2UgYXMgTW9jaykubW9ja1JldHVyblZhbHVlKCdFeHRyYWN0ZWQgbWVzc2FnZScpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0V2ViU29ja2V0RXJyb3JJbmZvKGVycm9yKTtcbiAgICAgIGV4cGVjdChyZXN1bHQubWVzc2FnZSkudG9CZSgnRXh0cmFjdGVkIG1lc3NhZ2UnKTtcbiAgICAgIGV4cGVjdChleHRyYWN0RXJyb3JNZXNzYWdlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=