@mecanizou/telemetry-hub 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.github/workflows/pull_request.yml +32 -32
  2. package/.github/workflows/release.yml +129 -129
  3. package/.prettierignore +4 -4
  4. package/CHANGELOG.md +36 -14
  5. package/DOCS_GUIDE.md +151 -151
  6. package/README.md +248 -248
  7. package/dist/core/__tests__/logger-types.test.js +1 -1
  8. package/dist/core/__tests__/logger.test.js +1 -1
  9. package/dist/core/__tests__/tracer.test.js +1 -1
  10. package/dist/core/index.js +1 -1
  11. package/dist/core/logger-types.js +1 -1
  12. package/dist/core/logger.js +1 -1
  13. package/dist/core/tracer-types.js +1 -1
  14. package/dist/core/tracer.js +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/sst/__tests__/telemetry.test.js +1 -1
  17. package/dist/sst/index.js +1 -1
  18. package/dist/sst/middy/index.js +1 -1
  19. package/dist/sst/middy/middleware.js +1 -1
  20. package/dist/sst/telemetry.js +1 -1
  21. package/dist/tsed/__tests__/config.test.js +1 -1
  22. package/dist/tsed/__tests__/service.test.js +1 -1
  23. package/dist/tsed/config.js +1 -1
  24. package/dist/tsed/index.js +1 -1
  25. package/dist/tsed/log-telemetry.js +1 -1
  26. package/dist/tsed/service.js +1 -1
  27. package/dist/tsed/sync-log-record-processor.js +1 -1
  28. package/package.json +72 -72
  29. package/release.config.js +23 -23
  30. package/vitest.config.ts +22 -22
  31. package/dist/telemetry/core/__tests__/logger-types.test.d.ts +0 -1
  32. package/dist/telemetry/core/__tests__/logger-types.test.js +0 -325
  33. package/dist/telemetry/core/__tests__/logger.test.d.ts +0 -1
  34. package/dist/telemetry/core/__tests__/logger.test.js +0 -337
  35. package/dist/telemetry/core/__tests__/tracer.test.d.ts +0 -1
  36. package/dist/telemetry/core/__tests__/tracer.test.js +0 -330
  37. package/dist/telemetry/core/index.d.ts +0 -4
  38. package/dist/telemetry/core/index.js +0 -8
  39. package/dist/telemetry/core/logger-types.d.ts +0 -43
  40. package/dist/telemetry/core/logger-types.js +0 -3
  41. package/dist/telemetry/core/logger.d.ts +0 -13
  42. package/dist/telemetry/core/logger.js +0 -123
  43. package/dist/telemetry/core/tracer-types.d.ts +0 -50
  44. package/dist/telemetry/core/tracer-types.js +0 -3
  45. package/dist/telemetry/core/tracer.d.ts +0 -10
  46. package/dist/telemetry/core/tracer.js +0 -114
  47. package/dist/telemetry/index.d.ts +0 -3
  48. package/dist/telemetry/index.js +0 -20
  49. package/dist/telemetry/sst/__tests__/telemetry.test.d.ts +0 -1
  50. package/dist/telemetry/sst/__tests__/telemetry.test.js +0 -138
  51. package/dist/telemetry/sst/index.d.ts +0 -1
  52. package/dist/telemetry/sst/index.js +0 -18
  53. package/dist/telemetry/sst/middy/index.d.ts +0 -1
  54. package/dist/telemetry/sst/middy/index.js +0 -18
  55. package/dist/telemetry/sst/middy/middleware.d.ts +0 -5
  56. package/dist/telemetry/sst/middy/middleware.js +0 -157
  57. package/dist/telemetry/sst/telemetry.d.ts +0 -4
  58. package/dist/telemetry/sst/telemetry.js +0 -121
  59. package/dist/telemetry/tsed/__tests__/config.test.d.ts +0 -1
  60. package/dist/telemetry/tsed/__tests__/config.test.js +0 -146
  61. package/dist/telemetry/tsed/__tests__/service.test.d.ts +0 -1
  62. package/dist/telemetry/tsed/__tests__/service.test.js +0 -63
  63. package/dist/telemetry/tsed/config.d.ts +0 -26
  64. package/dist/telemetry/tsed/config.js +0 -166
  65. package/dist/telemetry/tsed/index.d.ts +0 -4
  66. package/dist/telemetry/tsed/index.js +0 -21
  67. package/dist/telemetry/tsed/log-telemetry.d.ts +0 -1
  68. package/dist/telemetry/tsed/log-telemetry.js +0 -196
  69. package/dist/telemetry/tsed/service.d.ts +0 -26
  70. package/dist/telemetry/tsed/service.js +0 -150
  71. package/dist/telemetry/tsed/sync-log-record-processor.d.ts +0 -11
  72. package/dist/telemetry/tsed/sync-log-record-processor.js +0 -74
@@ -1,330 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const tracer_1 = require("../tracer");
5
- const api_1 = require("@opentelemetry/api");
6
- (0, vitest_1.describe)('StandardTracer', () => {
7
- let mockTracer;
8
- let mockSpan;
9
- let standardTracer;
10
- (0, vitest_1.beforeEach)(() => {
11
- mockSpan = {
12
- end: vitest_1.vi.fn(),
13
- setAttribute: vitest_1.vi.fn(),
14
- setStatus: vitest_1.vi.fn(),
15
- recordException: vitest_1.vi.fn(),
16
- };
17
- mockTracer = {
18
- startSpan: vitest_1.vi.fn().mockReturnValue(mockSpan),
19
- };
20
- standardTracer = new tracer_1.StandardTracer(mockTracer, 'test-service');
21
- });
22
- (0, vitest_1.describe)('startSpan', () => {
23
- (0, vitest_1.it)('deve criar span com nome e atributos básicos', () => {
24
- const spanResult = standardTracer.startSpan({
25
- spanName: 'test-operation',
26
- serviceName: 'my-service',
27
- environment: 'production',
28
- });
29
- (0, vitest_1.expect)(mockTracer.startSpan).toHaveBeenCalledWith('test-operation', {
30
- kind: api_1.SpanKind.SERVER,
31
- attributes: {
32
- 'service.name': 'my-service',
33
- 'deployment.environment.name': 'production',
34
- },
35
- });
36
- (0, vitest_1.expect)(spanResult.span).toBe(mockSpan);
37
- (0, vitest_1.expect)(spanResult.end).toBeDefined();
38
- (0, vitest_1.expect)(spanResult.setSuccess).toBeDefined();
39
- (0, vitest_1.expect)(spanResult.setError).toBeDefined();
40
- (0, vitest_1.expect)(spanResult.setAttribute).toBeDefined();
41
- });
42
- (0, vitest_1.it)('deve usar defaultServiceName quando serviceName não fornecido', () => {
43
- standardTracer.startSpan({
44
- spanName: 'test-operation',
45
- serviceName: '',
46
- environment: 'test',
47
- });
48
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
49
- (0, vitest_1.expect)(attributes['service.name']).toBe('test-service');
50
- });
51
- (0, vitest_1.it)('deve incluir atributos de execução', () => {
52
- standardTracer.startSpan({
53
- spanName: 'process-request',
54
- serviceName: 'api-service',
55
- environment: 'production',
56
- execution: {
57
- functionName: 'processPayment',
58
- invocationId: 'inv-123',
59
- awsRequestId: 'aws-456',
60
- requestId: 'req-789',
61
- controller: 'PaymentController',
62
- controllerMethod: 'process',
63
- origin: 'mobile',
64
- },
65
- });
66
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
67
- (0, vitest_1.expect)(attributes['faas.name']).toBe('processPayment');
68
- (0, vitest_1.expect)(attributes['faas.invocation_id']).toBe('inv-123');
69
- (0, vitest_1.expect)(attributes['aws.request.id']).toBe('aws-456');
70
- (0, vitest_1.expect)(attributes['request.id']).toBe('req-789');
71
- (0, vitest_1.expect)(attributes['controller.name']).toBe('PaymentController');
72
- (0, vitest_1.expect)(attributes['controller.method']).toBe('process');
73
- (0, vitest_1.expect)(attributes['origin']).toBe('mobile');
74
- });
75
- (0, vitest_1.it)('deve incluir atributos HTTP', () => {
76
- standardTracer.startSpan({
77
- spanName: 'http-request',
78
- serviceName: 'web-service',
79
- environment: 'production',
80
- http: {
81
- method: 'POST',
82
- url: 'https://api.example.com/orders',
83
- endpoint: '/orders',
84
- statusCode: 201,
85
- scheme: 'https',
86
- host: 'api.example.com',
87
- },
88
- });
89
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
90
- (0, vitest_1.expect)(attributes['http.method']).toBe('POST');
91
- (0, vitest_1.expect)(attributes['http.url']).toBe('https://api.example.com/orders');
92
- (0, vitest_1.expect)(attributes['http.target']).toBe('/orders');
93
- (0, vitest_1.expect)(attributes['http.status_code']).toBe(201);
94
- (0, vitest_1.expect)(attributes['http.scheme']).toBe('https');
95
- (0, vitest_1.expect)(attributes['http.host']).toBe('api.example.com');
96
- });
97
- (0, vitest_1.it)('deve incluir atributos de usuário', () => {
98
- standardTracer.startSpan({
99
- spanName: 'user-operation',
100
- serviceName: 'user-service',
101
- environment: 'production',
102
- user: {
103
- accountUserUid: 'user-123',
104
- accountUid: 'account-456',
105
- applicationUid: 'app-789',
106
- },
107
- });
108
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
109
- (0, vitest_1.expect)(attributes['accountUser.uid']).toBe('user-123');
110
- (0, vitest_1.expect)(attributes['account.uid']).toBe('account-456');
111
- (0, vitest_1.expect)(attributes['application.uid']).toBe('app-789');
112
- });
113
- (0, vitest_1.it)('deve incluir atributos de performance', () => {
114
- standardTracer.startSpan({
115
- spanName: 'performance-test',
116
- serviceName: 'perf-service',
117
- environment: 'test',
118
- performance: {
119
- durationMs: 250,
120
- success: true,
121
- },
122
- });
123
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
124
- (0, vitest_1.expect)(attributes['duration.ms']).toBe(250);
125
- (0, vitest_1.expect)(attributes['execution.success']).toBe(true);
126
- });
127
- (0, vitest_1.it)('deve incluir atributos de erro', () => {
128
- standardTracer.startSpan({
129
- spanName: 'error-operation',
130
- serviceName: 'error-service',
131
- environment: 'production',
132
- error: {
133
- type: 'ValidationError',
134
- message: 'Invalid input',
135
- stack: 'Error stack trace',
136
- },
137
- });
138
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
139
- (0, vitest_1.expect)(attributes['error.type']).toBe('ValidationError');
140
- (0, vitest_1.expect)(attributes['error.message']).toBe('Invalid input');
141
- (0, vitest_1.expect)(attributes['error.stack']).toBe('Error stack trace');
142
- });
143
- (0, vitest_1.it)('deve incluir atributos customizados', () => {
144
- standardTracer.startSpan({
145
- spanName: 'custom-operation',
146
- serviceName: 'custom-service',
147
- environment: 'production',
148
- attributes: {
149
- 'custom.field': 'value',
150
- 'custom.count': 42,
151
- 'custom.enabled': true,
152
- },
153
- });
154
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
155
- (0, vitest_1.expect)(attributes['custom.field']).toBe('value');
156
- (0, vitest_1.expect)(attributes['custom.count']).toBe(42);
157
- (0, vitest_1.expect)(attributes['custom.enabled']).toBe(true);
158
- });
159
- (0, vitest_1.it)('deve filtrar valores undefined e null', () => {
160
- standardTracer.startSpan({
161
- spanName: 'filter-test',
162
- serviceName: 'filter-service',
163
- environment: 'production',
164
- execution: {
165
- functionName: 'test',
166
- invocationId: undefined,
167
- awsRequestId: null,
168
- },
169
- attributes: {
170
- valid: 'value',
171
- invalid: undefined,
172
- nullValue: null,
173
- },
174
- });
175
- const attributes = mockTracer.startSpan.mock.calls[0][1].attributes;
176
- (0, vitest_1.expect)(attributes['faas.name']).toBe('test');
177
- (0, vitest_1.expect)(attributes['faas.invocation_id']).toBeUndefined();
178
- (0, vitest_1.expect)(attributes['aws.request.id']).toBeUndefined();
179
- (0, vitest_1.expect)(attributes['valid']).toBe('value');
180
- (0, vitest_1.expect)(attributes['invalid']).toBeUndefined();
181
- (0, vitest_1.expect)(attributes['nullValue']).toBeUndefined();
182
- });
183
- });
184
- (0, vitest_1.describe)('StandardSpanResult', () => {
185
- let spanResult;
186
- (0, vitest_1.beforeEach)(() => {
187
- spanResult = standardTracer.startSpan({
188
- spanName: 'test-span',
189
- serviceName: 'test-service',
190
- environment: 'test',
191
- });
192
- });
193
- (0, vitest_1.describe)('end', () => {
194
- (0, vitest_1.it)('deve finalizar o span', () => {
195
- spanResult.end();
196
- (0, vitest_1.expect)(mockSpan.end).toHaveBeenCalledTimes(1);
197
- });
198
- });
199
- (0, vitest_1.describe)('setSuccess', () => {
200
- (0, vitest_1.it)('deve marcar span como sucesso', () => {
201
- spanResult.setSuccess(true);
202
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('execution.success', true);
203
- (0, vitest_1.expect)(mockSpan.setStatus).toHaveBeenCalledWith({
204
- code: api_1.SpanStatusCode.OK,
205
- });
206
- });
207
- (0, vitest_1.it)('deve marcar span como falha', () => {
208
- spanResult.setSuccess(false);
209
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('execution.success', false);
210
- (0, vitest_1.expect)(mockSpan.setStatus).toHaveBeenCalledWith({
211
- code: api_1.SpanStatusCode.ERROR,
212
- });
213
- });
214
- });
215
- (0, vitest_1.describe)('setError', () => {
216
- (0, vitest_1.it)('deve registrar erro no span', () => {
217
- const error = new Error('Test error');
218
- spanResult.setError(error);
219
- (0, vitest_1.expect)(mockSpan.recordException).toHaveBeenCalledWith(error);
220
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.type', 'Error');
221
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.message', 'Test error');
222
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('execution.success', false);
223
- (0, vitest_1.expect)(mockSpan.setStatus).toHaveBeenCalledWith({
224
- code: api_1.SpanStatusCode.ERROR,
225
- message: 'Test error',
226
- });
227
- });
228
- (0, vitest_1.it)('deve incluir stack trace quando disponível', () => {
229
- const error = new Error('Error with stack');
230
- error.stack = 'Error: Error with stack\n at test.ts:1:1';
231
- spanResult.setError(error);
232
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.stack', error.stack);
233
- });
234
- (0, vitest_1.it)('deve funcionar com erro customizado', () => {
235
- class CustomError extends Error {
236
- constructor(message) {
237
- super(message);
238
- this.name = 'CustomError';
239
- }
240
- }
241
- const error = new CustomError('Custom error message');
242
- spanResult.setError(error);
243
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.type', 'CustomError');
244
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.message', 'Custom error message');
245
- });
246
- });
247
- (0, vitest_1.describe)('setAttribute', () => {
248
- (0, vitest_1.it)('deve adicionar atributo string', () => {
249
- spanResult.setAttribute('custom.key', 'custom value');
250
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('custom.key', 'custom value');
251
- });
252
- (0, vitest_1.it)('deve adicionar atributo numérico', () => {
253
- spanResult.setAttribute('custom.count', 123);
254
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('custom.count', 123);
255
- });
256
- (0, vitest_1.it)('deve adicionar atributo booleano', () => {
257
- spanResult.setAttribute('custom.enabled', true);
258
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('custom.enabled', true);
259
- });
260
- });
261
- });
262
- (0, vitest_1.describe)('recordException', () => {
263
- (0, vitest_1.it)('deve registrar exceção com todos os atributos', () => {
264
- const error = new Error('Exception test');
265
- error.stack = 'Error stack trace here';
266
- standardTracer.recordException(mockSpan, error);
267
- (0, vitest_1.expect)(mockSpan.recordException).toHaveBeenCalledWith(error);
268
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.type', 'Error');
269
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.message', 'Exception test');
270
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.stack', 'Error stack trace here');
271
- });
272
- (0, vitest_1.it)('deve funcionar sem stack trace', () => {
273
- const error = new Error('No stack');
274
- delete error.stack;
275
- standardTracer.recordException(mockSpan, error);
276
- (0, vitest_1.expect)(mockSpan.recordException).toHaveBeenCalledWith(error);
277
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.type', 'Error');
278
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('error.message', 'No stack');
279
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledTimes(2);
280
- });
281
- });
282
- (0, vitest_1.describe)('cenários de uso completos', () => {
283
- (0, vitest_1.it)('deve gerenciar fluxo de sucesso completo', () => {
284
- const spanResult = standardTracer.startSpan({
285
- spanName: 'complete-operation',
286
- serviceName: 'complete-service',
287
- environment: 'production',
288
- execution: {
289
- functionName: 'processData',
290
- requestId: 'req-123',
291
- },
292
- http: {
293
- method: 'POST',
294
- endpoint: '/api/data',
295
- },
296
- });
297
- spanResult.setAttribute('custom.step', 'processing');
298
- spanResult.setSuccess(true);
299
- spanResult.end();
300
- (0, vitest_1.expect)(mockTracer.startSpan).toHaveBeenCalled();
301
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('custom.step', 'processing');
302
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('execution.success', true);
303
- (0, vitest_1.expect)(mockSpan.setStatus).toHaveBeenCalledWith({
304
- code: api_1.SpanStatusCode.OK,
305
- });
306
- (0, vitest_1.expect)(mockSpan.end).toHaveBeenCalled();
307
- });
308
- (0, vitest_1.it)('deve gerenciar fluxo de erro completo', () => {
309
- const spanResult = standardTracer.startSpan({
310
- spanName: 'error-operation',
311
- serviceName: 'error-service',
312
- environment: 'production',
313
- user: {
314
- accountUserUid: 'user-123',
315
- },
316
- });
317
- const error = new Error('Operation failed');
318
- spanResult.setError(error);
319
- spanResult.end();
320
- (0, vitest_1.expect)(mockSpan.recordException).toHaveBeenCalledWith(error);
321
- (0, vitest_1.expect)(mockSpan.setAttribute).toHaveBeenCalledWith('execution.success', false);
322
- (0, vitest_1.expect)(mockSpan.setStatus).toHaveBeenCalledWith({
323
- code: api_1.SpanStatusCode.ERROR,
324
- message: 'Operation failed',
325
- });
326
- (0, vitest_1.expect)(mockSpan.end).toHaveBeenCalled();
327
- });
328
- });
329
- });
330
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2VyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdGVsZW1ldHJ5L2NvcmUvX190ZXN0c19fL3RyYWNlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQThEO0FBQzlELHNDQUEyQztBQUMzQyw0Q0FBOEQ7QUFFOUQsSUFBQSxpQkFBUSxFQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixJQUFJLFVBQWUsQ0FBQztJQUNwQixJQUFJLFFBQWEsQ0FBQztJQUNsQixJQUFJLGNBQThCLENBQUM7SUFFbkMsSUFBQSxtQkFBVSxFQUFDLEdBQUcsRUFBRTtRQUNkLFFBQVEsR0FBRztZQUNULEdBQUcsRUFBRSxXQUFFLENBQUMsRUFBRSxFQUFFO1lBQ1osWUFBWSxFQUFFLFdBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDckIsU0FBUyxFQUFFLFdBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbEIsZUFBZSxFQUFFLFdBQUUsQ0FBQyxFQUFFLEVBQUU7U0FDekIsQ0FBQztRQUVGLFVBQVUsR0FBRztZQUNYLFNBQVMsRUFBRSxXQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQztTQUM3QyxDQUFDO1FBRUYsY0FBYyxHQUFHLElBQUksdUJBQWMsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFBLGlCQUFRLEVBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRTtRQUN6QixJQUFBLFdBQUUsRUFBQyw4Q0FBOEMsRUFBRSxHQUFHLEVBQUU7WUFDdEQsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQztnQkFDMUMsUUFBUSxFQUFFLGdCQUFnQjtnQkFDMUIsV0FBVyxFQUFFLFlBQVk7Z0JBQ3pCLFdBQVcsRUFBRSxZQUFZO2FBQzFCLENBQUMsQ0FBQztZQUVILElBQUEsZUFBTSxFQUFDLFVBQVUsQ0FBQyxTQUFT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QUs7Z0JBQzFCLE9BQU8sRUFBRSxrQkFBa0I7YUFDNUIsQ0FBQyxDQUFDO1lBQ0gsSUFBQSxlQUFNLEVBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVzY3JpYmUsIGl0LCBleHBlY3QsIHZpLCBiZWZvcmVFYWNoIH0gZnJvbSAndml0ZXN0JztcclxuaW1wb3J0IHsgU3RhbmRhcmRUcmFjZXIgfSBmcm9tICcuLi90cmFjZXInO1xyXG5pbXBvcnQgeyBTcGFuU3RhdHVzQ29kZSwgU3BhbktpbmQgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xyXG5cclxuZGVzY3JpYmUoJ1N0YW5kYXJkVHJhY2VyJywgKCkgPT4ge1xyXG4gIGxldCBtb2NrVHJhY2VyOiBhbnk7XHJcbiAgbGV0IG1vY2tTcGFuOiBhbnk7XHJcbiAgbGV0IHN0YW5kYXJkVHJhY2VyOiBTdGFuZGFyZFRyYWNlcjtcclxuXHJcbiAgYmVmb3JlRWFjaCgoKSA9PiB7XHJcbiAgICBtb2NrU3BhbiA9IHtcclxuICAgICAgZW5kOiB2aS5mbigpLFxyXG4gICAgICBzZXRBdHRyaWJ1dGU6IHZpLmZuKCksXHJcbiAgICAgIHNldFN0YXR1czogdmkuZm4oKSxcclxuICAgICAgcmVjb3JkRXhjZXB0aW9uOiB2aS5mbigpLFxyXG4gICAgfTtcclxuXHJcbiAgICBtb2NrVHJhY2VyID0ge1xyXG4gICAgICBzdGFydFNwYW46IHZpLmZuKCkubW9ja1JldHVyblZhbHVlKG1vY2tTcGFuKSxcclxuICAgIH07XHJcblxyXG4gICAgc3RhbmRhcmRUcmFjZXIgPSBuZXcgU3RhbmRhcmRUcmFjZXIobW9ja1RyYWNlciwgJ3Rlc3Qtc2VydmljZScpO1xyXG4gIH0pO1xyXG5cclxuICBkZXNjcmliZSgnc3RhcnRTcGFuJywgKCkgPT4ge1xyXG4gICAgaXQoJ2RldmUgY3JpYXIgc3BhbiBjb20gbm9tZSBlIGF0cmlidXRvcyBiw6FzaWNvcycsICgpID0+IHtcclxuICAgICAgY29uc3Qgc3BhblJlc3VsdCA9IHN0YW5kYXJkVHJhY2VyLnN0YXJ0U3Bhbih7XHJcbiAgICAgICAgc3Bhbk5hbWU6ICd0ZXN0LW9wZXJhdGlvbicsXHJcbiAgICAgICAgc2VydmljZU5hbWU6ICdteS1zZXJ2aWNlJyxcclxuICAgICAgICBlbnZpcm9ubWVudDogJ3Byb2R1Y3Rpb24nLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGV4cGVjdChtb2NrVHJhY2VyLnN0YXJ0U3BhbikudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3Rlc3Qtb3BlcmF0aW9uJywge1xyXG4gICAgICAgIGtpbmQ6IFNwYW5LaW5kLlNFUlZFUixcclxuICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAnc2VydmljZS5uYW1lJzogJ215LXNlcnZpY2UnLFxyXG4gICAgICAgICAgJ2RlcGxveW1lbnQuZW52aXJvbm1lbnQubmFtZSc6ICdwcm9kdWN0aW9uJyxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGV4cGVjdChzcGFuUmVzdWx0LnNwYW4pLnRvQmUobW9ja1NwYW4pO1xyXG4gICAgICBleHBlY3Qoc3BhblJlc3VsdC5lbmQpLnRvQmVEZWZpbmVkKCk7XHJcbiAgICAgIGV4cGVjdChzcGFuUmVzdWx0LnNldFN1Y2Nlc3MpLnRvQmVEZWZpbmVkKCk7XHJcbiAgICAgIGV4cGVjdChzcGFuUmVzdWx0LnNldEVycm9yKS50b0JlRGVmaW5lZCgpO1xyXG4gICAgICBleHBlY3Qoc3BhblJlc3VsdC5zZXRBdHRyaWJ1dGUpLnRvQmVEZWZpbmVkKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSB1c2FyIGRlZmF1bHRTZXJ2aWNlTmFtZSBxdWFuZG8gc2VydmljZU5hbWUgbsOjbyBmb3JuZWNpZG8nLCAoKSA9PiB7XHJcbiAgICAgIHN0YW5kYXJkVHJhY2VyLnN0YXJ0U3Bhbih7XHJcbiAgICAgICAgc3Bhbk5hbWU6ICd0ZXN0LW9wZXJhdGlvbicsXHJcbiAgICAgICAgc2VydmljZU5hbWU6ICcnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAndGVzdCcsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IG1vY2tUcmFjZXIuc3RhcnRTcGFuLm1vY2suY2FsbHNbMF1bMV0uYXR0cmlidXRlcztcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ3NlcnZpY2UubmFtZSddKS50b0JlKCd0ZXN0LXNlcnZpY2UnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdkZXZlIGluY2x1aXIgYXRyaWJ1dG9zIGRlIGV4ZWN1w6fDo28nLCAoKSA9PiB7XHJcbiAgICAgIHN0YW5kYXJkVHJhY2VyLnN0YXJ0U3Bhbih7XHJcbiAgICAgICAgc3Bhbk5hbWU6ICdwcm9jZXNzLXJlcXVlc3QnLFxyXG4gICAgICAgIHNlcnZpY2VOYW1lOiAnYXBpLXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAncHJvZHVjdGlvbicsXHJcbiAgICAgICAgZXhlY3V0aW9uOiB7XHJcbiAgICAgICAgICBmdW5jdGlvbk5hbWU6ICdwcm9jZXNzUGF5bWVudCcsXHJcbiAgICAgICAgICBpbnZvY2F0aW9uSWQ6ICdpbnYtMTIzJyxcclxuICAgICAgICAgIGF3c1JlcXVlc3RJZDogJ2F3cy00NTYnLFxyXG4gICAgICAgICAgcmVxdWVzdElkOiAncmVxLTc4OScsXHJcbiAgICAgICAgICBjb250cm9sbGVyOiAnUGF5bWVudENvbnRyb2xsZXInLFxyXG4gICAgICAgICAgY29udHJvbGxlck1ldGhvZDogJ3Byb2Nlc3MnLFxyXG4gICAgICAgICAgb3JpZ2luOiAnbW9iaWxlJyxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBtb2NrVHJhY2VyLnN0YXJ0U3Bhbi5tb2NrLmNhbGxzWzBdWzFdLmF0dHJpYnV0ZXM7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydmYWFzLm5hbWUnXSkudG9CZSgncHJvY2Vzc1BheW1lbnQnKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2ZhYXMuaW52b2NhdGlvbl9pZCddKS50b0JlKCdpbnYtMTIzJyk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydhd3MucmVxdWVzdC5pZCddKS50b0JlKCdhd3MtNDU2Jyk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydyZXF1ZXN0LmlkJ10pLnRvQmUoJ3JlcS03ODknKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2NvbnRyb2xsZXIubmFtZSddKS50b0JlKCdQYXltZW50Q29udHJvbGxlcicpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snY29udHJvbGxlci5tZXRob2QnXSkudG9CZSgncHJvY2VzcycpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snb3JpZ2luJ10pLnRvQmUoJ21vYmlsZScpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ2RldmUgaW5jbHVpciBhdHJpYnV0b3MgSFRUUCcsICgpID0+IHtcclxuICAgICAgc3RhbmRhcmRUcmFjZXIuc3RhcnRTcGFuKHtcclxuICAgICAgICBzcGFuTmFtZTogJ2h0dHAtcmVxdWVzdCcsXHJcbiAgICAgICAgc2VydmljZU5hbWU6ICd3ZWItc2VydmljZScsXHJcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdwcm9kdWN0aW9uJyxcclxuICAgICAgICBodHRwOiB7XHJcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcclxuICAgICAgICAgIHVybDogJ2h0dHBzOi8vYXBpLmV4YW1wbGUuY29tL29yZGVycycsXHJcbiAgICAgICAgICBlbmRwb2ludDogJy9vcmRlcnMnLFxyXG4gICAgICAgICAgc3RhdHVzQ29kZTogMjAxLFxyXG4gICAgICAgICAgc2NoZW1lOiAnaHR0cHMnLFxyXG4gICAgICAgICAgaG9zdDogJ2FwaS5leGFtcGxlLmNvbScsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gbW9ja1RyYWNlci5zdGFydFNwYW4ubW9jay5jYWxsc1swXVsxXS5hdHRyaWJ1dGVzO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snaHR0cC5tZXRob2QnXSkudG9CZSgnUE9TVCcpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snaHR0cC51cmwnXSkudG9CZSgnaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20vb3JkZXJzJyk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydodHRwLnRhcmdldCddKS50b0JlKCcvb3JkZXJzJyk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydodHRwLnN0YXR1c19jb2RlJ10pLnRvQmUoMjAxKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2h0dHAuc2NoZW1lJ10pLnRvQmUoJ2h0dHBzJyk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydodHRwLmhvc3QnXSkudG9CZSgnYXBpLmV4YW1wbGUuY29tJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSBpbmNsdWlyIGF0cmlidXRvcyBkZSB1c3XDoXJpbycsICgpID0+IHtcclxuICAgICAgc3RhbmRhcmRUcmFjZXIuc3RhcnRTcGFuKHtcclxuICAgICAgICBzcGFuTmFtZTogJ3VzZXItb3BlcmF0aW9uJyxcclxuICAgICAgICBzZXJ2aWNlTmFtZTogJ3VzZXItc2VydmljZScsXHJcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdwcm9kdWN0aW9uJyxcclxuICAgICAgICB1c2VyOiB7XHJcbiAgICAgICAgICBhY2NvdW50VXNlclVpZDogJ3VzZXItMTIzJyxcclxuICAgICAgICAgIGFjY291bnRVaWQ6ICdhY2NvdW50LTQ1NicsXHJcbiAgICAgICAgICBhcHBsaWNhdGlvblVpZDogJ2FwcC03ODknLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IG1vY2tUcmFjZXIuc3RhcnRTcGFuLm1vY2suY2FsbHNbMF1bMV0uYXR0cmlidXRlcztcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2FjY291bnRVc2VyLnVpZCddKS50b0JlKCd1c2VyLTEyMycpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snYWNjb3VudC51aWQnXSkudG9CZSgnYWNjb3VudC00NTYnKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2FwcGxpY2F0aW9uLnVpZCddKS50b0JlKCdhcHAtNzg5Jyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSBpbmNsdWlyIGF0cmlidXRvcyBkZSBwZXJmb3JtYW5jZScsICgpID0+IHtcclxuICAgICAgc3RhbmRhcmRUcmFjZXIuc3RhcnRTcGFuKHtcclxuICAgICAgICBzcGFuTmFtZTogJ3BlcmZvcm1hbmNlLXRlc3QnLFxyXG4gICAgICAgIHNlcnZpY2VOYW1lOiAncGVyZi1zZXJ2aWNlJyxcclxuICAgICAgICBlbnZpcm9ubWVudDogJ3Rlc3QnLFxyXG4gICAgICAgIHBlcmZvcm1hbmNlOiB7XHJcbiAgICAgICAgICBkdXJhdGlvbk1zOiAyNTAsXHJcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IG1vY2tUcmFjZXIuc3RhcnRTcGFuLm1vY2suY2FsbHNbMF1bMV0uYXR0cmlidXRlcztcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2R1cmF0aW9uLm1zJ10pLnRvQmUoMjUwKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2V4ZWN1dGlvbi5zdWNjZXNzJ10pLnRvQmUodHJ1ZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSBpbmNsdWlyIGF0cmlidXRvcyBkZSBlcnJvJywgKCkgPT4ge1xyXG4gICAgICBzdGFuZGFyZFRyYWNlci5zdGFydFNwYW4oe1xyXG4gICAgICAgIHNwYW5OYW1lOiAnZXJyb3Itb3BlcmF0aW9uJyxcclxuICAgICAgICBzZXJ2aWNlTmFtZTogJ2Vycm9yLXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAncHJvZHVjdGlvbicsXHJcbiAgICAgICAgZXJyb3I6IHtcclxuICAgICAgICAgIHR5cGU6ICdWYWxpZGF0aW9uRXJyb3InLFxyXG4gICAgICAgICAgbWVzc2FnZTogJ0ludmFsaWQgaW5wdXQnLFxyXG4gICAgICAgICAgc3RhY2s6ICdFcnJvciBzdGFjayB0cmFjZScsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gbW9ja1RyYWNlci5zdGFydFNwYW4ubW9jay5jYWxsc1swXVsxXS5hdHRyaWJ1dGVzO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snZXJyb3IudHlwZSddKS50b0JlKCdWYWxpZGF0aW9uRXJyb3InKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2Vycm9yLm1lc3NhZ2UnXSkudG9CZSgnSW52YWxpZCBpbnB1dCcpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snZXJyb3Iuc3RhY2snXSkudG9CZSgnRXJyb3Igc3RhY2sgdHJhY2UnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdkZXZlIGluY2x1aXIgYXRyaWJ1dG9zIGN1c3RvbWl6YWRvcycsICgpID0+IHtcclxuICAgICAgc3RhbmRhcmRUcmFjZXIuc3RhcnRTcGFuKHtcclxuICAgICAgICBzcGFuTmFtZTogJ2N1c3RvbS1vcGVyYXRpb24nLFxyXG4gICAgICAgIHNlcnZpY2VOYW1lOiAnY3VzdG9tLXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAncHJvZHVjdGlvbicsXHJcbiAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgJ2N1c3RvbS5maWVsZCc6ICd2YWx1ZScsXHJcbiAgICAgICAgICAnY3VzdG9tLmNvdW50JzogNDIsXHJcbiAgICAgICAgICAnY3VzdG9tLmVuYWJsZWQnOiB0cnVlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IG1vY2tUcmFjZXIuc3RhcnRTcGFuLm1vY2suY2FsbHNbMF1bMV0uYXR0cmlidXRlcztcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2N1c3RvbS5maWVsZCddKS50b0JlKCd2YWx1ZScpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snY3VzdG9tLmNvdW50J10pLnRvQmUoNDIpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snY3VzdG9tLmVuYWJsZWQnXSkudG9CZSh0cnVlKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdkZXZlIGZpbHRyYXIgdmFsb3JlcyB1bmRlZmluZWQgZSBudWxsJywgKCkgPT4ge1xyXG4gICAgICBzdGFuZGFyZFRyYWNlci5zdGFydFNwYW4oe1xyXG4gICAgICAgIHNwYW5OYW1lOiAnZmlsdGVyLXRlc3QnLFxyXG4gICAgICAgIHNlcnZpY2VOYW1lOiAnZmlsdGVyLXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAncHJvZHVjdGlvbicsXHJcbiAgICAgICAgZXhlY3V0aW9uOiB7XHJcbiAgICAgICAgICBmdW5jdGlvbk5hbWU6ICd0ZXN0JyxcclxuICAgICAgICAgIGludm9jYXRpb25JZDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgYXdzUmVxdWVzdElkOiBudWxsIGFzIGFueSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgIHZhbGlkOiAndmFsdWUnLFxyXG4gICAgICAgICAgaW52YWxpZDogdW5kZWZpbmVkIGFzIGFueSxcclxuICAgICAgICAgIG51bGxWYWx1ZTogbnVsbCBhcyBhbnksXHJcbiAgICAgICAgfSxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gbW9ja1RyYWNlci5zdGFydFNwYW4ubW9jay5jYWxsc1swXVsxXS5hdHRyaWJ1dGVzO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snZmFhcy5uYW1lJ10pLnRvQmUoJ3Rlc3QnKTtcclxuICAgICAgZXhwZWN0KGF0dHJpYnV0ZXNbJ2ZhYXMuaW52b2NhdGlvbl9pZCddKS50b0JlVW5kZWZpbmVkKCk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydhd3MucmVxdWVzdC5pZCddKS50b0JlVW5kZWZpbmVkKCk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWyd2YWxpZCddKS50b0JlKCd2YWx1ZScpO1xyXG4gICAgICBleHBlY3QoYXR0cmlidXRlc1snaW52YWxpZCddKS50b0JlVW5kZWZpbmVkKCk7XHJcbiAgICAgIGV4cGVjdChhdHRyaWJ1dGVzWydudWxsVmFsdWUnXSkudG9CZVVuZGVmaW5lZCgpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIGRlc2NyaWJlKCdTdGFuZGFyZFNwYW5SZXN1bHQnLCAoKSA9PiB7XHJcbiAgICBsZXQgc3BhblJlc3VsdDogYW55O1xyXG5cclxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xyXG4gICAgICBzcGFuUmVzdWx0ID0gc3RhbmRhcmRUcmFjZXIuc3RhcnRTcGFuKHtcclxuICAgICAgICBzcGFuTmFtZTogJ3Rlc3Qtc3BhbicsXHJcbiAgICAgICAgc2VydmljZU5hbWU6ICd0ZXN0LXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAndGVzdCcsXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZGVzY3JpYmUoJ2VuZCcsICgpID0+IHtcclxuICAgICAgaXQoJ2RldmUgZmluYWxpemFyIG8gc3BhbicsICgpID0+IHtcclxuICAgICAgICBzcGFuUmVzdWx0LmVuZCgpO1xyXG5cclxuICAgICAgICBleHBlY3QobW9ja1NwYW4uZW5kKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZGVzY3JpYmUoJ3NldFN1Y2Nlc3MnLCAoKSA9PiB7XHJcbiAgICAgIGl0KCdkZXZlIG1hcmNhciBzcGFuIGNvbW8gc3VjZXNzbycsICgpID0+IHtcclxuICAgICAgICBzcGFuUmVzdWx0LnNldFN1Y2Nlc3ModHJ1ZSk7XHJcblxyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICAgJ2V4ZWN1dGlvbi5zdWNjZXNzJyxcclxuICAgICAgICAgIHRydWVcclxuICAgICAgICApO1xyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRTdGF0dXMpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcclxuICAgICAgICAgIGNvZGU6IFNwYW5TdGF0dXNDb2RlLk9LLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGl0KCdkZXZlIG1hcmNhciBzcGFuIGNvbW8gZmFsaGEnLCAoKSA9PiB7XHJcbiAgICAgICAgc3BhblJlc3VsdC5zZXRTdWNjZXNzKGZhbHNlKTtcclxuXHJcbiAgICAgICAgZXhwZWN0KG1vY2tTcGFuLnNldEF0dHJpYnV0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgICAnZXhlY3V0aW9uLnN1Y2Nlc3MnLFxyXG4gICAgICAgICAgZmFsc2VcclxuICAgICAgICApO1xyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRTdGF0dXMpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcclxuICAgICAgICAgIGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIGRlc2NyaWJlKCdzZXRFcnJvcicsICgpID0+IHtcclxuICAgICAgaXQoJ2RldmUgcmVnaXN0cmFyIGVycm8gbm8gc3BhbicsICgpID0+IHtcclxuICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignVGVzdCBlcnJvcicpO1xyXG5cclxuICAgICAgICBzcGFuUmVzdWx0LnNldEVycm9yKGVycm9yKTtcclxuXHJcbiAgICAgICAgZXhwZWN0KG1vY2tTcGFuLnJlY29yZEV4Y2VwdGlvbikudG9IYXZlQmVlbkNhbGxlZFdpdGgoZXJyb3IpO1xyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICAgJ2Vycm9yLnR5cGUnLFxyXG4gICAgICAgICAgJ0Vycm9yJ1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgZXhwZWN0KG1vY2tTcGFuLnNldEF0dHJpYnV0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgICAnZXJyb3IubWVzc2FnZScsXHJcbiAgICAgICAgICAnVGVzdCBlcnJvcidcclxuICAgICAgICApO1xyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICAgJ2V4ZWN1dGlvbi5zdWNjZXNzJyxcclxuICAgICAgICAgIGZhbHNlXHJcbiAgICAgICAgKTtcclxuICAgICAgICBleHBlY3QobW9ja1NwYW4uc2V0U3RhdHVzKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XHJcbiAgICAgICAgICBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUixcclxuICAgICAgICAgIG1lc3NhZ2U6ICdUZXN0IGVycm9yJyxcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpdCgnZGV2ZSBpbmNsdWlyIHN0YWNrIHRyYWNlIHF1YW5kbyBkaXNwb27DrXZlbCcsICgpID0+IHtcclxuICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignRXJyb3Igd2l0aCBzdGFjaycpO1xyXG4gICAgICAgIGVycm9yLnN0YWNrID0gJ0Vycm9yOiBFcnJvciB3aXRoIHN0YWNrXFxuICBhdCB0ZXN0LnRzOjE6MSc7XHJcblxyXG4gICAgICAgIHNwYW5SZXN1bHQuc2V0RXJyb3IoZXJyb3IpO1xyXG5cclxuICAgICAgICBleHBlY3QobW9ja1NwYW4uc2V0QXR0cmlidXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICAgICdlcnJvci5zdGFjaycsXHJcbiAgICAgICAgICBlcnJvci5zdGFja1xyXG4gICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaXQoJ2RldmUgZnVuY2lvbmFyIGNvbSBlcnJvIGN1c3RvbWl6YWRvJywgKCkgPT4ge1xyXG4gICAgICAgIGNsYXNzIEN1c3RvbUVycm9yIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLm5hbWUgPSAnQ3VzdG9tRXJyb3InO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgQ3VzdG9tRXJyb3IoJ0N1c3RvbSBlcnJvciBtZXNzYWdlJyk7XHJcblxyXG4gICAgICAgIHNwYW5SZXN1bHQuc2V0RXJyb3IoZXJyb3IpO1xyXG5cclxuICAgICAgICBleHBlY3QobW9ja1NwYW4uc2V0QXR0cmlidXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICAgICdlcnJvci50eXBlJyxcclxuICAgICAgICAgICdDdXN0b21FcnJvcidcclxuICAgICAgICApO1xyXG4gICAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICAgJ2Vycm9yLm1lc3NhZ2UnLFxyXG4gICAgICAgICAgJ0N1c3RvbSBlcnJvciBtZXNzYWdlJ1xyXG4gICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZGVzY3JpYmUoJ3NldEF0dHJpYnV0ZScsICgpID0+IHtcclxuICAgICAgaXQoJ2RldmUgYWRpY2lvbmFyIGF0cmlidXRvIHN0cmluZycsICgpID0+IHtcclxuICAgICAgICBzcGFuUmVzdWx0LnNldEF0dHJpYnV0ZSgnY3VzdG9tLmtleScsICdjdXN0b20gdmFsdWUnKTtcclxuXHJcbiAgICAgICAgZXhwZWN0KG1vY2tTcGFuLnNldEF0dHJpYnV0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgICAnY3VzdG9tLmtleScsXHJcbiAgICAgICAgICAnY3VzdG9tIHZhbHVlJ1xyXG4gICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaXQoJ2RldmUgYWRpY2lvbmFyIGF0cmlidXRvIG51bcOpcmljbycsICgpID0+IHtcclxuICAgICAgICBzcGFuUmVzdWx0LnNldEF0dHJpYnV0ZSgnY3VzdG9tLmNvdW50JywgMTIzKTtcclxuXHJcbiAgICAgICAgZXhwZWN0KG1vY2tTcGFuLnNldEF0dHJpYnV0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ2N1c3RvbS5jb3VudCcsIDEyMyk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaXQoJ2RldmUgYWRpY2lvbmFyIGF0cmlidXRvIGJvb2xlYW5vJywgKCkgPT4ge1xyXG4gICAgICAgIHNwYW5SZXN1bHQuc2V0QXR0cmlidXRlKCdjdXN0b20uZW5hYmxlZCcsIHRydWUpO1xyXG5cclxuICAgICAgICBleHBlY3QobW9ja1NwYW4uc2V0QXR0cmlidXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICAgICdjdXN0b20uZW5hYmxlZCcsXHJcbiAgICAgICAgICB0cnVlXHJcbiAgICAgICAgKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9KTtcclxuXHJcbiAgZGVzY3JpYmUoJ3JlY29yZEV4Y2VwdGlvbicsICgpID0+IHtcclxuICAgIGl0KCdkZXZlIHJlZ2lzdHJhciBleGNlw6fDo28gY29tIHRvZG9zIG9zIGF0cmlidXRvcycsICgpID0+IHtcclxuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoJ0V4Y2VwdGlvbiB0ZXN0Jyk7XHJcbiAgICAgIGVycm9yLnN0YWNrID0gJ0Vycm9yIHN0YWNrIHRyYWNlIGhlcmUnO1xyXG5cclxuICAgICAgc3RhbmRhcmRUcmFjZXIucmVjb3JkRXhjZXB0aW9uKG1vY2tTcGFuLCBlcnJvcik7XHJcblxyXG4gICAgICBleHBlY3QobW9ja1NwYW4ucmVjb3JkRXhjZXB0aW9uKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChlcnJvcik7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdlcnJvci50eXBlJywgJ0Vycm9yJyk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICdlcnJvci5tZXNzYWdlJyxcclxuICAgICAgICAnRXhjZXB0aW9uIHRlc3QnXHJcbiAgICAgICk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICdlcnJvci5zdGFjaycsXHJcbiAgICAgICAgJ0Vycm9yIHN0YWNrIHRyYWNlIGhlcmUnXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSBmdW5jaW9uYXIgc2VtIHN0YWNrIHRyYWNlJywgKCkgPT4ge1xyXG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignTm8gc3RhY2snKTtcclxuICAgICAgZGVsZXRlIGVycm9yLnN0YWNrO1xyXG5cclxuICAgICAgc3RhbmRhcmRUcmFjZXIucmVjb3JkRXhjZXB0aW9uKG1vY2tTcGFuLCBlcnJvcik7XHJcblxyXG4gICAgICBleHBlY3QobW9ja1NwYW4ucmVjb3JkRXhjZXB0aW9uKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChlcnJvcik7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdlcnJvci50eXBlJywgJ0Vycm9yJyk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICdlcnJvci5tZXNzYWdlJyxcclxuICAgICAgICAnTm8gc3RhY2snXHJcbiAgICAgICk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygyKTsgLy8gQXBlbmFzIHR5cGUgZSBtZXNzYWdlXHJcbiAgICB9KTtcclxuICB9KTtcclxuXHJcbiAgZGVzY3JpYmUoJ2NlbsOhcmlvcyBkZSB1c28gY29tcGxldG9zJywgKCkgPT4ge1xyXG4gICAgaXQoJ2RldmUgZ2VyZW5jaWFyIGZsdXhvIGRlIHN1Y2Vzc28gY29tcGxldG8nLCAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IHNwYW5SZXN1bHQgPSBzdGFuZGFyZFRyYWNlci5zdGFydFNwYW4oe1xyXG4gICAgICAgIHNwYW5OYW1lOiAnY29tcGxldGUtb3BlcmF0aW9uJyxcclxuICAgICAgICBzZXJ2aWNlTmFtZTogJ2NvbXBsZXRlLXNlcnZpY2UnLFxyXG4gICAgICAgIGVudmlyb25tZW50OiAncHJvZHVjdGlvbicsXHJcbiAgICAgICAgZXhlY3V0aW9uOiB7XHJcbiAgICAgICAgICBmdW5jdGlvbk5hbWU6ICdwcm9jZXNzRGF0YScsXHJcbiAgICAgICAgICByZXF1ZXN0SWQ6ICdyZXEtMTIzJyxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGh0dHA6IHtcclxuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxyXG4gICAgICAgICAgZW5kcG9pbnQ6ICcvYXBpL2RhdGEnLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc3BhblJlc3VsdC5zZXRBdHRyaWJ1dGUoJ2N1c3RvbS5zdGVwJywgJ3Byb2Nlc3NpbmcnKTtcclxuICAgICAgc3BhblJlc3VsdC5zZXRTdWNjZXNzKHRydWUpO1xyXG4gICAgICBzcGFuUmVzdWx0LmVuZCgpO1xyXG5cclxuICAgICAgZXhwZWN0KG1vY2tUcmFjZXIuc3RhcnRTcGFuKS50b0hhdmVCZWVuQ2FsbGVkKCk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICdjdXN0b20uc3RlcCcsXHJcbiAgICAgICAgJ3Byb2Nlc3NpbmcnXHJcbiAgICAgICk7XHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5zZXRBdHRyaWJ1dGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgICdleGVjdXRpb24uc3VjY2VzcycsXHJcbiAgICAgICAgdHJ1ZVxyXG4gICAgICApO1xyXG4gICAgICBleHBlY3QobW9ja1NwYW4uc2V0U3RhdHVzKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XHJcbiAgICAgICAgY29kZTogU3BhblN0YXR1c0NvZGUuT0ssXHJcbiAgICAgIH0pO1xyXG4gICAgICBleHBlY3QobW9ja1NwYW4uZW5kKS50b0hhdmVCZWVuQ2FsbGVkKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnZGV2ZSBnZXJlbmNpYXIgZmx1eG8gZGUgZXJybyBjb21wbGV0bycsICgpID0+IHtcclxuICAgICAgY29uc3Qgc3BhblJlc3VsdCA9IHN0YW5kYXJkVHJhY2VyLnN0YXJ0U3Bhbih7XHJcbiAgICAgICAgc3Bhbk5hbWU6ICdlcnJvci1vcGVyYXRpb24nLFxyXG4gICAgICAgIHNlcnZpY2VOYW1lOiAnZXJyb3Itc2VydmljZScsXHJcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdwcm9kdWN0aW9uJyxcclxuICAgICAgICB1c2VyOiB7XHJcbiAgICAgICAgICBhY2NvdW50VXNlclVpZDogJ3VzZXItMTIzJyxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCdPcGVyYXRpb24gZmFpbGVkJyk7XHJcblxyXG4gICAgICBzcGFuUmVzdWx0LnNldEVycm9yKGVycm9yKTtcclxuICAgICAgc3BhblJlc3VsdC5lbmQoKTtcclxuXHJcbiAgICAgIGV4cGVjdChtb2NrU3Bhbi5yZWNvcmRFeGNlcHRpb24pLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGVycm9yKTtcclxuICAgICAgZXhwZWN0KG1vY2tTcGFuLnNldEF0dHJpYnV0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgJ2V4ZWN1dGlvbi5zdWNjZXNzJyxcclxuICAgICAgICBmYWxzZVxyXG4gICAgICApO1xyXG4gICAgICBleHBlY3QobW9ja1NwYW4uc2V0U3RhdHVzKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XHJcbiAgICAgICAgY29kZTogU3BhblN0YXR1c0NvZGUuRVJST1IsXHJcbiAgICAgICAgbWVzc2FnZTogJ09wZXJhdGlvbiBmYWlsZWQnLFxyXG4gICAgICB9KTtcclxuICAgICAgZXhwZWN0KG1vY2tTcGFuLmVuZCkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcbn0pO1xyXG4iXX0=
@@ -1,4 +0,0 @@
1
- export { StandardLogger } from './logger';
2
- export { IStandardLogger, StandardLogData } from './logger-types';
3
- export { StandardTracer } from './tracer';
4
- export { IStandardTracer, StandardTraceData, StandardSpanResult, } from './tracer-types';
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StandardTracer = exports.StandardLogger = void 0;
4
- var logger_1 = require("./logger");
5
- Object.defineProperty(exports, "StandardLogger", { enumerable: true, get: function () { return logger_1.StandardLogger; } });
6
- var tracer_1 = require("./tracer");
7
- Object.defineProperty(exports, "StandardTracer", { enumerable: true, get: function () { return tracer_1.StandardTracer; } });
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVsZW1ldHJ5L2NvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQTBDO0FBQWpDLHdHQUFBLGNBQWMsT0FBQTtBQUV2QixtQ0FBMEM7QUFBakMsd0dBQUEsY0FBYyxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgU3RhbmRhcmRMb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XHJcbmV4cG9ydCB7IElTdGFuZGFyZExvZ2dlciwgU3RhbmRhcmRMb2dEYXRhIH0gZnJvbSAnLi9sb2dnZXItdHlwZXMnO1xyXG5leHBvcnQgeyBTdGFuZGFyZFRyYWNlciB9IGZyb20gJy4vdHJhY2VyJztcclxuZXhwb3J0IHtcclxuICBJU3RhbmRhcmRUcmFjZXIsXHJcbiAgU3RhbmRhcmRUcmFjZURhdGEsXHJcbiAgU3RhbmRhcmRTcGFuUmVzdWx0LFxyXG59IGZyb20gJy4vdHJhY2VyLXR5cGVzJztcclxuIl19
@@ -1,43 +0,0 @@
1
- export interface StandardLogData {
2
- severity: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
3
- message: string;
4
- error?: Error;
5
- serviceName: string;
6
- environment: string;
7
- http?: {
8
- method?: string;
9
- url?: string;
10
- endpoint?: string;
11
- statusCode?: number;
12
- headers?: Record<string, any>;
13
- body?: any;
14
- params?: Record<string, any>;
15
- query?: Record<string, any>;
16
- };
17
- user?: {
18
- accountUserUid?: string;
19
- accountUid?: string;
20
- applicationUid?: string;
21
- };
22
- execution?: {
23
- requestId?: string;
24
- awsRequestId?: string;
25
- functionName?: string;
26
- invocationId?: string;
27
- controller?: string;
28
- controllerMethod?: string;
29
- origin?: string;
30
- };
31
- performance?: {
32
- durationMs?: number;
33
- success?: boolean;
34
- };
35
- context?: Record<string, any>;
36
- timestamp: string;
37
- }
38
- export interface IStandardLogger {
39
- logError(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
40
- logInfo(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
41
- logWarn(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
42
- logDebug(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
43
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLXR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RlbGVtZXRyeS9jb3JlL2xvZ2dlci10eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEludGVyZmFjZSBwYWRyw6NvIHBhcmEgbG9ncyBlc3RydXR1cmFkb3MgZW0gdG9kYSBhIGFwbGljYcOnw6NvLlxyXG4gKiBDb21iaW5hIGNhbXBvcyBpbXBvcnRhbnRlcyBkZSBhbWJhcyBpbXBsZW1lbnRhw6fDtWVzIChUc2VkIGUgU1NUKS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgU3RhbmRhcmRMb2dEYXRhIHtcclxuICAvLyBJbmZvcm1hw6fDtWVzIGRvIGVycm8vZXZlbnRvXHJcbiAgc2V2ZXJpdHk6ICdFUlJPUicgfCAnV0FSTicgfCAnSU5GTycgfCAnREVCVUcnO1xyXG4gIG1lc3NhZ2U6IHN0cmluZztcclxuICBlcnJvcj86IEVycm9yO1xyXG5cclxuICAvLyBJZGVudGlmaWNhw6fDo28gZG8gc2VydmnDp29cclxuICBzZXJ2aWNlTmFtZTogc3RyaW5nO1xyXG4gIGVudmlyb25tZW50OiBzdHJpbmc7IC8vIGRldmVsb3BtZW50LCBzdGFnaW5nLCBwcm9kdWN0aW9uXHJcblxyXG4gIC8vIENvbnRleHRvIGRhIHJlcXVpc2nDp8OjbyBIVFRQXHJcbiAgaHR0cD86IHtcclxuICAgIG1ldGhvZD86IHN0cmluZztcclxuICAgIHVybD86IHN0cmluZztcclxuICAgIGVuZHBvaW50Pzogc3RyaW5nO1xyXG4gICAgc3RhdHVzQ29kZT86IG51bWJlcjtcclxuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG4gICAgYm9keT86IGFueTtcclxuICAgIHBhcmFtcz86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgICBxdWVyeT86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgfTtcclxuXHJcbiAgLy8gSWRlbnRpZmljYcOnw6NvIGRvIHVzdcOhcmlvL2NvbnRhXHJcbiAgdXNlcj86IHtcclxuICAgIGFjY291bnRVc2VyVWlkPzogc3RyaW5nO1xyXG4gICAgYWNjb3VudFVpZD86IHN0cmluZztcclxuICAgIGFwcGxpY2F0aW9uVWlkPzogc3RyaW5nO1xyXG4gIH07XHJcblxyXG4gIC8vIENvbnRleHRvIGRhIGV4ZWN1w6fDo29cclxuICBleGVjdXRpb24/OiB7XHJcbiAgICByZXF1ZXN0SWQ/OiBzdHJpbmc7XHJcbiAgICBhd3NSZXF1ZXN0SWQ/OiBzdHJpbmc7XHJcbiAgICBmdW5jdGlvbk5hbWU/OiBzdHJpbmc7XHJcbiAgICBpbnZvY2F0aW9uSWQ/OiBzdHJpbmc7XHJcbiAgICBjb250cm9sbGVyPzogc3RyaW5nO1xyXG4gICAgY29udHJvbGxlck1ldGhvZD86IHN0cmluZztcclxuICAgIG9yaWdpbj86IHN0cmluZzsgLy8gb3JpZ2VtIGRhIHJlcXVpc2nDp8OjbyAoZXg6IHdlYiwgbW9iaWxlKVxyXG4gIH07XHJcblxyXG4gIC8vIFBlcmZvcm1hbmNlXHJcbiAgcGVyZm9ybWFuY2U/OiB7XHJcbiAgICBkdXJhdGlvbk1zPzogbnVtYmVyO1xyXG4gICAgc3VjY2Vzcz86IGJvb2xlYW47XHJcbiAgfTtcclxuXHJcbiAgLy8gQ29udGV4dG8gYWRpY2lvbmFsIGxpdnJlXHJcbiAgY29udGV4dD86IFJlY29yZDxzdHJpbmcsIGFueT47XHJcblxyXG4gIC8vIFRpbWVzdGFtcFxyXG4gIHRpbWVzdGFtcDogc3RyaW5nO1xyXG59XHJcblxyXG4vKipcclxuICogSW50ZXJmYWNlIHBhcmEgbyBsb2dnZXIgY29yZVxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBJU3RhbmRhcmRMb2dnZXIge1xyXG4gIGxvZ0Vycm9yKFxyXG4gICAgZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz5cclxuICApOiBQcm9taXNlPHZvaWQ+O1xyXG4gIGxvZ0luZm8oZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz4pOiBQcm9taXNlPHZvaWQ+O1xyXG4gIGxvZ1dhcm4oZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz4pOiBQcm9taXNlPHZvaWQ+O1xyXG4gIGxvZ0RlYnVnKFxyXG4gICAgZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz5cclxuICApOiBQcm9taXNlPHZvaWQ+O1xyXG59XHJcbiJdfQ==
@@ -1,13 +0,0 @@
1
- import { Logger } from '@opentelemetry/api-logs';
2
- import { IStandardLogger, StandardLogData } from './logger-types';
3
- export declare class StandardLogger implements IStandardLogger {
4
- private readonly defaultServiceName;
5
- private logger;
6
- constructor(logger: Logger, defaultServiceName?: string);
7
- logError(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
8
- logInfo(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
9
- logWarn(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
10
- logDebug(data: Omit<StandardLogData, 'severity' | 'timestamp'>): Promise<void>;
11
- private log;
12
- private buildAttributes;
13
- }
@@ -1,123 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.StandardLogger = void 0;
13
- const api_logs_1 = require("@opentelemetry/api-logs");
14
- class StandardLogger {
15
- constructor(logger, defaultServiceName = 'unknown-service') {
16
- this.defaultServiceName = defaultServiceName;
17
- this.logger = logger;
18
- }
19
- logError(data) {
20
- return __awaiter(this, void 0, void 0, function* () {
21
- yield this.log(Object.assign(Object.assign({}, data), { severity: 'ERROR' }));
22
- });
23
- }
24
- logInfo(data) {
25
- return __awaiter(this, void 0, void 0, function* () {
26
- yield this.log(Object.assign(Object.assign({}, data), { severity: 'INFO' }));
27
- });
28
- }
29
- logWarn(data) {
30
- return __awaiter(this, void 0, void 0, function* () {
31
- yield this.log(Object.assign(Object.assign({}, data), { severity: 'WARN' }));
32
- });
33
- }
34
- logDebug(data) {
35
- return __awaiter(this, void 0, void 0, function* () {
36
- yield this.log(Object.assign(Object.assign({}, data), { severity: 'DEBUG' }));
37
- });
38
- }
39
- log(data) {
40
- return __awaiter(this, void 0, void 0, function* () {
41
- const fullData = Object.assign(Object.assign({}, data), { timestamp: new Date().toISOString(), serviceName: data.serviceName || this.defaultServiceName });
42
- const severityMap = {
43
- ERROR: api_logs_1.SeverityNumber.ERROR,
44
- WARN: api_logs_1.SeverityNumber.WARN,
45
- INFO: api_logs_1.SeverityNumber.INFO,
46
- DEBUG: api_logs_1.SeverityNumber.DEBUG,
47
- };
48
- const logRecord = {
49
- severityNumber: severityMap[fullData.severity],
50
- severityText: fullData.severity,
51
- body: fullData.message,
52
- attributes: this.buildAttributes(fullData),
53
- };
54
- this.logger.emit(logRecord);
55
- });
56
- }
57
- buildAttributes(data) {
58
- const attributes = {
59
- timestamp: data.timestamp,
60
- 'service.name': data.serviceName,
61
- 'deployment.environment.name': data.environment,
62
- };
63
- if (data.error) {
64
- attributes['error.type'] = data.error.name;
65
- attributes['error.message'] = data.error.message;
66
- attributes['error.stack'] = data.error.stack || '';
67
- }
68
- if (data.http) {
69
- if (data.http.method)
70
- attributes['http.method'] = data.http.method;
71
- if (data.http.url)
72
- attributes['http.url'] = data.http.url;
73
- if (data.http.endpoint)
74
- attributes['http.endpoint'] = data.http.endpoint;
75
- if (data.http.statusCode)
76
- attributes['http.status_code'] = data.http.statusCode;
77
- if (data.http.headers)
78
- attributes['http.headers'] = JSON.stringify(data.http.headers);
79
- if (data.http.body)
80
- attributes['http.body'] = JSON.stringify(data.http.body);
81
- if (data.http.params)
82
- attributes['http.params'] = JSON.stringify(data.http.params);
83
- if (data.http.query)
84
- attributes['http.query'] = JSON.stringify(data.http.query);
85
- }
86
- if (data.user) {
87
- if (data.user.accountUserUid)
88
- attributes['accountUser.uid'] = data.user.accountUserUid;
89
- if (data.user.accountUid)
90
- attributes['account.uid'] = data.user.accountUid;
91
- if (data.user.applicationUid)
92
- attributes['application.uid'] = data.user.applicationUid;
93
- }
94
- if (data.execution) {
95
- if (data.execution.requestId)
96
- attributes['request.id'] = data.execution.requestId;
97
- if (data.execution.awsRequestId)
98
- attributes['aws.request.id'] = data.execution.awsRequestId;
99
- if (data.execution.functionName)
100
- attributes['faas.name'] = data.execution.functionName;
101
- if (data.execution.invocationId)
102
- attributes['faas.invocation_id'] = data.execution.invocationId;
103
- if (data.execution.controller)
104
- attributes['controller.name'] = data.execution.controller;
105
- if (data.execution.controllerMethod)
106
- attributes['controller.method'] = data.execution.controllerMethod;
107
- if (data.execution.origin)
108
- attributes['origin'] = data.execution.origin;
109
- }
110
- if (data.performance) {
111
- if (data.performance.durationMs)
112
- attributes['duration.ms'] = data.performance.durationMs;
113
- if (data.performance.success !== undefined)
114
- attributes['execution.success'] = data.performance.success;
115
- }
116
- if (data.context) {
117
- attributes['context'] = JSON.stringify(data.context);
118
- }
119
- return Object.fromEntries(Object.entries(attributes).filter(([, value]) => value !== undefined && value !== null));
120
- }
121
- }
122
- exports.StandardLogger = StandardLogger;
123
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RlbGVtZXRyeS9jb3JlL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSxzREFBaUU7QUFPakUsTUFBYSxjQUFjO0lBR3pCLFlBQ0UsTUFBYyxFQUNHLHFCQUE2QixpQkFBaUI7UUFBOUMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUE0QjtRQUUvRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUssUUFBUSxDQUNaLElBQXFEOztZQUVyRCxNQUFNLElBQUksQ0FBQyxHQUFHLGlDQUFNLElBQUksS0FBRSxRQUFRLEVBQUUsT0FBTyxJQUFHLENBQUM7UUFDakQsQ0FBQztLQUFBO0lBRUssT0FBTyxDQUNYLElBQXFEOztZQUVyRCxNQUFNLElBQUksQ0FBQyxHQUFHLGlDQUFNLElBQUksS0FBRSxRQUFRLEVBQUUsTUFBTSxJQUFHLENBQUM7UUFDaEQsQ0FBQztLQUFBO0lBRUssT0FBTyxDQUNYLElBQXFEOztZQUVyRCxNQUFNLElBQUksQ0FBQyxHQUFHLGlDQUFNLElBQUksS0FBRSxRQUFRLEVBQUUsTUFBTSxJQUFHLENBQUM7UUFDaEQsQ0FBQztLQUFBO0lBRUssUUFBUSxDQUNaLElBQXFEOztZQUVyRCxNQUFNLElBQUksQ0FBQyxHQUFHLGlDQUFNLElBQUksS0FBRSxRQUFRLEVBQUUsT0FBTyxJQUFHLENBQUM7UUFDakQsQ0FBQztLQUFBO0lBRWEsR0FBRyxDQUNmLElBRUM7O1lBRUQsTUFBTSxRQUFRLG1DQUNULElBQUksS0FDUCxTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGtCQUFrQixHQUN6RCxDQUFDO1lBRUYsTUFBTSxXQUFXLEdBQUc7Z0JBQ2xCLEtBQUssRUFBRSx5QkFBYyxDQUFD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Z0JBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQzFFLENBQUM7UUFHRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVTtnQkFDN0IsVUFBVSxDQUFDLGFBQWEsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO1lBQzFELElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEtBQUssU0FBUztnQkFDeEMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFDL0QsQ0FBQztRQUdELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBR0QsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUN2QixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FDL0IsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLElBQUksQ0FDckQsQ0FDRixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBNUlELHdDQTRJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNldmVyaXR5TnVtYmVyLCBMb2dnZXIgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGktbG9ncyc7XHJcbmltcG9ydCB7IElTdGFuZGFyZExvZ2dlciwgU3RhbmRhcmRMb2dEYXRhIH0gZnJvbSAnLi9sb2dnZXItdHlwZXMnO1xyXG5cclxuLyoqXHJcbiAqIExvZ2dlciBjb3JlIHF1ZSBpbXBsZW1lbnRhIG8gcGFkcsOjbyBkZSBsb2dzIGVzdHJ1dHVyYWRvcy5cclxuICogUmVjZWJlIHVtIExvZ2dlclByb3ZpZGVyIGRvIE9wZW5UZWxlbWV0cnkgcGFyYSBlbWl0aXIgb3MgbG9ncy5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBTdGFuZGFyZExvZ2dlciBpbXBsZW1lbnRzIElTdGFuZGFyZExvZ2dlciB7XHJcbiAgcHJpdmF0ZSBsb2dnZXI6IExvZ2dlcjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBsb2dnZXI6IExvZ2dlcixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdFNlcnZpY2VOYW1lOiBzdHJpbmcgPSAndW5rbm93bi1zZXJ2aWNlJ1xyXG4gICkge1xyXG4gICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7XHJcbiAgfVxyXG5cclxuICBhc3luYyBsb2dFcnJvcihcclxuICAgIGRhdGE6IE9taXQ8U3RhbmRhcmRMb2dEYXRhLCAnc2V2ZXJpdHknIHwgJ3RpbWVzdGFtcCc+XHJcbiAgKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBhd2FpdCB0aGlzLmxvZyh7IC4uLmRhdGEsIHNldmVyaXR5OiAnRVJST1InIH0pO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgbG9nSW5mbyhcclxuICAgIGRhdGE6IE9taXQ8U3RhbmRhcmRMb2dEYXRhLCAnc2V2ZXJpdHknIHwgJ3RpbWVzdGFtcCc+XHJcbiAgKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBhd2FpdCB0aGlzLmxvZyh7IC4uLmRhdGEsIHNldmVyaXR5OiAnSU5GTycgfSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBsb2dXYXJuKFxyXG4gICAgZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz5cclxuICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGF3YWl0IHRoaXMubG9nKHsgLi4uZGF0YSwgc2V2ZXJpdHk6ICdXQVJOJyB9KTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGxvZ0RlYnVnKFxyXG4gICAgZGF0YTogT21pdDxTdGFuZGFyZExvZ0RhdGEsICdzZXZlcml0eScgfCAndGltZXN0YW1wJz5cclxuICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGF3YWl0IHRoaXMubG9nKHsgLi4uZGF0YSwgc2V2ZXJpdHk6ICdERUJVRycgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGxvZyhcclxuICAgIGRhdGE6IE9taXQ8U3RhbmRhcmRMb2dEYXRhLCAndGltZXN0YW1wJz4gJiB7XHJcbiAgICAgIHNldmVyaXR5OiBTdGFuZGFyZExvZ0RhdGFbJ3NldmVyaXR5J107XHJcbiAgICB9XHJcbiAgKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBmdWxsRGF0YTogU3RhbmRhcmRMb2dEYXRhID0ge1xyXG4gICAgICAuLi5kYXRhLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcclxuICAgICAgc2VydmljZU5hbWU6IGRhdGEuc2VydmljZU5hbWUgfHwgdGhpcy5kZWZhdWx0U2VydmljZU5hbWUsXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IHNldmVyaXR5TWFwID0ge1xyXG4gICAgICBFUlJPUjogU2V2ZXJpdHlOdW1iZXIuRVJST1IsXHJcbiAgICAgIFdBUk46IFNldmVyaXR5TnVtYmVyLldBUk4sXHJcbiAgICAgIElORk86IFNldmVyaXR5TnVtYmVyLklORk8sXHJcbiAgICAgIERFQlVHOiBTZXZlcml0eU51bWJlci5ERUJVRyxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgbG9nUmVjb3JkID0ge1xyXG4gICAgICBzZXZlcml0eU51bWJlcjogc2V2ZXJpdHlNYXBbZnVsbERhdGEuc2V2ZXJpdHldLFxyXG4gICAgICBzZXZlcml0eVRleHQ6IGZ1bGxEYXRhLnNldmVyaXR5LFxyXG4gICAgICBib2R5OiBmdWxsRGF0YS5tZXNzYWdlLFxyXG4gICAgICBhdHRyaWJ1dGVzOiB0aGlzLmJ1aWxkQXR0cmlidXRlcyhmdWxsRGF0YSksXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMubG9nZ2VyLmVtaXQobG9nUmVjb3JkKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYnVpbGRBdHRyaWJ1dGVzKGRhdGE6IFN0YW5kYXJkTG9nRGF0YSk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgY29uc3QgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHtcclxuICAgICAgdGltZXN0YW1wOiBkYXRhLnRpbWVzdGFtcCxcclxuICAgICAgJ3NlcnZpY2UubmFtZSc6IGRhdGEuc2VydmljZU5hbWUsXHJcbiAgICAgICdkZXBsb3ltZW50LmVudmlyb25tZW50Lm5hbWUnOiBkYXRhLmVudmlyb25tZW50LFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBJbmZvcm1hw6fDtWVzIGRvIGVycm9cclxuICAgIGlmIChkYXRhLmVycm9yKSB7XHJcbiAgICAgIGF0dHJpYnV0ZXNbJ2Vycm9yLnR5cGUnXSA9IGRhdGEuZXJyb3IubmFtZTtcclxuICAgICAgYXR0cmlidXRlc1snZXJyb3IubWVzc2FnZSddID0gZGF0YS5lcnJvci5tZXNzYWdlO1xyXG4gICAgICBhdHRyaWJ1dGVzWydlcnJvci5zdGFjayddID0gZGF0YS5lcnJvci5zdGFjayB8fCAnJztcclxuICAgIH1cclxuXHJcbiAgICAvLyBIVFRQXHJcbiAgICBpZiAoZGF0YS5odHRwKSB7XHJcbiAgICAgIGlmIChkYXRhLmh0dHAubWV0aG9kKSBhdHRyaWJ1dGVzWydodHRwLm1ldGhvZCddID0gZGF0YS5odHRwLm1ldGhvZDtcclxuICAgICAgaWYgKGRhdGEuaHR0cC51cmwpIGF0dHJpYnV0ZXNbJ2h0dHAudXJsJ10gPSBkYXRhLmh0dHAudXJsO1xyXG4gICAgICBpZiAoZGF0YS5odHRwLmVuZHBvaW50KSBhdHRyaWJ1dGVzWydodHRwLmVuZHBvaW50J10gPSBkYXRhLmh0dHAuZW5kcG9pbnQ7XHJcbiAgICAgIGlmIChkYXRhLmh0dHAuc3RhdHVzQ29kZSlcclxuICAgICAgICBhdHRyaWJ1dGVzWydodHRwLnN0YXR1c19jb2RlJ10gPSBkYXRhLmh0dHAuc3RhdHVzQ29kZTtcclxuICAgICAgaWYgKGRhdGEuaHR0cC5oZWFkZXJzKVxyXG4gICAgICAgIGF0dHJpYnV0ZXNbJ2h0dHAuaGVhZGVycyddID0gSlNPTi5zdHJpbmdpZnkoZGF0YS5odHRwLmhlYWRlcnMpO1xyXG4gICAgICBpZiAoZGF0YS5odHRwLmJvZHkpXHJcbiAgICAgICAgYXR0cmlidXRlc1snaHR0cC5ib2R5J10gPSBKU09OLnN0cmluZ2lmeShkYXRhLmh0dHAuYm9keSk7XHJcbiAgICAgIGlmIChkYXRhLmh0dHAucGFyYW1zKVxyXG4gICAgICAgIGF0dHJpYnV0ZXNbJ2h0dHAucGFyYW1zJ10gPSBKU09OLnN0cmluZ2lmeShkYXRhLmh0dHAucGFyYW1zKTtcclxuICAgICAgaWYgKGRhdGEuaHR0cC5xdWVyeSlcclxuICAgICAgICBhdHRyaWJ1dGVzWydodHRwLnF1ZXJ5J10gPSBKU09OLnN0cmluZ2lmeShkYXRhLmh0dHAucXVlcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFVzdcOhcmlvXHJcbiAgICBpZiAoZGF0YS51c2VyKSB7XHJcbiAgICAgIGlmIChkYXRhLnVzZXIuYWNjb3VudFVzZXJVaWQpXHJcbiAgICAgICAgYXR0cmlidXRlc1snYWNjb3VudFVzZXIudWlkJ10gPSBkYXRhLnVzZXIuYWNjb3VudFVzZXJVaWQ7XHJcbiAgICAgIGlmIChkYXRhLnVzZXIuYWNjb3VudFVpZClcclxuICAgICAgICBhdHRyaWJ1dGVzWydhY2NvdW50LnVpZCddID0gZGF0YS51c2VyLmFjY291bnRVaWQ7XHJcbiAgICAgIGlmIChkYXRhLnVzZXIuYXBwbGljYXRpb25VaWQpXHJcbiAgICAgICAgYXR0cmlidXRlc1snYXBwbGljYXRpb24udWlkJ10gPSBkYXRhLnVzZXIuYXBwbGljYXRpb25VaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRXhlY3XDp8Ojb1xyXG4gICAgaWYgKGRhdGEuZXhlY3V0aW9uKSB7XHJcbiAgICAgIGlmIChkYXRhLmV4ZWN1dGlvbi5yZXF1ZXN0SWQpXHJcbiAgICAgICAgYXR0cmlidXRlc1sncmVxdWVzdC5pZCddID0gZGF0YS5leGVjdXRpb24ucmVxdWVzdElkO1xyXG4gICAgICBpZiAoZGF0YS5leGVjdXRpb24uYXdzUmVxdWVzdElkKVxyXG4gICAgICAgIGF0dHJpYnV0ZXNbJ2F3cy5yZXF1ZXN0LmlkJ10gPSBkYXRhLmV4ZWN1dGlvbi5hd3NSZXF1ZXN0SWQ7XHJcbiAgICAgIGlmIChkYXRhLmV4ZWN1dGlvbi5mdW5jdGlvbk5hbWUpXHJcbiAgICAgICAgYXR0cmlidXRlc1snZmFhcy5uYW1lJ10gPSBkYXRhLmV4ZWN1dGlvbi5mdW5jdGlvbk5hbWU7XHJcbiAgICAgIGlmIChkYXRhLmV4ZWN1dGlvbi5pbnZvY2F0aW9uSWQpXHJcbiAgICAgICAgYXR0cmlidXRlc1snZmFhcy5pbnZvY2F0aW9uX2lkJ10gPSBkYXRhLmV4ZWN1dGlvbi5pbnZvY2F0aW9uSWQ7XHJcbiAgICAgIGlmIChkYXRhLmV4ZWN1dGlvbi5jb250cm9sbGVyKVxyXG4gICAgICAgIGF0dHJpYnV0ZXNbJ2NvbnRyb2xsZXIubmFtZSddID0gZGF0YS5leGVjdXRpb24uY29udHJvbGxlcjtcclxuICAgICAgaWYgKGRhdGEuZXhlY3V0aW9uLmNvbnRyb2xsZXJNZXRob2QpXHJcbiAgICAgICAgYXR0cmlidXRlc1snY29udHJvbGxlci5tZXRob2QnXSA9IGRhdGEuZXhlY3V0aW9uLmNvbnRyb2xsZXJNZXRob2Q7XHJcbiAgICAgIGlmIChkYXRhLmV4ZWN1dGlvbi5vcmlnaW4pIGF0dHJpYnV0ZXNbJ29yaWdpbiddID0gZGF0YS5leGVjdXRpb24ub3JpZ2luO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBlcmZvcm1hbmNlXHJcbiAgICBpZiAoZGF0YS5wZXJmb3JtYW5jZSkge1xyXG4gICAgICBpZiAoZGF0YS5wZXJmb3JtYW5jZS5kdXJhdGlvbk1zKVxyXG4gICAgICAgIGF0dHJpYnV0ZXNbJ2R1cmF0aW9uLm1zJ10gPSBkYXRhLnBlcmZvcm1hbmNlLmR1cmF0aW9uTXM7XHJcbiAgICAgIGlmIChkYXRhLnBlcmZvcm1hbmNlLnN1Y2Nlc3MgIT09IHVuZGVmaW5lZClcclxuICAgICAgICBhdHRyaWJ1dGVzWydleGVjdXRpb24uc3VjY2VzcyddID0gZGF0YS5wZXJmb3JtYW5jZS5zdWNjZXNzO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvbnRleHRvIGFkaWNpb25hbFxyXG4gICAgaWYgKGRhdGEuY29udGV4dCkge1xyXG4gICAgICBhdHRyaWJ1dGVzWydjb250ZXh0J10gPSBKU09OLnN0cmluZ2lmeShkYXRhLmNvbnRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbHRyYXIgdmFsb3JlcyB1bmRlZmluZWQvbnVsbFxyXG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcclxuICAgICAgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykuZmlsdGVyKFxyXG4gICAgICAgIChbLCB2YWx1ZV0pID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGxcclxuICAgICAgKVxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIl19