@chirpier/chirpier-js 0.2.1 → 0.4.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.
- package/README.md +42 -10
- package/dist/__tests__/chirpier.test.js +410 -7
- package/dist/index.d.ts +67 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +227 -14
- package/package.json +1 -1
- package/src/__tests__/chirpier.test.ts +267 -6
- package/src/index.ts +232 -16
package/README.md
CHANGED
|
@@ -76,6 +76,11 @@ Default servicer endpoint is `https://api.chirpier.co/v1.0`.
|
|
|
76
76
|
The same bearer token is used for both ingest and servicer APIs.
|
|
77
77
|
Queued logs are not dropped locally because of queue capacity or retry exhaustion.
|
|
78
78
|
|
|
79
|
+
### Retry behavior
|
|
80
|
+
|
|
81
|
+
The SDK retries network/transport failures, `429` responses, and retryable `5xx` responses such as `502` and `504`.
|
|
82
|
+
It does not retry `401`, `403`, `404`, `500`, or `503`, and `401`/`403` errors surface the Chirpier response message when available.
|
|
83
|
+
|
|
79
84
|
### `logEvent(log)`
|
|
80
85
|
|
|
81
86
|
Queues a log for batched delivery.
|
|
@@ -124,6 +129,7 @@ Client methods:
|
|
|
124
129
|
- `client.close()`: Alias of `client.shutdown()`.
|
|
125
130
|
- `client.listEvents()`: List event definitions using the servicer API.
|
|
126
131
|
- `client.getEvent(eventID)`: Read one event definition.
|
|
132
|
+
- `client.getEventAnalytics(eventID, query)`: Read analytics window comparisons.
|
|
127
133
|
- `client.updateEvent(eventID, payload)`: Update event definition metadata.
|
|
128
134
|
- `client.listPolicies()`: List monitors/policies.
|
|
129
135
|
- `client.createPolicy(payload)`: Create a monitor/policy.
|
|
@@ -132,7 +138,7 @@ Client methods:
|
|
|
132
138
|
- `client.acknowledgeAlert(alertID)`: Acknowledge an alert.
|
|
133
139
|
- `client.resolveAlert(alertID)`: Resolve an alert.
|
|
134
140
|
- `client.archiveAlert(alertID)`: Archive an alert.
|
|
135
|
-
- `client.
|
|
141
|
+
- `client.testDestination(destinationID)`: Send a destination test and return the synthetic test `alert_id`.
|
|
136
142
|
- `client.getEventLogs(eventID, { period, limit, offset })`: Read minute/hour/day event rollups.
|
|
137
143
|
<!-- docs:end common-tasks -->
|
|
138
144
|
|
|
@@ -155,10 +161,20 @@ await client.log({
|
|
|
155
161
|
meta: { task_name: "daily_digest" },
|
|
156
162
|
});
|
|
157
163
|
|
|
164
|
+
await client.flush();
|
|
165
|
+
|
|
158
166
|
const events = await client.listEvents();
|
|
159
|
-
const toolErrors = events.find(
|
|
167
|
+
const toolErrors = events.find(
|
|
168
|
+
(eventDef) => eventDef.agent === "openclaw.main" && eventDef.event === "tool.errors.count"
|
|
169
|
+
);
|
|
160
170
|
|
|
161
171
|
if (toolErrors) {
|
|
172
|
+
const analytics = await client.getEventAnalytics(toolErrors.event_id, {
|
|
173
|
+
view: "window",
|
|
174
|
+
period: "1h",
|
|
175
|
+
previous: "previous_window",
|
|
176
|
+
});
|
|
177
|
+
|
|
162
178
|
await client.createPolicy({
|
|
163
179
|
event_id: toolErrors.event_id,
|
|
164
180
|
title: "OpenClaw tool errors spike",
|
|
@@ -172,6 +188,17 @@ if (toolErrors) {
|
|
|
172
188
|
});
|
|
173
189
|
|
|
174
190
|
await client.getEventLogs(toolErrors.event_id, { period: "hour", limit: 24 });
|
|
191
|
+
|
|
192
|
+
const destination = await client.createDestination({
|
|
193
|
+
channel: "slack",
|
|
194
|
+
url: "https://hooks.slack.com/services/T000/B000/secret",
|
|
195
|
+
scope: "all",
|
|
196
|
+
policy_ids: [],
|
|
197
|
+
enabled: true,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const test = await client.testDestination(destination.destination_id);
|
|
201
|
+
await client.getAlertDeliveries(test.alert_id, { kind: "test" });
|
|
175
202
|
}
|
|
176
203
|
|
|
177
204
|
await client.shutdown();
|
|
@@ -187,16 +214,18 @@ Flushes pending logs and stops the SDK singleton.
|
|
|
187
214
|
npm test
|
|
188
215
|
```
|
|
189
216
|
|
|
190
|
-
##
|
|
217
|
+
## Destination Setup Examples
|
|
191
218
|
|
|
192
|
-
Create a Slack
|
|
219
|
+
Create a Slack destination for OpenClaw alerts:
|
|
193
220
|
|
|
194
221
|
```ts
|
|
195
222
|
await axios.post(
|
|
196
|
-
"https://api.chirpier.co/v1.0/
|
|
223
|
+
"https://api.chirpier.co/v1.0/destinations",
|
|
197
224
|
{
|
|
198
225
|
url: "https://hooks.slack.com/services/T000/B000/secret",
|
|
199
|
-
|
|
226
|
+
channel: "slack",
|
|
227
|
+
scope: "all",
|
|
228
|
+
policy_ids: [],
|
|
200
229
|
enabled: true,
|
|
201
230
|
},
|
|
202
231
|
{
|
|
@@ -205,14 +234,16 @@ await axios.post(
|
|
|
205
234
|
);
|
|
206
235
|
```
|
|
207
236
|
|
|
208
|
-
Create a Telegram
|
|
237
|
+
Create a Telegram destination for OpenClaw alerts:
|
|
209
238
|
|
|
210
239
|
```ts
|
|
211
240
|
await axios.post(
|
|
212
|
-
"https://api.chirpier.co/v1.0/
|
|
241
|
+
"https://api.chirpier.co/v1.0/destinations",
|
|
213
242
|
{
|
|
214
|
-
|
|
243
|
+
channel: "telegram",
|
|
215
244
|
enabled: true,
|
|
245
|
+
scope: "all",
|
|
246
|
+
policy_ids: [],
|
|
216
247
|
credentials: {
|
|
217
248
|
bot_token: "123456:telegram-bot-token",
|
|
218
249
|
chat_id: "987654321",
|
|
@@ -227,5 +258,6 @@ await axios.post(
|
|
|
227
258
|
Send a test notification:
|
|
228
259
|
|
|
229
260
|
```ts
|
|
230
|
-
await client.
|
|
261
|
+
const result = await client.testDestination("whk_123");
|
|
262
|
+
await client.getAlertDeliveries(result.alert_id, { kind: "test" });
|
|
231
263
|
```
|
|
@@ -50,7 +50,10 @@ describe("Chirpier SDK", function () {
|
|
|
50
50
|
afterEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
51
51
|
return __generator(this, function (_a) {
|
|
52
52
|
switch (_a.label) {
|
|
53
|
-
case 0:
|
|
53
|
+
case 0:
|
|
54
|
+
jest.useRealTimers();
|
|
55
|
+
jest.restoreAllMocks();
|
|
56
|
+
return [4 /*yield*/, (0, index_1.stop)()];
|
|
54
57
|
case 1:
|
|
55
58
|
_a.sent();
|
|
56
59
|
return [2 /*return*/];
|
|
@@ -450,6 +453,306 @@ describe("Chirpier SDK", function () {
|
|
|
450
453
|
}
|
|
451
454
|
});
|
|
452
455
|
}); });
|
|
456
|
+
test("retries network errors", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
457
|
+
var client, axiosBackedClient, attempts, flushPromise;
|
|
458
|
+
return __generator(this, function (_a) {
|
|
459
|
+
switch (_a.label) {
|
|
460
|
+
case 0:
|
|
461
|
+
jest.useFakeTimers();
|
|
462
|
+
client = (0, index_1.createClient)({
|
|
463
|
+
key: "chp_network_retry_key",
|
|
464
|
+
retries: 2,
|
|
465
|
+
flushDelay: 10000,
|
|
466
|
+
});
|
|
467
|
+
axiosBackedClient = client;
|
|
468
|
+
attempts = 0;
|
|
469
|
+
axiosBackedClient.axiosInstance.defaults.adapter = function (config) { return __awaiter(void 0, void 0, void 0, function () {
|
|
470
|
+
return __generator(this, function (_a) {
|
|
471
|
+
attempts += 1;
|
|
472
|
+
if (attempts < 3) {
|
|
473
|
+
throw Object.assign(new Error("Network Error"), {
|
|
474
|
+
code: "ECONNRESET",
|
|
475
|
+
config: config,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
return [2 /*return*/, {
|
|
479
|
+
data: { success: true },
|
|
480
|
+
status: 200,
|
|
481
|
+
statusText: "OK",
|
|
482
|
+
headers: {},
|
|
483
|
+
config: config,
|
|
484
|
+
}];
|
|
485
|
+
});
|
|
486
|
+
}); };
|
|
487
|
+
_a.label = 1;
|
|
488
|
+
case 1:
|
|
489
|
+
_a.trys.push([1, , 5, 7]);
|
|
490
|
+
return [4 /*yield*/, client.log({ event: "network.retry", value: 1 })];
|
|
491
|
+
case 2:
|
|
492
|
+
_a.sent();
|
|
493
|
+
flushPromise = client.flush();
|
|
494
|
+
return [4 /*yield*/, jest.runAllTimersAsync()];
|
|
495
|
+
case 3:
|
|
496
|
+
_a.sent();
|
|
497
|
+
return [4 /*yield*/, expect(flushPromise).resolves.toBeUndefined()];
|
|
498
|
+
case 4:
|
|
499
|
+
_a.sent();
|
|
500
|
+
expect(attempts).toBe(3);
|
|
501
|
+
return [3 /*break*/, 7];
|
|
502
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
503
|
+
case 6:
|
|
504
|
+
_a.sent();
|
|
505
|
+
return [7 /*endfinally*/];
|
|
506
|
+
case 7: return [2 /*return*/];
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}); });
|
|
510
|
+
test("retries 429 responses", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
511
|
+
var mock, client, flushPromise;
|
|
512
|
+
return __generator(this, function (_a) {
|
|
513
|
+
switch (_a.label) {
|
|
514
|
+
case 0:
|
|
515
|
+
jest.useFakeTimers();
|
|
516
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
517
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(429, { error: "rate limited" }, { "retry-after": "1" });
|
|
518
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(429, { error: "rate limited" }, { "retry-after": "1" });
|
|
519
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(200, { success: true });
|
|
520
|
+
client = (0, index_1.createClient)({
|
|
521
|
+
key: "chp_rate_limit_key",
|
|
522
|
+
retries: 2,
|
|
523
|
+
flushDelay: 10000,
|
|
524
|
+
});
|
|
525
|
+
_a.label = 1;
|
|
526
|
+
case 1:
|
|
527
|
+
_a.trys.push([1, , 5, 7]);
|
|
528
|
+
return [4 /*yield*/, client.log({ event: "rate.limit", value: 1 })];
|
|
529
|
+
case 2:
|
|
530
|
+
_a.sent();
|
|
531
|
+
flushPromise = client.flush();
|
|
532
|
+
return [4 /*yield*/, jest.runAllTimersAsync()];
|
|
533
|
+
case 3:
|
|
534
|
+
_a.sent();
|
|
535
|
+
return [4 /*yield*/, expect(flushPromise).resolves.toBeUndefined()];
|
|
536
|
+
case 4:
|
|
537
|
+
_a.sent();
|
|
538
|
+
expect(mock.history.post.length).toBe(3);
|
|
539
|
+
return [3 /*break*/, 7];
|
|
540
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
541
|
+
case 6:
|
|
542
|
+
_a.sent();
|
|
543
|
+
return [7 /*endfinally*/];
|
|
544
|
+
case 7: return [2 /*return*/];
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
}); });
|
|
548
|
+
test("does not retry 401 and logs the Chirpier response message", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
549
|
+
var mock, errorSpy, client;
|
|
550
|
+
return __generator(this, function (_a) {
|
|
551
|
+
switch (_a.label) {
|
|
552
|
+
case 0:
|
|
553
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
554
|
+
errorSpy = jest.spyOn(console, "error").mockImplementation(function () { return undefined; });
|
|
555
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(401, { error: "invalid api key" });
|
|
556
|
+
client = (0, index_1.createClient)({
|
|
557
|
+
key: "chp_unauthorized_key",
|
|
558
|
+
retries: 3,
|
|
559
|
+
flushDelay: 10000,
|
|
560
|
+
logLevel: 1 /* LogLevel.Error */,
|
|
561
|
+
});
|
|
562
|
+
_a.label = 1;
|
|
563
|
+
case 1:
|
|
564
|
+
_a.trys.push([1, , 5, 7]);
|
|
565
|
+
return [4 /*yield*/, client.log({ event: "auth.failed", value: 1 })];
|
|
566
|
+
case 2:
|
|
567
|
+
_a.sent();
|
|
568
|
+
return [4 /*yield*/, client.flush()];
|
|
569
|
+
case 3:
|
|
570
|
+
_a.sent();
|
|
571
|
+
return [4 /*yield*/, client.flush()];
|
|
572
|
+
case 4:
|
|
573
|
+
_a.sent();
|
|
574
|
+
expect(mock.history.post.length).toBe(1);
|
|
575
|
+
expect(errorSpy).toHaveBeenCalledWith("Chirpier API returned 401: invalid api key");
|
|
576
|
+
return [3 /*break*/, 7];
|
|
577
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
578
|
+
case 6:
|
|
579
|
+
_a.sent();
|
|
580
|
+
return [7 /*endfinally*/];
|
|
581
|
+
case 7: return [2 /*return*/];
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}); });
|
|
585
|
+
test("does not retry 403 and logs the Chirpier response message", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
586
|
+
var mock, errorSpy, client;
|
|
587
|
+
return __generator(this, function (_a) {
|
|
588
|
+
switch (_a.label) {
|
|
589
|
+
case 0:
|
|
590
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
591
|
+
errorSpy = jest.spyOn(console, "error").mockImplementation(function () { return undefined; });
|
|
592
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(403, { message: "project is disabled" });
|
|
593
|
+
client = (0, index_1.createClient)({
|
|
594
|
+
key: "chp_forbidden_key",
|
|
595
|
+
retries: 3,
|
|
596
|
+
flushDelay: 10000,
|
|
597
|
+
logLevel: 1 /* LogLevel.Error */,
|
|
598
|
+
});
|
|
599
|
+
_a.label = 1;
|
|
600
|
+
case 1:
|
|
601
|
+
_a.trys.push([1, , 5, 7]);
|
|
602
|
+
return [4 /*yield*/, client.log({ event: "auth.forbidden", value: 1 })];
|
|
603
|
+
case 2:
|
|
604
|
+
_a.sent();
|
|
605
|
+
return [4 /*yield*/, client.flush()];
|
|
606
|
+
case 3:
|
|
607
|
+
_a.sent();
|
|
608
|
+
return [4 /*yield*/, client.flush()];
|
|
609
|
+
case 4:
|
|
610
|
+
_a.sent();
|
|
611
|
+
expect(mock.history.post.length).toBe(1);
|
|
612
|
+
expect(errorSpy).toHaveBeenCalledWith("Chirpier API returned 403: project is disabled");
|
|
613
|
+
return [3 /*break*/, 7];
|
|
614
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
615
|
+
case 6:
|
|
616
|
+
_a.sent();
|
|
617
|
+
return [7 /*endfinally*/];
|
|
618
|
+
case 7: return [2 /*return*/];
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
}); });
|
|
622
|
+
test.each([404, 500, 503])("does not retry non-retryable status %s", function (status) { return __awaiter(void 0, void 0, void 0, function () {
|
|
623
|
+
var mock, client;
|
|
624
|
+
return __generator(this, function (_a) {
|
|
625
|
+
switch (_a.label) {
|
|
626
|
+
case 0:
|
|
627
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
628
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(status, { error: "http ".concat(status) });
|
|
629
|
+
client = (0, index_1.createClient)({
|
|
630
|
+
key: "chp_non_retryable_".concat(status),
|
|
631
|
+
retries: 3,
|
|
632
|
+
flushDelay: 10000,
|
|
633
|
+
});
|
|
634
|
+
_a.label = 1;
|
|
635
|
+
case 1:
|
|
636
|
+
_a.trys.push([1, , 5, 7]);
|
|
637
|
+
return [4 /*yield*/, client.log({ event: "non.retryable.".concat(status), value: 1 })];
|
|
638
|
+
case 2:
|
|
639
|
+
_a.sent();
|
|
640
|
+
return [4 /*yield*/, client.flush()];
|
|
641
|
+
case 3:
|
|
642
|
+
_a.sent();
|
|
643
|
+
return [4 /*yield*/, client.flush()];
|
|
644
|
+
case 4:
|
|
645
|
+
_a.sent();
|
|
646
|
+
expect(mock.history.post.length).toBe(1);
|
|
647
|
+
return [3 /*break*/, 7];
|
|
648
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
649
|
+
case 6:
|
|
650
|
+
_a.sent();
|
|
651
|
+
return [7 /*endfinally*/];
|
|
652
|
+
case 7: return [2 /*return*/];
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}); });
|
|
656
|
+
test("retries 502 responses", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
657
|
+
var mock, client, flushPromise;
|
|
658
|
+
return __generator(this, function (_a) {
|
|
659
|
+
switch (_a.label) {
|
|
660
|
+
case 0:
|
|
661
|
+
jest.useFakeTimers();
|
|
662
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
663
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(502, { error: "bad gateway" });
|
|
664
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(502, { error: "bad gateway" });
|
|
665
|
+
mock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(200, { success: true });
|
|
666
|
+
client = (0, index_1.createClient)({
|
|
667
|
+
key: "chp_bad_gateway_key",
|
|
668
|
+
retries: 2,
|
|
669
|
+
flushDelay: 10000,
|
|
670
|
+
});
|
|
671
|
+
_a.label = 1;
|
|
672
|
+
case 1:
|
|
673
|
+
_a.trys.push([1, , 5, 7]);
|
|
674
|
+
return [4 /*yield*/, client.log({ event: "bad.gateway", value: 1 })];
|
|
675
|
+
case 2:
|
|
676
|
+
_a.sent();
|
|
677
|
+
flushPromise = client.flush();
|
|
678
|
+
return [4 /*yield*/, jest.runAllTimersAsync()];
|
|
679
|
+
case 3:
|
|
680
|
+
_a.sent();
|
|
681
|
+
return [4 /*yield*/, expect(flushPromise).resolves.toBeUndefined()];
|
|
682
|
+
case 4:
|
|
683
|
+
_a.sent();
|
|
684
|
+
expect(mock.history.post.length).toBe(3);
|
|
685
|
+
return [3 /*break*/, 7];
|
|
686
|
+
case 5: return [4 /*yield*/, client.shutdown()];
|
|
687
|
+
case 6:
|
|
688
|
+
_a.sent();
|
|
689
|
+
return [7 /*endfinally*/];
|
|
690
|
+
case 7: return [2 /*return*/];
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
}); });
|
|
694
|
+
test("flush requeues only retryable failures", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
695
|
+
var retryableMock, retryableClient, nonRetryableMock, nonRetryableClient;
|
|
696
|
+
return __generator(this, function (_a) {
|
|
697
|
+
switch (_a.label) {
|
|
698
|
+
case 0:
|
|
699
|
+
retryableMock = new axios_mock_adapter_1.default(axios_1.default);
|
|
700
|
+
retryableMock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(502, { error: "bad gateway" });
|
|
701
|
+
retryableMock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(200, { success: true });
|
|
702
|
+
retryableClient = (0, index_1.createClient)({
|
|
703
|
+
key: "chp_retryable_requeue_key",
|
|
704
|
+
retries: 0,
|
|
705
|
+
flushDelay: 10000,
|
|
706
|
+
});
|
|
707
|
+
_a.label = 1;
|
|
708
|
+
case 1:
|
|
709
|
+
_a.trys.push([1, , 5, 7]);
|
|
710
|
+
return [4 /*yield*/, retryableClient.log({ event: "retryable.requeue", value: 1 })];
|
|
711
|
+
case 2:
|
|
712
|
+
_a.sent();
|
|
713
|
+
return [4 /*yield*/, retryableClient.flush()];
|
|
714
|
+
case 3:
|
|
715
|
+
_a.sent();
|
|
716
|
+
return [4 /*yield*/, retryableClient.flush()];
|
|
717
|
+
case 4:
|
|
718
|
+
_a.sent();
|
|
719
|
+
expect(retryableMock.history.post.length).toBe(2);
|
|
720
|
+
return [3 /*break*/, 7];
|
|
721
|
+
case 5: return [4 /*yield*/, retryableClient.shutdown()];
|
|
722
|
+
case 6:
|
|
723
|
+
_a.sent();
|
|
724
|
+
return [7 /*endfinally*/];
|
|
725
|
+
case 7:
|
|
726
|
+
nonRetryableMock = new axios_mock_adapter_1.default(axios_1.default);
|
|
727
|
+
nonRetryableMock.onPost(constants_1.DEFAULT_API_ENDPOINT).replyOnce(404, { error: "not found" });
|
|
728
|
+
nonRetryableClient = (0, index_1.createClient)({
|
|
729
|
+
key: "chp_non_retryable_requeue_key",
|
|
730
|
+
retries: 0,
|
|
731
|
+
flushDelay: 10000,
|
|
732
|
+
logLevel: 0 /* LogLevel.None */,
|
|
733
|
+
});
|
|
734
|
+
_a.label = 8;
|
|
735
|
+
case 8:
|
|
736
|
+
_a.trys.push([8, , 12, 14]);
|
|
737
|
+
return [4 /*yield*/, nonRetryableClient.log({ event: "non.retryable.drop", value: 1 })];
|
|
738
|
+
case 9:
|
|
739
|
+
_a.sent();
|
|
740
|
+
return [4 /*yield*/, nonRetryableClient.flush()];
|
|
741
|
+
case 10:
|
|
742
|
+
_a.sent();
|
|
743
|
+
return [4 /*yield*/, nonRetryableClient.flush()];
|
|
744
|
+
case 11:
|
|
745
|
+
_a.sent();
|
|
746
|
+
expect(nonRetryableMock.history.post.length).toBe(1);
|
|
747
|
+
return [3 /*break*/, 14];
|
|
748
|
+
case 12: return [4 /*yield*/, nonRetryableClient.shutdown()];
|
|
749
|
+
case 13:
|
|
750
|
+
_a.sent();
|
|
751
|
+
return [7 /*endfinally*/];
|
|
752
|
+
case 14: return [2 /*return*/];
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
}); });
|
|
453
756
|
test("getEventLogs uses servicer endpoint with period, limit, and offset", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
454
757
|
var mock, client;
|
|
455
758
|
return __generator(this, function (_a) {
|
|
@@ -474,6 +777,66 @@ describe("Chirpier SDK", function () {
|
|
|
474
777
|
}
|
|
475
778
|
});
|
|
476
779
|
}); });
|
|
780
|
+
test("event, policy, alert, and destination helpers use servicer endpoints", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
781
|
+
var mock, client, createdEvent, policy, alert_1, destination, updatedDestination;
|
|
782
|
+
return __generator(this, function (_a) {
|
|
783
|
+
switch (_a.label) {
|
|
784
|
+
case 0:
|
|
785
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
786
|
+
mock.onPost("https://api.chirpier.co/v1.0/events").reply(200, { event_id: "evt_123", event: "tool.errors.count", public: false, timezone: "UTC" });
|
|
787
|
+
mock.onGet("https://api.chirpier.co/v1.0/events/evt_123").reply(200, { event_id: "evt_123", event: "tool.errors.count", public: false, timezone: "UTC" });
|
|
788
|
+
mock.onGet("https://api.chirpier.co/v1.0/policies/pol_123").reply(200, { policy_id: "pol_123", event_id: "evt_123", title: "Policy", channel: "ops", period: "hour", aggregate: "sum", condition: "gt", threshold: 1, severity: "warning", enabled: true });
|
|
789
|
+
mock.onPut("https://api.chirpier.co/v1.0/policies/pol_123").reply(200, { policy_id: "pol_123", event_id: "evt_123", title: "Updated", channel: "ops", period: "hour", aggregate: "sum", condition: "gt", threshold: 1, severity: "warning", enabled: true });
|
|
790
|
+
mock.onGet("https://api.chirpier.co/v1.0/alerts/alrt_123").reply(200, { alert_id: "alrt_123", policy_id: "pol_123", event_id: "evt_123", event: "tool.errors.count", title: "Alert", channel: "ops", period: "hour", aggregate: "sum", condition: "gt", threshold: 1, severity: "warning", status: "triggered", value: 2, count: 2, min: 1, max: 1 });
|
|
791
|
+
mock.onGet("https://api.chirpier.co/v1.0/destinations").reply(200, []);
|
|
792
|
+
mock.onPost("https://api.chirpier.co/v1.0/destinations").reply(200, { destination_id: "dst_123", channel: "slack", scope: "all", enabled: true });
|
|
793
|
+
mock.onGet("https://api.chirpier.co/v1.0/destinations/dst_123").reply(200, { destination_id: "dst_123", channel: "slack", scope: "all", enabled: true });
|
|
794
|
+
mock.onPut("https://api.chirpier.co/v1.0/destinations/dst_123").reply(200, { destination_id: "dst_123", channel: "slack", scope: "all", enabled: false });
|
|
795
|
+
client = (0, index_1.createClient)({ key: "chp_client_route_key" });
|
|
796
|
+
_a.label = 1;
|
|
797
|
+
case 1:
|
|
798
|
+
_a.trys.push([1, , 11, 13]);
|
|
799
|
+
return [4 /*yield*/, client.createEvent({ event: "tool.errors.count" })];
|
|
800
|
+
case 2:
|
|
801
|
+
createdEvent = _a.sent();
|
|
802
|
+
expect(createdEvent.event_id).toBe("evt_123");
|
|
803
|
+
return [4 /*yield*/, client.getEvent("evt_123")];
|
|
804
|
+
case 3:
|
|
805
|
+
_a.sent();
|
|
806
|
+
return [4 /*yield*/, client.getPolicy("pol_123")];
|
|
807
|
+
case 4:
|
|
808
|
+
policy = _a.sent();
|
|
809
|
+
expect(policy.policy_id).toBe("pol_123");
|
|
810
|
+
return [4 /*yield*/, client.updatePolicy("pol_123", { title: "Updated" })];
|
|
811
|
+
case 5:
|
|
812
|
+
_a.sent();
|
|
813
|
+
return [4 /*yield*/, client.getAlert("alrt_123")];
|
|
814
|
+
case 6:
|
|
815
|
+
alert_1 = _a.sent();
|
|
816
|
+
expect(alert_1.alert_id).toBe("alrt_123");
|
|
817
|
+
return [4 /*yield*/, client.listDestinations()];
|
|
818
|
+
case 7:
|
|
819
|
+
_a.sent();
|
|
820
|
+
return [4 /*yield*/, client.createDestination({ channel: "slack", scope: "all", enabled: true })];
|
|
821
|
+
case 8:
|
|
822
|
+
destination = _a.sent();
|
|
823
|
+
expect(destination.destination_id).toBe("dst_123");
|
|
824
|
+
return [4 /*yield*/, client.getDestination("dst_123")];
|
|
825
|
+
case 9:
|
|
826
|
+
_a.sent();
|
|
827
|
+
return [4 /*yield*/, client.updateDestination("dst_123", { enabled: false })];
|
|
828
|
+
case 10:
|
|
829
|
+
updatedDestination = _a.sent();
|
|
830
|
+
expect(updatedDestination.enabled).toBe(false);
|
|
831
|
+
return [3 /*break*/, 13];
|
|
832
|
+
case 11: return [4 /*yield*/, client.shutdown()];
|
|
833
|
+
case 12:
|
|
834
|
+
_a.sent();
|
|
835
|
+
return [7 /*endfinally*/];
|
|
836
|
+
case 13: return [2 /*return*/];
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
}); });
|
|
477
840
|
test("getAlertDeliveries uses pagination params", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
478
841
|
var mock, client;
|
|
479
842
|
return __generator(this, function (_a) {
|
|
@@ -522,21 +885,61 @@ describe("Chirpier SDK", function () {
|
|
|
522
885
|
}
|
|
523
886
|
});
|
|
524
887
|
}); });
|
|
525
|
-
test("
|
|
526
|
-
var mock, client;
|
|
888
|
+
test("testDestination posts to servicer endpoint", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
889
|
+
var mock, client, result;
|
|
527
890
|
return __generator(this, function (_a) {
|
|
528
891
|
switch (_a.label) {
|
|
529
892
|
case 0:
|
|
530
893
|
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
531
|
-
mock.onPost("https://api.chirpier.co/v1.0/
|
|
532
|
-
|
|
894
|
+
mock.onPost("https://api.chirpier.co/v1.0/destinations/whk_123/test").reply(200, {
|
|
895
|
+
alert_id: "alrt_123",
|
|
896
|
+
destination_id: "whk_123",
|
|
897
|
+
status: "sent",
|
|
898
|
+
});
|
|
899
|
+
client = (0, index_1.createClient)({ key: "chp_client_destination_key" });
|
|
533
900
|
_a.label = 1;
|
|
534
901
|
case 1:
|
|
535
902
|
_a.trys.push([1, , 3, 5]);
|
|
536
|
-
return [4 /*yield*/, client.
|
|
903
|
+
return [4 /*yield*/, client.testDestination("whk_123")];
|
|
537
904
|
case 2:
|
|
905
|
+
result = _a.sent();
|
|
906
|
+
expect(result.alert_id).toBe("alrt_123");
|
|
907
|
+
expect(mock.history.post[0].url).toBe("https://api.chirpier.co/v1.0/destinations/whk_123/test");
|
|
908
|
+
return [3 /*break*/, 5];
|
|
909
|
+
case 3: return [4 /*yield*/, client.shutdown()];
|
|
910
|
+
case 4:
|
|
538
911
|
_a.sent();
|
|
539
|
-
|
|
912
|
+
return [7 /*endfinally*/];
|
|
913
|
+
case 5: return [2 /*return*/];
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
}); });
|
|
917
|
+
test("getEventAnalytics uses analytics endpoint", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
918
|
+
var mock, client, analytics;
|
|
919
|
+
return __generator(this, function (_a) {
|
|
920
|
+
switch (_a.label) {
|
|
921
|
+
case 0:
|
|
922
|
+
mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
923
|
+
mock.onGet("https://api.chirpier.co/v1.0/events/evt_123/analytics?view=window&period=1h&previous=previous_window").reply(200, {
|
|
924
|
+
event_id: "evt_123",
|
|
925
|
+
view: "window",
|
|
926
|
+
period: "1h",
|
|
927
|
+
previous: "previous_window",
|
|
928
|
+
data: null,
|
|
929
|
+
});
|
|
930
|
+
client = (0, index_1.createClient)({ key: "chp_client_analytics_key" });
|
|
931
|
+
_a.label = 1;
|
|
932
|
+
case 1:
|
|
933
|
+
_a.trys.push([1, , 3, 5]);
|
|
934
|
+
return [4 /*yield*/, client.getEventAnalytics("evt_123", {
|
|
935
|
+
view: "window",
|
|
936
|
+
period: "1h",
|
|
937
|
+
previous: "previous_window",
|
|
938
|
+
})];
|
|
939
|
+
case 2:
|
|
940
|
+
analytics = _a.sent();
|
|
941
|
+
expect(analytics.event_id).toBe("evt_123");
|
|
942
|
+
expect(mock.history.get[0].url).toBe("https://api.chirpier.co/v1.0/events/evt_123/analytics?view=window&period=1h&previous=previous_window");
|
|
540
943
|
return [3 /*break*/, 5];
|
|
541
944
|
case 3: return [4 /*yield*/, client.shutdown()];
|
|
542
945
|
case 4:
|