@growsober/sdk 1.0.0

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 (129) hide show
  1. package/README.md +276 -0
  2. package/dist/__tests__/e2e.test.d.ts +7 -0
  3. package/dist/__tests__/e2e.test.js +472 -0
  4. package/dist/api/client.d.ts +11 -0
  5. package/dist/api/client.js +61 -0
  6. package/dist/api/mutations/admin.d.ts +167 -0
  7. package/dist/api/mutations/admin.js +326 -0
  8. package/dist/api/mutations/ambassadors.d.ts +52 -0
  9. package/dist/api/mutations/ambassadors.js +148 -0
  10. package/dist/api/mutations/auth.d.ts +267 -0
  11. package/dist/api/mutations/auth.js +332 -0
  12. package/dist/api/mutations/bookings.d.ts +59 -0
  13. package/dist/api/mutations/bookings.js +143 -0
  14. package/dist/api/mutations/event-chat.d.ts +35 -0
  15. package/dist/api/mutations/event-chat.js +147 -0
  16. package/dist/api/mutations/events.d.ts +87 -0
  17. package/dist/api/mutations/events.js +205 -0
  18. package/dist/api/mutations/grow90.d.ts +36 -0
  19. package/dist/api/mutations/grow90.js +132 -0
  20. package/dist/api/mutations/hubs.d.ts +111 -0
  21. package/dist/api/mutations/hubs.js +240 -0
  22. package/dist/api/mutations/index.d.ts +22 -0
  23. package/dist/api/mutations/index.js +39 -0
  24. package/dist/api/mutations/jack.d.ts +61 -0
  25. package/dist/api/mutations/jack.js +104 -0
  26. package/dist/api/mutations/library.d.ts +67 -0
  27. package/dist/api/mutations/library.js +168 -0
  28. package/dist/api/mutations/map.d.ts +153 -0
  29. package/dist/api/mutations/map.js +181 -0
  30. package/dist/api/mutations/matching.d.ts +130 -0
  31. package/dist/api/mutations/matching.js +204 -0
  32. package/dist/api/mutations/notifications.d.ts +63 -0
  33. package/dist/api/mutations/notifications.js +106 -0
  34. package/dist/api/mutations/offers.d.ts +26 -0
  35. package/dist/api/mutations/offers.js +47 -0
  36. package/dist/api/mutations/subscriptions.d.ts +127 -0
  37. package/dist/api/mutations/subscriptions.js +140 -0
  38. package/dist/api/mutations/support.d.ts +165 -0
  39. package/dist/api/mutations/support.js +307 -0
  40. package/dist/api/mutations/users.d.ts +211 -0
  41. package/dist/api/mutations/users.js +261 -0
  42. package/dist/api/queries/admin.d.ts +257 -0
  43. package/dist/api/queries/admin.js +320 -0
  44. package/dist/api/queries/ambassadors.d.ts +53 -0
  45. package/dist/api/queries/ambassadors.js +98 -0
  46. package/dist/api/queries/auth.d.ts +16 -0
  47. package/dist/api/queries/auth.js +25 -0
  48. package/dist/api/queries/bookings.d.ts +91 -0
  49. package/dist/api/queries/bookings.js +102 -0
  50. package/dist/api/queries/businesses.d.ts +212 -0
  51. package/dist/api/queries/businesses.js +154 -0
  52. package/dist/api/queries/event-chat.d.ts +19 -0
  53. package/dist/api/queries/event-chat.js +75 -0
  54. package/dist/api/queries/events.d.ts +322 -0
  55. package/dist/api/queries/events.js +221 -0
  56. package/dist/api/queries/grow90.d.ts +26 -0
  57. package/dist/api/queries/grow90.js +85 -0
  58. package/dist/api/queries/hubs.d.ts +165 -0
  59. package/dist/api/queries/hubs.js +143 -0
  60. package/dist/api/queries/index.d.ts +23 -0
  61. package/dist/api/queries/index.js +40 -0
  62. package/dist/api/queries/jack.d.ts +63 -0
  63. package/dist/api/queries/jack.js +92 -0
  64. package/dist/api/queries/library.d.ts +132 -0
  65. package/dist/api/queries/library.js +120 -0
  66. package/dist/api/queries/map.d.ts +216 -0
  67. package/dist/api/queries/map.js +278 -0
  68. package/dist/api/queries/matching.d.ts +136 -0
  69. package/dist/api/queries/matching.js +161 -0
  70. package/dist/api/queries/notifications.d.ts +78 -0
  71. package/dist/api/queries/notifications.js +88 -0
  72. package/dist/api/queries/offers.d.ts +91 -0
  73. package/dist/api/queries/offers.js +103 -0
  74. package/dist/api/queries/subscriptions.d.ts +56 -0
  75. package/dist/api/queries/subscriptions.js +73 -0
  76. package/dist/api/queries/support.d.ts +106 -0
  77. package/dist/api/queries/support.js +202 -0
  78. package/dist/api/queries/users.d.ts +293 -0
  79. package/dist/api/queries/users.js +370 -0
  80. package/dist/api/types.d.ts +464 -0
  81. package/dist/api/types.js +9 -0
  82. package/dist/hooks/useAuth.d.ts +5 -0
  83. package/dist/hooks/useAuth.js +39 -0
  84. package/dist/hooks/useUser.d.ts +43 -0
  85. package/dist/hooks/useUser.js +44 -0
  86. package/dist/index.d.ts +36 -0
  87. package/dist/index.js +67 -0
  88. package/package.json +62 -0
  89. package/src/__tests__/e2e.test.ts +502 -0
  90. package/src/api/client.ts +71 -0
  91. package/src/api/mutations/admin.ts +531 -0
  92. package/src/api/mutations/ambassadors.ts +185 -0
  93. package/src/api/mutations/auth.ts +350 -0
  94. package/src/api/mutations/bookings.ts +190 -0
  95. package/src/api/mutations/event-chat.ts +177 -0
  96. package/src/api/mutations/events.ts +273 -0
  97. package/src/api/mutations/grow90.ts +169 -0
  98. package/src/api/mutations/hubs.ts +385 -0
  99. package/src/api/mutations/index.ts +23 -0
  100. package/src/api/mutations/jack.ts +130 -0
  101. package/src/api/mutations/library.ts +212 -0
  102. package/src/api/mutations/map.ts +230 -0
  103. package/src/api/mutations/matching.ts +271 -0
  104. package/src/api/mutations/notifications.ts +114 -0
  105. package/src/api/mutations/offers.ts +73 -0
  106. package/src/api/mutations/subscriptions.ts +162 -0
  107. package/src/api/mutations/support.ts +390 -0
  108. package/src/api/mutations/users.ts +271 -0
  109. package/src/api/queries/admin.ts +480 -0
  110. package/src/api/queries/ambassadors.ts +139 -0
  111. package/src/api/queries/auth.ts +24 -0
  112. package/src/api/queries/bookings.ts +135 -0
  113. package/src/api/queries/businesses.ts +203 -0
  114. package/src/api/queries/event-chat.ts +78 -0
  115. package/src/api/queries/events.ts +272 -0
  116. package/src/api/queries/grow90.ts +98 -0
  117. package/src/api/queries/hubs.ts +211 -0
  118. package/src/api/queries/index.ts +24 -0
  119. package/src/api/queries/jack.ts +127 -0
  120. package/src/api/queries/library.ts +166 -0
  121. package/src/api/queries/map.ts +331 -0
  122. package/src/api/queries/matching.ts +238 -0
  123. package/src/api/queries/notifications.ts +103 -0
  124. package/src/api/queries/offers.ts +136 -0
  125. package/src/api/queries/subscriptions.ts +91 -0
  126. package/src/api/queries/support.ts +235 -0
  127. package/src/api/queries/users.ts +393 -0
  128. package/src/api/types.ts +596 -0
  129. package/src/index.ts +57 -0
@@ -0,0 +1,472 @@
1
+ "use strict";
2
+ /**
3
+ * GrowSober API E2E Tests
4
+ *
5
+ * Tests all SDK endpoints against the real API.
6
+ * Run with: npx ts-node src/__tests__/e2e.test.ts
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const axios_1 = __importDefault(require("axios"));
13
+ const BASE_URL = 'http://localhost:3001/api/v1';
14
+ const TEST_EMAIL = `e2e-${Date.now()}@growsober.com`;
15
+ const TEST_PASSWORD = 'SecurePass123!';
16
+ // Colors for output
17
+ const c = {
18
+ reset: '\x1b[0m',
19
+ green: '\x1b[32m',
20
+ red: '\x1b[31m',
21
+ yellow: '\x1b[33m',
22
+ cyan: '\x1b[36m',
23
+ dim: '\x1b[2m',
24
+ };
25
+ // State shared across tests
26
+ const state = {
27
+ accessToken: '',
28
+ refreshToken: '',
29
+ userId: '',
30
+ };
31
+ // Stats
32
+ let passed = 0;
33
+ let failed = 0;
34
+ // Create axios client
35
+ function api(token) {
36
+ return axios_1.default.create({
37
+ baseURL: BASE_URL,
38
+ headers: token ? { Authorization: `Bearer ${token}` } : {},
39
+ validateStatus: () => true,
40
+ });
41
+ }
42
+ // Test runner
43
+ async function test(name, fn) {
44
+ const start = Date.now();
45
+ try {
46
+ await fn();
47
+ console.log(`${c.green}PASS${c.reset} ${name} ${c.dim}(${Date.now() - start}ms)${c.reset}`);
48
+ passed++;
49
+ return true;
50
+ }
51
+ catch (e) {
52
+ console.log(`${c.red}FAIL${c.reset} ${name} ${c.dim}(${Date.now() - start}ms)${c.reset}`);
53
+ console.log(` ${c.yellow}${e.message}${c.reset}`);
54
+ failed++;
55
+ return false;
56
+ }
57
+ }
58
+ // Unwrap API response
59
+ function unwrap(res) {
60
+ return res.data.data;
61
+ }
62
+ // ============================================================================
63
+ // TESTS
64
+ // ============================================================================
65
+ async function runTests() {
66
+ console.log(`\n${c.cyan}${'='.repeat(60)}${c.reset}`);
67
+ console.log(`${c.cyan} GrowSober API E2E Tests${c.reset}`);
68
+ console.log(`${c.cyan}${'='.repeat(60)}${c.reset}`);
69
+ console.log(`${c.dim}Base URL: ${BASE_URL}${c.reset}`);
70
+ console.log(`${c.dim}Test Email: ${TEST_EMAIL}${c.reset}\n`);
71
+ // Health check
72
+ const health = await api().get('/health');
73
+ if (health.status !== 200) {
74
+ console.log(`${c.red}API is not reachable${c.reset}`);
75
+ process.exit(1);
76
+ }
77
+ console.log(`${c.green}API is healthy${c.reset}\n`);
78
+ // =========================================================================
79
+ // AUTH
80
+ // =========================================================================
81
+ console.log(`\n${c.cyan}--- AUTHENTICATION ---${c.reset}\n`);
82
+ await test('Register new user', async () => {
83
+ const res = await api().post('/auth/register', {
84
+ email: TEST_EMAIL,
85
+ password: TEST_PASSWORD,
86
+ name: 'E2E Test User',
87
+ });
88
+ if (res.status !== 201)
89
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
90
+ const data = unwrap(res);
91
+ state.accessToken = data.accessToken;
92
+ state.refreshToken = data.refreshToken;
93
+ state.userId = data.user.id;
94
+ });
95
+ await test('Login with email', async () => {
96
+ const res = await api().post('/auth/login', {
97
+ email: TEST_EMAIL,
98
+ password: TEST_PASSWORD,
99
+ });
100
+ if (res.status !== 200)
101
+ throw new Error(`Status ${res.status}`);
102
+ const data = unwrap(res);
103
+ state.accessToken = data.accessToken;
104
+ state.refreshToken = data.refreshToken;
105
+ });
106
+ await test('Refresh token', async () => {
107
+ const res = await api().post('/auth/refresh', {
108
+ refreshToken: state.refreshToken,
109
+ });
110
+ if (res.status !== 200)
111
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
112
+ const data = unwrap(res);
113
+ state.accessToken = data.accessToken;
114
+ state.refreshToken = data.refreshToken;
115
+ });
116
+ await test('Get current user (auth/me)', async () => {
117
+ const res = await api(state.accessToken).get('/auth/me');
118
+ if (res.status !== 200)
119
+ throw new Error(`Status ${res.status}`);
120
+ });
121
+ await test('Invalid login returns 401', async () => {
122
+ const res = await api().post('/auth/login', {
123
+ email: TEST_EMAIL,
124
+ password: 'WrongPassword',
125
+ });
126
+ if (res.status !== 401)
127
+ throw new Error(`Expected 401, got ${res.status}`);
128
+ });
129
+ // =========================================================================
130
+ // USERS
131
+ // =========================================================================
132
+ console.log(`\n${c.cyan}--- USERS ---${c.reset}\n`);
133
+ await test('Get current user profile', async () => {
134
+ const res = await api(state.accessToken).get('/users/me');
135
+ if (res.status !== 200)
136
+ throw new Error(`Status ${res.status}`);
137
+ });
138
+ await test('Update profile', async () => {
139
+ const res = await api(state.accessToken).put('/users/me', {
140
+ name: 'Updated E2E User',
141
+ bio: 'E2E test bio',
142
+ });
143
+ if (res.status !== 200)
144
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
145
+ });
146
+ await test('Get user by ID', async () => {
147
+ const res = await api(state.accessToken).get(`/users/${state.userId}`);
148
+ if (res.status !== 200)
149
+ throw new Error(`Status ${res.status}`);
150
+ });
151
+ await test('Get user public profile', async () => {
152
+ const res = await api(state.accessToken).get(`/users/${state.userId}/public`);
153
+ if (res.status !== 200)
154
+ throw new Error(`Status ${res.status}`);
155
+ });
156
+ // =========================================================================
157
+ // EVENTS
158
+ // =========================================================================
159
+ console.log(`\n${c.cyan}--- EVENTS ---${c.reset}\n`);
160
+ await test('List events', async () => {
161
+ const res = await api().get('/events');
162
+ if (res.status !== 200)
163
+ throw new Error(`Status ${res.status}`);
164
+ });
165
+ await test('Get upcoming events', async () => {
166
+ const res = await api().get('/events/upcoming');
167
+ if (res.status !== 200)
168
+ throw new Error(`Status ${res.status}`);
169
+ });
170
+ await test('Create event', async () => {
171
+ const res = await api(state.accessToken).post('/events', {
172
+ title: 'E2E Test Event',
173
+ description: 'A test event created by E2E tests',
174
+ startDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), // 7 days from now
175
+ totalSpots: 20,
176
+ locationName: 'Test Location',
177
+ locationAddress: '123 Test Street',
178
+ });
179
+ if (res.status !== 201)
180
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
181
+ const data = unwrap(res);
182
+ state.eventId = data.id;
183
+ });
184
+ if (state.eventId) {
185
+ await test('Get event by ID', async () => {
186
+ const res = await api().get(`/events/${state.eventId}`);
187
+ if (res.status !== 200)
188
+ throw new Error(`Status ${res.status}`);
189
+ });
190
+ await test('Update event', async () => {
191
+ const res = await api(state.accessToken).put(`/events/${state.eventId}`, {
192
+ title: 'E2E Test Event (Updated)',
193
+ });
194
+ if (res.status !== 200)
195
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
196
+ });
197
+ await test('Publish event', async () => {
198
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/publish`);
199
+ if (res.status !== 200)
200
+ throw new Error(`Status ${res.status}`);
201
+ });
202
+ await test('Get my events', async () => {
203
+ const res = await api(state.accessToken).get('/events/my-events');
204
+ if (res.status !== 200)
205
+ throw new Error(`Status ${res.status}`);
206
+ });
207
+ }
208
+ // =========================================================================
209
+ // BOOKINGS
210
+ // =========================================================================
211
+ console.log(`\n${c.cyan}--- BOOKINGS ---${c.reset}\n`);
212
+ if (state.eventId) {
213
+ await test('RSVP to event', async () => {
214
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/book`);
215
+ // 201 for new booking, 409 if already exists
216
+ if (res.status !== 201 && res.status !== 409)
217
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
218
+ if (res.status === 201) {
219
+ const data = unwrap(res);
220
+ state.bookingId = data.id;
221
+ }
222
+ });
223
+ await test('Get my bookings', async () => {
224
+ const res = await api(state.accessToken).get('/bookings/me');
225
+ if (res.status !== 200)
226
+ throw new Error(`Status ${res.status}`);
227
+ });
228
+ }
229
+ // =========================================================================
230
+ // EVENT CHAT
231
+ // =========================================================================
232
+ console.log(`\n${c.cyan}--- EVENT CHAT ---${c.reset}\n`);
233
+ if (state.eventId) {
234
+ await test('Get or create event chat', async () => {
235
+ const res = await api(state.accessToken).get(`/events/${state.eventId}/chat`);
236
+ if (res.status !== 200)
237
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
238
+ const data = unwrap(res);
239
+ state.chatId = data.id;
240
+ });
241
+ await test('Join event chat', async () => {
242
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/chat/join`);
243
+ // 200 for join, 403 if no booking (but we just booked)
244
+ if (res.status !== 200)
245
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
246
+ });
247
+ await test('Send chat message', async () => {
248
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/chat/messages`, {
249
+ content: 'Hello from E2E test!',
250
+ });
251
+ if (res.status !== 201)
252
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
253
+ });
254
+ await test('Get chat messages', async () => {
255
+ const res = await api(state.accessToken).get(`/events/${state.eventId}/chat/messages`);
256
+ if (res.status !== 200)
257
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
258
+ });
259
+ await test('Get chat members', async () => {
260
+ const res = await api(state.accessToken).get(`/events/${state.eventId}/chat/members`);
261
+ if (res.status !== 200)
262
+ throw new Error(`Status ${res.status}`);
263
+ });
264
+ await test('Mark chat as read', async () => {
265
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/chat/read`);
266
+ if (res.status !== 204)
267
+ throw new Error(`Status ${res.status}`);
268
+ });
269
+ }
270
+ // =========================================================================
271
+ // HUBS
272
+ // =========================================================================
273
+ console.log(`\n${c.cyan}--- HUBS ---${c.reset}\n`);
274
+ await test('List hubs', async () => {
275
+ const res = await api().get('/hubs');
276
+ if (res.status !== 200)
277
+ throw new Error(`Status ${res.status}`);
278
+ // Get first hub if exists
279
+ const data = res.data.data;
280
+ if (Array.isArray(data) && data.length > 0) {
281
+ state.hubId = data[0].id;
282
+ }
283
+ });
284
+ if (state.hubId) {
285
+ await test('Get hub by ID', async () => {
286
+ const res = await api().get(`/hubs/${state.hubId}`);
287
+ if (res.status !== 200)
288
+ throw new Error(`Status ${res.status}`);
289
+ });
290
+ await test('Join hub', async () => {
291
+ const res = await api(state.accessToken).post(`/hubs/${state.hubId}/join`);
292
+ // 200/201 for join, 409 if already member
293
+ if (res.status !== 200 && res.status !== 201 && res.status !== 409) {
294
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
295
+ }
296
+ });
297
+ await test('Get hub members', async () => {
298
+ const res = await api(state.accessToken).get(`/hubs/${state.hubId}/members`);
299
+ if (res.status !== 200)
300
+ throw new Error(`Status ${res.status}`);
301
+ });
302
+ }
303
+ // =========================================================================
304
+ // JACK AI (Support Conversations)
305
+ // =========================================================================
306
+ console.log(`\n${c.cyan}--- JACK AI ---${c.reset}\n`);
307
+ await test('Start Jack conversation', async () => {
308
+ const res = await api(state.accessToken).post('/support/jack/conversations/new', {
309
+ message: 'Hello Jack!',
310
+ });
311
+ if (res.status !== 201 && res.status !== 200)
312
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
313
+ const data = unwrap(res);
314
+ state.conversationId = data.conversation?.id || data.id;
315
+ });
316
+ await test('Get Jack conversations', async () => {
317
+ const res = await api(state.accessToken).get('/support/jack/conversations');
318
+ if (res.status !== 200)
319
+ throw new Error(`Status ${res.status}`);
320
+ });
321
+ await test('Get Jack chat history', async () => {
322
+ const res = await api(state.accessToken).get('/support/jack/history');
323
+ if (res.status !== 200)
324
+ throw new Error(`Status ${res.status}`);
325
+ });
326
+ if (state.conversationId) {
327
+ await test('Get Jack conversation by ID', async () => {
328
+ const res = await api(state.accessToken).get(`/support/jack/conversations/${state.conversationId}`);
329
+ if (res.status !== 200)
330
+ throw new Error(`Status ${res.status}`);
331
+ });
332
+ }
333
+ // =========================================================================
334
+ // SUPPORT (Check-ins, Wins)
335
+ // =========================================================================
336
+ console.log(`\n${c.cyan}--- SUPPORT ---${c.reset}\n`);
337
+ await test('Create daily check-in', async () => {
338
+ const res = await api(state.accessToken).post('/support/check-ins', {
339
+ date: new Date().toISOString().split('T')[0],
340
+ mood: 4, // Valid range 1-5
341
+ energy: 4, // Valid range 1-5
342
+ stayedSober: true,
343
+ notes: 'E2E test check-in',
344
+ });
345
+ // 201 for new, 409 if exists
346
+ if (res.status !== 201 && res.status !== 409)
347
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
348
+ });
349
+ await test('Get check-ins', async () => {
350
+ const res = await api(state.accessToken).get('/support/check-ins');
351
+ if (res.status !== 200)
352
+ throw new Error(`Status ${res.status}`);
353
+ });
354
+ await test('Get today check-in', async () => {
355
+ const res = await api(state.accessToken).get('/support/check-ins/today');
356
+ if (res.status !== 200 && res.status !== 404)
357
+ throw new Error(`Status ${res.status}`);
358
+ });
359
+ await test('Get check-in streak', async () => {
360
+ const res = await api(state.accessToken).get('/support/check-ins/streak');
361
+ if (res.status !== 200)
362
+ throw new Error(`Status ${res.status}`);
363
+ });
364
+ await test('Log a win', async () => {
365
+ const res = await api(state.accessToken).post('/support/wins', {
366
+ title: 'Completed E2E tests',
367
+ description: 'Successfully ran all API tests',
368
+ category: 'PERSONAL', // Valid: SOBRIETY, HEALTH, RELATIONSHIP, CAREER, PERSONAL, FINANCIAL, OTHER
369
+ });
370
+ if (res.status !== 201)
371
+ throw new Error(`Status ${res.status}: ${JSON.stringify(res.data)}`);
372
+ });
373
+ await test('Get wins', async () => {
374
+ const res = await api(state.accessToken).get('/support/wins');
375
+ if (res.status !== 200)
376
+ throw new Error(`Status ${res.status}`);
377
+ });
378
+ await test('Get wins count', async () => {
379
+ const res = await api(state.accessToken).get('/support/wins/count');
380
+ if (res.status !== 200)
381
+ throw new Error(`Status ${res.status}`);
382
+ });
383
+ // =========================================================================
384
+ // NOTIFICATIONS
385
+ // =========================================================================
386
+ console.log(`\n${c.cyan}--- NOTIFICATIONS ---${c.reset}\n`);
387
+ await test('Get notifications', async () => {
388
+ const res = await api(state.accessToken).get('/notifications');
389
+ if (res.status !== 200)
390
+ throw new Error(`Status ${res.status}`);
391
+ });
392
+ await test('Get unread count', async () => {
393
+ const res = await api(state.accessToken).get('/notifications/unread-count');
394
+ if (res.status !== 200)
395
+ throw new Error(`Status ${res.status}`);
396
+ });
397
+ // =========================================================================
398
+ // SUBSCRIPTIONS
399
+ // =========================================================================
400
+ console.log(`\n${c.cyan}--- SUBSCRIPTIONS ---${c.reset}\n`);
401
+ await test('Get subscription plans', async () => {
402
+ const res = await api(state.accessToken).get('/subscriptions/plans');
403
+ if (res.status !== 200)
404
+ throw new Error(`Status ${res.status}`);
405
+ });
406
+ await test('Get my subscription', async () => {
407
+ const res = await api(state.accessToken).get('/subscriptions/me');
408
+ // 200 if subscribed, 404 if not
409
+ if (res.status !== 200 && res.status !== 404)
410
+ throw new Error(`Status ${res.status}`);
411
+ });
412
+ // =========================================================================
413
+ // LIBRARY
414
+ // =========================================================================
415
+ console.log(`\n${c.cyan}--- LIBRARY ---${c.reset}\n`);
416
+ await test('Get library content', async () => {
417
+ const res = await api(state.accessToken).get('/library');
418
+ if (res.status !== 200)
419
+ throw new Error(`Status ${res.status}`);
420
+ });
421
+ await test('Get featured content', async () => {
422
+ const res = await api(state.accessToken).get('/library/featured');
423
+ if (res.status !== 200)
424
+ throw new Error(`Status ${res.status}`);
425
+ });
426
+ // =========================================================================
427
+ // MAP
428
+ // =========================================================================
429
+ console.log(`\n${c.cyan}--- MAP ---${c.reset}\n`);
430
+ await test('Get map hubs', async () => {
431
+ const res = await api(state.accessToken).get('/map/hubs');
432
+ if (res.status !== 200)
433
+ throw new Error(`Status ${res.status}`);
434
+ });
435
+ await test('Get map events', async () => {
436
+ const res = await api(state.accessToken).get('/map/events');
437
+ if (res.status !== 200)
438
+ throw new Error(`Status ${res.status}`);
439
+ });
440
+ // =========================================================================
441
+ // CLEANUP
442
+ // =========================================================================
443
+ console.log(`\n${c.cyan}--- CLEANUP ---${c.reset}\n`);
444
+ if (state.bookingId) {
445
+ await test('Cancel booking', async () => {
446
+ const res = await api(state.accessToken).delete(`/bookings/${state.bookingId}`);
447
+ if (res.status !== 204 && res.status !== 200)
448
+ throw new Error(`Status ${res.status}`);
449
+ });
450
+ }
451
+ if (state.eventId) {
452
+ await test('Cancel event', async () => {
453
+ const res = await api(state.accessToken).post(`/events/${state.eventId}/cancel`);
454
+ if (res.status !== 200)
455
+ throw new Error(`Status ${res.status}`);
456
+ });
457
+ }
458
+ // =========================================================================
459
+ // SUMMARY
460
+ // =========================================================================
461
+ console.log(`\n${c.cyan}${'='.repeat(60)}${c.reset}`);
462
+ console.log(`${c.cyan} TEST SUMMARY${c.reset}`);
463
+ console.log(`${c.cyan}${'='.repeat(60)}${c.reset}`);
464
+ console.log(`${c.green}Passed: ${passed}${c.reset}`);
465
+ console.log(`${c.red}Failed: ${failed}${c.reset}`);
466
+ console.log(`Total: ${passed + failed}`);
467
+ console.log(`${c.cyan}${'='.repeat(60)}${c.reset}\n`);
468
+ process.exit(failed > 0 ? 1 : 0);
469
+ }
470
+ // Run tests
471
+ runTests().catch(console.error);
472
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTJlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX190ZXN0c19fL2UyZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7Ozs7QUFFSCxrREFBNkM7QUFFN0MsTUFBTSxRQUFRLEdBQUcsOEJBQThCLENBQUM7QUFDaEQsTUFBTSxVQUFVLEdBQUcsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDO0FBQ3JELE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDO0FBRXZDLG9CQUFvQjtBQUNwQixNQUFNLENBQUMsR0FBRztJQUNSLEtBQUssRUFBRSxTQUFTO0lBQ2hCLEtBQUssRUFBRSxVQUFVO0lBQ2pCLEdBQUcsRUFBRSxVQUFVO0lBQ2YsTUFBTSxFQUFFLFVBQVU7SUFDbEIsSUFBSSxFQUFFLFVBQVU7SUFDaEIsR0FBRyxFQUFFLFNBQVM7Q0FDZixDQUFDO0FBRUYsNEJBQTRCO0FBQzVCLE1BQU0sS0FBSyxHQVNQO0lBQ0YsV0FBVyxFQUFFLEVBQUU7SUFDZixZQUFZLEVBQUUsRUFBRTtJQUNoQixNQUFNLEVBQUUsRUFBRTtDQUNYLENBQUM7QUFFRixRQUFRO0FBQ1IsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBRWYsc0JBQXNCO0FBQ3RCLFNBQVMsR0FBRyxDQUFDLEtBQWM7SUFDekIsT0FBTyxlQUFLLENBQUMsTUFBTSxDQUFDO1FBQ2xCLE9BQU8sRUFBRSxRQUFRO1FBQ2pCLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLFVBQVUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUMxRCxjQUFjLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSTtLQUMzQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsY0FBYztBQUNkLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBWSxF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QztBQUNuQyxDQUFDO0FBRUQsWUFBWTtBQUNaLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdyb3dTb2JlciBBUEkgRTJFIFRlc3RzXG4gKlxuICogVGVzdHMgYWxsIFNESyBlbmRwb2ludHMgYWdhaW5zdCB0aGUgcmVhbCBBUEkuXG4gKiBSdW4gd2l0aDogbnB4IHRzLW5vZGUgc3JjL19fdGVzdHNfXy9lMmUudGVzdC50c1xuICovXG5cbmltcG9ydCBheGlvcywgeyBBeGlvc0luc3RhbmNlIH0gZnJvbSAnYXhpb3MnO1xuXG5jb25zdCBCQVNFX1VSTCA9ICdodHRwOi8vbG9jYWxob3N0OjMwMDEvYXBpL3YxJztcbmNvbnN0IFRFU1RfRU1BSUwgPSBgZTJlLSR7RGF0ZS5ub3coKX1AZ3Jvd3NvYmVyLmNvbWA7XG5jb25zdCBURVNUX1BBU1NXT1JEID0gJ1NlY3VyZVBhc3MxMjMhJztcblxuLy8gQ29sb3JzIGZvciBvdXRwdXRcbmNvbnN0IGMgPSB7XG4gIHJlc2V0OiAnXFx4MWJbMG0nLFxuICBncmVlbjogJ1xceDFiWzMybScsXG4gIHJlZDogJ1xceDFiWzMxbScsXG4gIHllbGxvdzogJ1xceDFiWzMzbScsXG4gIGN5YW46ICdcXHgxYlszNm0nLFxuICBkaW06ICdcXHgxYlsybScsXG59O1xuXG4vLyBTdGF0ZSBzaGFyZWQgYWNyb3NzIHRlc3RzXG5jb25zdCBzdGF0ZToge1xuICBhY2Nlc3NUb2tlbjogc3RyaW5nO1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGV2ZW50SWQ/OiBzdHJpbmc7XG4gIGh1YklkPzogc3RyaW5nO1xuICBib29raW5nSWQ/OiBzdHJpbmc7XG4gIGNoYXRJZD86IHN0cmluZztcbiAgY29udmVyc2F0aW9uSWQ/OiBzdHJpbmc7XG59ID0ge1xuICBhY2Nlc3NUb2tlbjogJycsXG4gIHJlZnJlc2hUb2tlbjogJycsXG4gIHVzZXJJZDogJycsXG59O1xuXG4vLyBTdGF0c1xubGV0IHBhc3NlZCA9IDA7XG5sZXQgZmFpbGVkID0gMDtcblxuLy8gQ3JlYXRlIGF4aW9zIGNsaWVudFxuZnVuY3Rpb24gYXBpKHRva2VuPzogc3RyaW5nKTogQXhpb3NJbnN0YW5jZSB7XG4gIHJldHVybiBheGlvcy5jcmVhdGUoe1xuICAgIGJhc2VVUkw6IEJBU0VfVVJMLFxuICAgIGhlYWRlcnM6IHRva2VuID8geyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7dG9rZW59YCB9IDoge30sXG4gICAgdmFsaWRhdGVTdGF0dXM6ICgpID0+IHRydWUsXG4gIH0pO1xufVxuXG4vLyBUZXN0IHJ1bm5lclxuYXN5bmMgZnVuY3Rpb24gdGVzdChuYW1lOiBzdHJpbmcsIGZuOiAoKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmbigpO1xuICAgIGNvbnNvbGUubG9nKGAke2MuZ3JlZW59UEFTUyR7Yy5yZXNldH0gJHtuYW1lfSAke2MuZGltfSgke0RhdGUubm93KCkgLSBzdGFydH1tcykke2MucmVzZXR9YCk7XG4gICAgcGFzc2VkKys7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnNvbGUubG9nKGAke2MucmVkfUZBSUwke2MucmVzZXR9ICR7bmFtZX0gJHtjLmRpbX0oJHtEYXRlLm5vdygpIC0gc3RhcnR9bXMpJHtjLnJlc2V0fWApO1xuICAgIGNvbnNvbGUubG9nKGAgICR7Yy55ZWxsb3d9JHtlLm1lc3NhZ2V9JHtjLnJlc2V0fWApO1xuICAgIGZhaWxlZCsrO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vLyBVbndyYXAgQVBJIHJlc3BvbnNlXG5mdW5jdGlvbiB1bndyYXA8VD4ocmVzOiB7IGRhdGE6IHsgZGF0YTogVCB9IH0pOiBUIHtcbiAgcmV0dXJuIHJlcy5kYXRhLmRhdGE7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRFU1RTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzKCkge1xuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59JHsnPScucmVwZWF0KDYwKX0ke2MucmVzZXR9YCk7XG4gIGNvbnNvbGUubG9nKGAke2MuY3lhbn0gIEdyb3dTb2JlciBBUEkgRTJFIFRlc3RzJHtjLnJlc2V0fWApO1xuICBjb25zb2xlLmxvZyhgJHtjLmN5YW59JHsnPScucmVwZWF0KDYwKX0ke2MucmVzZXR9YCk7XG4gIGNvbnNvbGUubG9nKGAke2MuZGltfUJhc2UgVVJMOiAke0JBU0VfVVJMfSR7Yy5yZXNldH1gKTtcbiAgY29uc29sZS5sb2coYCR7Yy5kaW19VGVzdCBFbWFpbDogJHtURVNUX0VNQUlMfSR7Yy5yZXNldH1cXG5gKTtcblxuICAvLyBIZWFsdGggY2hlY2tcbiAgY29uc3QgaGVhbHRoID0gYXdhaXQgYXBpKCkuZ2V0KCcvaGVhbHRoJyk7XG4gIGlmIChoZWFsdGguc3RhdHVzICE9PSAyMDApIHtcbiAgICBjb25zb2xlLmxvZyhgJHtjLnJlZH1BUEkgaXMgbm90IHJlYWNoYWJsZSR7Yy5yZXNldH1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgY29uc29sZS5sb2coYCR7Yy5ncmVlbn1BUEkgaXMgaGVhbHRoeSR7Yy5yZXNldH1cXG5gKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEFVVEhcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIEFVVEhFTlRJQ0FUSU9OIC0tLSR7Yy5yZXNldH1cXG5gKTtcblxuICBhd2FpdCB0ZXN0KCdSZWdpc3RlciBuZXcgdXNlcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoKS5wb3N0KCcvYXV0aC9yZWdpc3RlcicsIHtcbiAgICAgIGVtYWlsOiBURVNUX0VNQUlMLFxuICAgICAgcGFzc3dvcmQ6IFRFU1RfUEFTU1dPUkQsXG4gICAgICBuYW1lOiAnRTJFIFRlc3QgVXNlcicsXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMSkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfTogJHtKU09OLnN0cmluZ2lmeShyZXMuZGF0YSl9YCk7XG4gICAgY29uc3QgZGF0YSA9IHVud3JhcDxhbnk+KHJlcyk7XG4gICAgc3RhdGUuYWNjZXNzVG9rZW4gPSBkYXRhLmFjY2Vzc1Rva2VuO1xuICAgIHN0YXRlLnJlZnJlc2hUb2tlbiA9IGRhdGEucmVmcmVzaFRva2VuO1xuICAgIHN0YXRlLnVzZXJJZCA9IGRhdGEudXNlci5pZDtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnTG9naW4gd2l0aCBlbWFpbCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoKS5wb3N0KCcvYXV0aC9sb2dpbicsIHtcbiAgICAgIGVtYWlsOiBURVNUX0VNQUlMLFxuICAgICAgcGFzc3dvcmQ6IFRFU1RfUEFTU1dPUkQsXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICAgIGNvbnN0IGRhdGEgPSB1bndyYXA8YW55PihyZXMpO1xuICAgIHN0YXRlLmFjY2Vzc1Rva2VuID0gZGF0YS5hY2Nlc3NUb2tlbjtcbiAgICBzdGF0ZS5yZWZyZXNoVG9rZW4gPSBkYXRhLnJlZnJlc2hUb2tlbjtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnUmVmcmVzaCB0b2tlbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoKS5wb3N0KCcvYXV0aC9yZWZyZXNoJywge1xuICAgICAgcmVmcmVzaFRva2VuOiBzdGF0ZS5yZWZyZXNoVG9rZW4sXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfTogJHtKU09OLnN0cmluZ2lmeShyZXMuZGF0YSl9YCk7XG4gICAgY29uc3QgZGF0YSA9IHVud3JhcDxhbnk+KHJlcyk7XG4gICAgc3RhdGUuYWNjZXNzVG9rZW4gPSBkYXRhLmFjY2Vzc1Rva2VuO1xuICAgIHN0YXRlLnJlZnJlc2hUb2tlbiA9IGRhdGEucmVmcmVzaFRva2VuO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgY3VycmVudCB1c2VyIChhdXRoL21lKScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL2F1dGgvbWUnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0ludmFsaWQgbG9naW4gcmV0dXJucyA0MDEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKCkucG9zdCgnL2F1dGgvbG9naW4nLCB7XG4gICAgICBlbWFpbDogVEVTVF9FTUFJTCxcbiAgICAgIHBhc3N3b3JkOiAnV3JvbmdQYXNzd29yZCcsXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDQwMSkgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCA0MDEsIGdvdCAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gVVNFUlNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIFVTRVJTIC0tLSR7Yy5yZXNldH1cXG5gKTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgY3VycmVudCB1c2VyIHByb2ZpbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy91c2Vycy9tZScpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnVXBkYXRlIHByb2ZpbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5wdXQoJy91c2Vycy9tZScsIHtcbiAgICAgIG5hbWU6ICdVcGRhdGVkIEUyRSBVc2VyJyxcbiAgICAgIGJpbzogJ0UyRSB0ZXN0IGJpbycsXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfTogJHtKU09OLnN0cmluZ2lmeShyZXMuZGF0YSl9YCk7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCB1c2VyIGJ5IElEJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KGAvdXNlcnMvJHtzdGF0ZS51c2VySWR9YCk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgdXNlciBwdWJsaWMgcHJvZmlsZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldChgL3VzZXJzLyR7c3RhdGUudXNlcklkfS9wdWJsaWNgKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gRVZFTlRTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc29sZS5sb2coYFxcbiR7Yy5jeWFufS0tLSBFVkVOVFMgLS0tJHtjLnJlc2V0fVxcbmApO1xuXG4gIGF3YWl0IHRlc3QoJ0xpc3QgZXZlbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaSgpLmdldCgnL2V2ZW50cycpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IHVwY29taW5nIGV2ZW50cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoKS5nZXQoJy9ldmVudHMvdXBjb21pbmcnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0NyZWF0ZSBldmVudCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLnBvc3QoJy9ldmVudHMnLCB7XG4gICAgICB0aXRsZTogJ0UyRSBUZXN0IEV2ZW50JyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQSB0ZXN0IGV2ZW50IGNyZWF0ZWQgYnkgRTJFIHRlc3RzJyxcbiAgICAgIHN0YXJ0RGF0ZTogbmV3IERhdGUoRGF0ZS5ub3coKSArIDcgKiAyNCAqIDYwICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLCAvLyA3IGRheXMgZnJvbSBub3dcbiAgICAgIHRvdGFsU3BvdHM6IDIwLFxuICAgICAgbG9jYXRpb25OYW1lOiAnVGVzdCBMb2NhdGlvbicsXG4gICAgICBsb2NhdGlvbkFkZHJlc3M6ICcxMjMgVGVzdCBTdHJlZXQnLFxuICAgIH0pO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEpIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICAgIGNvbnN0IGRhdGEgPSB1bndyYXA8YW55PihyZXMpO1xuICAgIHN0YXRlLmV2ZW50SWQgPSBkYXRhLmlkO1xuICB9KTtcblxuICBpZiAoc3RhdGUuZXZlbnRJZCkge1xuICAgIGF3YWl0IHRlc3QoJ0dldCBldmVudCBieSBJRCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaSgpLmdldChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9YCk7XG4gICAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0ZXN0KCdVcGRhdGUgZXZlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLnB1dChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9YCwge1xuICAgICAgICB0aXRsZTogJ0UyRSBUZXN0IEV2ZW50IChVcGRhdGVkKScsXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgdGVzdCgnUHVibGlzaCBldmVudCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L3B1Ymxpc2hgKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgICB9KTtcblxuICAgIGF3YWl0IHRlc3QoJ0dldCBteSBldmVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL2V2ZW50cy9teS1ldmVudHMnKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQk9PS0lOR1NcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIEJPT0tJTkdTIC0tLSR7Yy5yZXNldH1cXG5gKTtcblxuICBpZiAoc3RhdGUuZXZlbnRJZCkge1xuICAgIGF3YWl0IHRlc3QoJ1JTVlAgdG8gZXZlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLnBvc3QoYC9ldmVudHMvJHtzdGF0ZS5ldmVudElkfS9ib29rYCk7XG4gICAgICAvLyAyMDEgZm9yIG5ldyBib29raW5nLCA0MDkgaWYgYWxyZWFkeSBleGlzdHNcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEgJiYgcmVzLnN0YXR1cyAhPT0gNDA5KSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9OiAke0pTT04uc3RyaW5naWZ5KHJlcy5kYXRhKX1gKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzID09PSAyMDEpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHVud3JhcDxhbnk+KHJlcyk7XG4gICAgICAgIHN0YXRlLmJvb2tpbmdJZCA9IGRhdGEuaWQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0ZXN0KCdHZXQgbXkgYm9va2luZ3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL2Jvb2tpbmdzL21lJyk7XG4gICAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEVWRU5UIENIQVRcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIEVWRU5UIENIQVQgLS0tJHtjLnJlc2V0fVxcbmApO1xuXG4gIGlmIChzdGF0ZS5ldmVudElkKSB7XG4gICAgYXdhaXQgdGVzdCgnR2V0IG9yIGNyZWF0ZSBldmVudCBjaGF0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoYC9ldmVudHMvJHtzdGF0ZS5ldmVudElkfS9jaGF0YCk7XG4gICAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9OiAke0pTT04uc3RyaW5naWZ5KHJlcy5kYXRhKX1gKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB1bndyYXA8YW55PihyZXMpO1xuICAgICAgc3RhdGUuY2hhdElkID0gZGF0YS5pZDtcbiAgICB9KTtcblxuICAgIGF3YWl0IHRlc3QoJ0pvaW4gZXZlbnQgY2hhdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L2NoYXQvam9pbmApO1xuICAgICAgLy8gMjAwIGZvciBqb2luLCA0MDMgaWYgbm8gYm9va2luZyAoYnV0IHdlIGp1c3QgYm9va2VkKVxuICAgICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfTogJHtKU09OLnN0cmluZ2lmeShyZXMuZGF0YSl9YCk7XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0ZXN0KCdTZW5kIGNoYXQgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L2NoYXQvbWVzc2FnZXNgLCB7XG4gICAgICAgIGNvbnRlbnQ6ICdIZWxsbyBmcm9tIEUyRSB0ZXN0IScsXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEpIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgdGVzdCgnR2V0IGNoYXQgbWVzc2FnZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L2NoYXQvbWVzc2FnZXNgKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgdGVzdCgnR2V0IGNoYXQgbWVtYmVycycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KGAvZXZlbnRzLyR7c3RhdGUuZXZlbnRJZH0vY2hhdC9tZW1iZXJzYCk7XG4gICAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0ZXN0KCdNYXJrIGNoYXQgYXMgcmVhZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L2NoYXQvcmVhZGApO1xuICAgICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwNCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBIVUJTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc29sZS5sb2coYFxcbiR7Yy5jeWFufS0tLSBIVUJTIC0tLSR7Yy5yZXNldH1cXG5gKTtcblxuICBhd2FpdCB0ZXN0KCdMaXN0IGh1YnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKCkuZ2V0KCcvaHVicycpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgICAvLyBHZXQgZmlyc3QgaHViIGlmIGV4aXN0c1xuICAgIGNvbnN0IGRhdGEgPSByZXMuZGF0YS5kYXRhO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpICYmIGRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgc3RhdGUuaHViSWQgPSBkYXRhWzBdLmlkO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKHN0YXRlLmh1YklkKSB7XG4gICAgYXdhaXQgdGVzdCgnR2V0IGh1YiBieSBJRCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaSgpLmdldChgL2h1YnMvJHtzdGF0ZS5odWJJZH1gKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgICB9KTtcblxuICAgIGF3YWl0IHRlc3QoJ0pvaW4gaHViJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5wb3N0KGAvaHVicy8ke3N0YXRlLmh1YklkfS9qb2luYCk7XG4gICAgICAvLyAyMDAvMjAxIGZvciBqb2luLCA0MDkgaWYgYWxyZWFkeSBtZW1iZXJcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDAgJiYgcmVzLnN0YXR1cyAhPT0gMjAxICYmIHJlcy5zdGF0dXMgIT09IDQwOSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9OiAke0pTT04uc3RyaW5naWZ5KHJlcy5kYXRhKX1gKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGF3YWl0IHRlc3QoJ0dldCBodWIgbWVtYmVycycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KGAvaHVicy8ke3N0YXRlLmh1YklkfS9tZW1iZXJzYCk7XG4gICAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEpBQ0sgQUkgKFN1cHBvcnQgQ29udmVyc2F0aW9ucylcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIEpBQ0sgQUkgLS0tJHtjLnJlc2V0fVxcbmApO1xuXG4gIGF3YWl0IHRlc3QoJ1N0YXJ0IEphY2sgY29udmVyc2F0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdCgnL3N1cHBvcnQvamFjay9jb252ZXJzYXRpb25zL25ldycsIHtcbiAgICAgIG1lc3NhZ2U6ICdIZWxsbyBKYWNrIScsXG4gICAgfSk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMSAmJiByZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICAgIGNvbnN0IGRhdGEgPSB1bndyYXA8YW55PihyZXMpO1xuICAgIHN0YXRlLmNvbnZlcnNhdGlvbklkID0gZGF0YS5jb252ZXJzYXRpb24/LmlkIHx8IGRhdGEuaWQ7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCBKYWNrIGNvbnZlcnNhdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy9zdXBwb3J0L2phY2svY29udmVyc2F0aW9ucycpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IEphY2sgY2hhdCBoaXN0b3J5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KCcvc3VwcG9ydC9qYWNrL2hpc3RvcnknKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIGlmIChzdGF0ZS5jb252ZXJzYXRpb25JZCkge1xuICAgIGF3YWl0IHRlc3QoJ0dldCBKYWNrIGNvbnZlcnNhdGlvbiBieSBJRCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KGAvc3VwcG9ydC9qYWNrL2NvbnZlcnNhdGlvbnMvJHtzdGF0ZS5jb252ZXJzYXRpb25JZH1gKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU1VQUE9SVCAoQ2hlY2staW5zLCBXaW5zKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGNvbnNvbGUubG9nKGBcXG4ke2MuY3lhbn0tLS0gU1VQUE9SVCAtLS0ke2MucmVzZXR9XFxuYCk7XG5cbiAgYXdhaXQgdGVzdCgnQ3JlYXRlIGRhaWx5IGNoZWNrLWluJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdCgnL3N1cHBvcnQvY2hlY2staW5zJywge1xuICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0sXG4gICAgICBtb29kOiA0LCAvLyBWYWxpZCByYW5nZSAxLTVcbiAgICAgIGVuZXJneTogNCwgLy8gVmFsaWQgcmFuZ2UgMS01XG4gICAgICBzdGF5ZWRTb2JlcjogdHJ1ZSxcbiAgICAgIG5vdGVzOiAnRTJFIHRlc3QgY2hlY2staW4nLFxuICAgIH0pO1xuICAgIC8vIDIwMSBmb3IgbmV3LCA0MDkgaWYgZXhpc3RzXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMSAmJiByZXMuc3RhdHVzICE9PSA0MDkpIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgY2hlY2staW5zJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KCcvc3VwcG9ydC9jaGVjay1pbnMnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCB0b2RheSBjaGVjay1pbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL3N1cHBvcnQvY2hlY2staW5zL3RvZGF5Jyk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCAmJiByZXMuc3RhdHVzICE9PSA0MDQpIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IGNoZWNrLWluIHN0cmVhaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL3N1cHBvcnQvY2hlY2staW5zL3N0cmVhaycpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnTG9nIGEgd2luJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdCgnL3N1cHBvcnQvd2lucycsIHtcbiAgICAgIHRpdGxlOiAnQ29tcGxldGVkIEUyRSB0ZXN0cycsXG4gICAgICBkZXNjcmlwdGlvbjogJ1N1Y2Nlc3NmdWxseSByYW4gYWxsIEFQSSB0ZXN0cycsXG4gICAgICBjYXRlZ29yeTogJ1BFUlNPTkFMJywgLy8gVmFsaWQ6IFNPQlJJRVRZLCBIRUFMVEgsIFJFTEFUSU9OU0hJUCwgQ0FSRUVSLCBQRVJTT05BTCwgRklOQU5DSUFMLCBPVEhFUlxuICAgIH0pO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEpIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c306ICR7SlNPTi5zdHJpbmdpZnkocmVzLmRhdGEpfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgd2lucycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL3N1cHBvcnQvd2lucycpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihgU3RhdHVzICR7cmVzLnN0YXR1c31gKTtcbiAgfSk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IHdpbnMgY291bnQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy9zdXBwb3J0L3dpbnMvY291bnQnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gTk9USUZJQ0FUSU9OU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGNvbnNvbGUubG9nKGBcXG4ke2MuY3lhbn0tLS0gTk9USUZJQ0FUSU9OUyAtLS0ke2MucmVzZXR9XFxuYCk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IG5vdGlmaWNhdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy9ub3RpZmljYXRpb25zJyk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgdW5yZWFkIGNvdW50JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikuZ2V0KCcvbm90aWZpY2F0aW9ucy91bnJlYWQtY291bnQnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU1VCU0NSSVBUSU9OU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGNvbnNvbGUubG9nKGBcXG4ke2MuY3lhbn0tLS0gU1VCU0NSSVBUSU9OUyAtLS0ke2MucmVzZXR9XFxuYCk7XG5cbiAgYXdhaXQgdGVzdCgnR2V0IHN1YnNjcmlwdGlvbiBwbGFucycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL3N1YnNjcmlwdGlvbnMvcGxhbnMnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCBteSBzdWJzY3JpcHRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy9zdWJzY3JpcHRpb25zL21lJyk7XG4gICAgLy8gMjAwIGlmIHN1YnNjcmliZWQsIDQwNCBpZiBub3RcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwICYmIHJlcy5zdGF0dXMgIT09IDQwNCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICB9KTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIExJQlJBUllcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zb2xlLmxvZyhgXFxuJHtjLmN5YW59LS0tIExJQlJBUlkgLS0tJHtjLnJlc2V0fVxcbmApO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCBsaWJyYXJ5IGNvbnRlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5nZXQoJy9saWJyYXJ5Jyk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgZmVhdHVyZWQgY29udGVudCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL2xpYnJhcnkvZmVhdHVyZWQnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gTUFQXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc29sZS5sb2coYFxcbiR7Yy5jeWFufS0tLSBNQVAgLS0tJHtjLnJlc2V0fVxcbmApO1xuXG4gIGF3YWl0IHRlc3QoJ0dldCBtYXAgaHVicycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL21hcC9odWJzJyk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICB9KTtcblxuICBhd2FpdCB0ZXN0KCdHZXQgbWFwIGV2ZW50cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkoc3RhdGUuYWNjZXNzVG9rZW4pLmdldCgnL21hcC9ldmVudHMnKTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQ0xFQU5VUFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGNvbnNvbGUubG9nKGBcXG4ke2MuY3lhbn0tLS0gQ0xFQU5VUCAtLS0ke2MucmVzZXR9XFxuYCk7XG5cbiAgaWYgKHN0YXRlLmJvb2tpbmdJZCkge1xuICAgIGF3YWl0IHRlc3QoJ0NhbmNlbCBib29raW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpKHN0YXRlLmFjY2Vzc1Rva2VuKS5kZWxldGUoYC9ib29raW5ncy8ke3N0YXRlLmJvb2tpbmdJZH1gKTtcbiAgICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDQgJiYgcmVzLnN0YXR1cyAhPT0gMjAwKSB0aHJvdyBuZXcgRXJyb3IoYFN0YXR1cyAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoc3RhdGUuZXZlbnRJZCkge1xuICAgIGF3YWl0IHRlc3QoJ0NhbmNlbCBldmVudCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaShzdGF0ZS5hY2Nlc3NUb2tlbikucG9zdChgL2V2ZW50cy8ke3N0YXRlLmV2ZW50SWR9L2NhbmNlbGApO1xuICAgICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKGBTdGF0dXMgJHtyZXMuc3RhdHVzfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTVU1NQVJZXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc29sZS5sb2coYFxcbiR7Yy5jeWFufSR7Jz0nLnJlcGVhdCg2MCl9JHtjLnJlc2V0fWApO1xuICBjb25zb2xlLmxvZyhgJHtjLmN5YW59ICBURVNUIFNVTU1BUlkke2MucmVzZXR9YCk7XG4gIGNvbnNvbGUubG9nKGAke2MuY3lhbn0keyc9Jy5yZXBlYXQoNjApfSR7Yy5yZXNldH1gKTtcbiAgY29uc29sZS5sb2coYCR7Yy5ncmVlbn1QYXNzZWQ6ICR7cGFzc2VkfSR7Yy5yZXNldH1gKTtcbiAgY29uc29sZS5sb2coYCR7Yy5yZWR9RmFpbGVkOiAke2ZhaWxlZH0ke2MucmVzZXR9YCk7XG4gIGNvbnNvbGUubG9nKGBUb3RhbDogICR7cGFzc2VkICsgZmFpbGVkfWApO1xuICBjb25zb2xlLmxvZyhgJHtjLmN5YW59JHsnPScucmVwZWF0KDYwKX0ke2MucmVzZXR9XFxuYCk7XG5cbiAgcHJvY2Vzcy5leGl0KGZhaWxlZCA+IDAgPyAxIDogMCk7XG59XG5cbi8vIFJ1biB0ZXN0c1xucnVuVGVzdHMoKS5jYXRjaChjb25zb2xlLmVycm9yKTtcbiJdfQ==
@@ -0,0 +1,11 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export interface SDKConfig {
3
+ baseURL: string;
4
+ getAccessToken: () => string | null | Promise<string | null>;
5
+ refreshAccessToken?: () => Promise<string>;
6
+ onUnauthorized?: () => void;
7
+ }
8
+ declare let apiClient: AxiosInstance | null;
9
+ export declare function configureSDK(sdkConfig: SDKConfig): void;
10
+ export declare function getApiClient(): AxiosInstance;
11
+ export { apiClient };