@chirpier/chirpier-js 0.1.5 → 0.2.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 +180 -108
- package/dist/__tests__/chirpier.test.js +395 -96
- package/dist/constants.d.ts +7 -6
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -4
- package/dist/index.d.ts +132 -56
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +478 -193
- package/package.json +2 -2
- package/src/__tests__/chirpier.test.ts +265 -93
- package/src/constants.ts +7 -6
- package/src/index.ts +495 -189
package/dist/index.js
CHANGED
|
@@ -14,6 +14,17 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
15
|
};
|
|
16
16
|
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
17
28
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
29
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
30
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -63,26 +74,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
63
74
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
64
75
|
};
|
|
65
76
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
|
-
exports.
|
|
67
|
-
// Import necessary dependencies
|
|
77
|
+
exports.flush = exports.stop = exports.logEvent = exports.initialize = exports.createClient = exports.Client = exports.ChirpierError = void 0;
|
|
68
78
|
var axios_1 = __importDefault(require("axios"));
|
|
69
79
|
var axios_retry_1 = __importDefault(require("axios-retry"));
|
|
70
|
-
var
|
|
80
|
+
var dotenv_1 = __importDefault(require("dotenv"));
|
|
71
81
|
var constants_1 = require("./constants");
|
|
72
82
|
var async_lock_1 = __importDefault(require("async-lock"));
|
|
73
|
-
// Define logging levels
|
|
74
|
-
var LogLevel;
|
|
75
|
-
(function (LogLevel) {
|
|
76
|
-
LogLevel[LogLevel["None"] = 0] = "None";
|
|
77
|
-
LogLevel[LogLevel["Error"] = 1] = "Error";
|
|
78
|
-
LogLevel[LogLevel["Info"] = 2] = "Info";
|
|
79
|
-
LogLevel[LogLevel["Debug"] = 3] = "Debug";
|
|
80
|
-
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
|
|
81
83
|
// Custom error class for Chirpier-specific errors
|
|
82
84
|
var ChirpierError = /** @class */ (function (_super) {
|
|
83
85
|
__extends(ChirpierError, _super);
|
|
84
|
-
function ChirpierError(message) {
|
|
86
|
+
function ChirpierError(message, code) {
|
|
85
87
|
var _this = _super.call(this, message) || this;
|
|
88
|
+
_this.code = code;
|
|
86
89
|
_this.name = "ChirpierError";
|
|
87
90
|
Object.setPrototypeOf(_this, ChirpierError.prototype);
|
|
88
91
|
return _this;
|
|
@@ -90,113 +93,166 @@ var ChirpierError = /** @class */ (function (_super) {
|
|
|
90
93
|
return ChirpierError;
|
|
91
94
|
}(Error));
|
|
92
95
|
exports.ChirpierError = ChirpierError;
|
|
93
|
-
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Initializes a new instance of the Chirpier class.
|
|
99
|
-
* @param options - Configuration options for the SDK.
|
|
100
|
-
*/
|
|
101
|
-
function Chirpier(options) {
|
|
102
|
-
this.eventQueue = [];
|
|
96
|
+
var Client = /** @class */ (function () {
|
|
97
|
+
function Client(options) {
|
|
98
|
+
if (options === void 0) { options = {}; }
|
|
99
|
+
this.logQueue = [];
|
|
103
100
|
this.flushTimeoutId = null;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
var providedKey = options.key, _a = options.apiEndpoint, apiEndpoint = _a === void 0 ? constants_1.DEFAULT_API_ENDPOINT : _a, _b = options.servicerEndpoint, servicerEndpoint = _b === void 0 ? constants_1.DEFAULT_SERVICER_ENDPOINT : _b, _c = options.logLevel, logLevel = _c === void 0 ? 0 /* LogLevel.None */ : _c, _d = options.retries, retries = _d === void 0 ? constants_1.DEFAULT_RETRIES : _d, _e = options.timeout, timeout = _e === void 0 ? constants_1.DEFAULT_TIMEOUT : _e, _f = options.batchSize, batchSize = _f === void 0 ? constants_1.DEFAULT_BATCH_SIZE : _f, _g = options.flushDelay, flushDelay = _g === void 0 ? constants_1.DEFAULT_FLUSH_DELAY : _g, _h = options.maxQueueSize, maxQueueSize = _h === void 0 ? constants_1.MAX_QUEUE_SIZE : _h;
|
|
102
|
+
var key = resolveAPIKey(providedKey);
|
|
103
|
+
if (!key) {
|
|
104
|
+
throw new ChirpierError("API key is required", "INVALID_KEY");
|
|
105
|
+
}
|
|
106
|
+
if (!isValidAPIKey(key)) {
|
|
107
|
+
throw new ChirpierError("Invalid API key: must start with 'chp_'", "INVALID_KEY");
|
|
108
|
+
}
|
|
109
|
+
if (apiEndpoint !== undefined) {
|
|
110
|
+
if (typeof apiEndpoint !== "string" || apiEndpoint.trim().length === 0) {
|
|
111
|
+
throw new ChirpierError("apiEndpoint must be a non-empty string", "INVALID_API_ENDPOINT");
|
|
112
|
+
}
|
|
113
|
+
var parsedURL = void 0;
|
|
114
|
+
try {
|
|
115
|
+
parsedURL = new URL(apiEndpoint);
|
|
116
|
+
}
|
|
117
|
+
catch (_j) {
|
|
118
|
+
throw new ChirpierError("apiEndpoint must be a valid absolute URL", "INVALID_API_ENDPOINT");
|
|
119
|
+
}
|
|
120
|
+
if (parsedURL.protocol !== "https:" && parsedURL.protocol !== "http:") {
|
|
121
|
+
throw new ChirpierError("apiEndpoint must use http or https", "INVALID_API_ENDPOINT");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Validate numeric options
|
|
125
|
+
if (retries < 0 || !Number.isInteger(retries)) {
|
|
126
|
+
throw new ChirpierError("Retries must be a non-negative integer", "INVALID_RETRIES");
|
|
127
|
+
}
|
|
128
|
+
if (timeout <= 0) {
|
|
129
|
+
throw new ChirpierError("Timeout must be positive", "INVALID_TIMEOUT");
|
|
130
|
+
}
|
|
131
|
+
if (batchSize <= 0 || !Number.isInteger(batchSize)) {
|
|
132
|
+
throw new ChirpierError("Batch size must be a positive integer", "INVALID_BATCH_SIZE");
|
|
109
133
|
}
|
|
110
|
-
if (
|
|
111
|
-
throw new ChirpierError("
|
|
134
|
+
if (flushDelay < 0) {
|
|
135
|
+
throw new ChirpierError("Flush delay must be non-negative", "INVALID_FLUSH_DELAY");
|
|
112
136
|
}
|
|
113
|
-
|
|
137
|
+
if (maxQueueSize <= 0 || !Number.isInteger(maxQueueSize)) {
|
|
138
|
+
throw new ChirpierError("Max queue size must be a positive integer", "INVALID_QUEUE_SIZE");
|
|
139
|
+
}
|
|
140
|
+
this.apiEndpoint = apiEndpoint !== null && apiEndpoint !== void 0 ? apiEndpoint : constants_1.DEFAULT_API_ENDPOINT;
|
|
141
|
+
this.servicerEndpoint = servicerEndpoint !== null && servicerEndpoint !== void 0 ? servicerEndpoint : constants_1.DEFAULT_SERVICER_ENDPOINT;
|
|
114
142
|
this.apiKey = key;
|
|
115
|
-
this.retries =
|
|
116
|
-
this.timeout =
|
|
117
|
-
this.batchSize =
|
|
118
|
-
this.flushDelay =
|
|
143
|
+
this.retries = retries;
|
|
144
|
+
this.timeout = timeout;
|
|
145
|
+
this.batchSize = batchSize;
|
|
146
|
+
this.flushDelay = flushDelay;
|
|
147
|
+
this.maxQueueSize = maxQueueSize;
|
|
119
148
|
this.logLevel = logLevel;
|
|
120
|
-
|
|
149
|
+
this.queueLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
|
|
150
|
+
this.flushLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
|
|
121
151
|
this.axiosInstance = axios_1.default.create({
|
|
122
152
|
headers: { Authorization: "Bearer ".concat(this.apiKey) },
|
|
123
153
|
timeout: this.timeout,
|
|
124
154
|
});
|
|
125
|
-
|
|
126
|
-
this.axiosInstance.interceptors.response.use(function (response) { return response; }, function (error) {
|
|
127
|
-
// Don't handle the error here; let axios-retry handle it
|
|
128
|
-
return Promise.reject(error);
|
|
129
|
-
});
|
|
130
|
-
// Apply axios-retry to your Axios instance
|
|
155
|
+
this.axiosInstance.interceptors.response.use(function (response) { return response; }, function (error) { return Promise.reject(error); });
|
|
131
156
|
(0, axios_retry_1.default)(this.axiosInstance, {
|
|
132
157
|
retries: this.retries,
|
|
133
158
|
retryDelay: function (retryCount) {
|
|
134
|
-
|
|
159
|
+
var baseDelay = Math.pow(2, retryCount) * 1000;
|
|
160
|
+
var jitter = Math.random() * 0.3 * baseDelay;
|
|
161
|
+
return baseDelay + jitter;
|
|
135
162
|
},
|
|
136
163
|
retryCondition: function (error) {
|
|
137
|
-
// Retry on network errors, 5xx errors, and 429 (Too Many Requests)
|
|
138
164
|
return (axios_retry_1.default.isNetworkError(error) ||
|
|
139
165
|
axios_retry_1.default.isRetryableError(error) ||
|
|
140
|
-
(
|
|
166
|
+
(error.response && error.response.status) === 429);
|
|
141
167
|
},
|
|
142
168
|
shouldResetTimeout: true,
|
|
143
169
|
});
|
|
144
170
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
Client.prototype.isValidLog = function (log) {
|
|
172
|
+
var now = Date.now();
|
|
173
|
+
var oldestAllowed = now - 30 * 24 * 60 * 60 * 1000;
|
|
174
|
+
var newestAllowed = now + 24 * 60 * 60 * 1000;
|
|
175
|
+
if (typeof log.event !== "string" || log.event.trim().length === 0) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
if (typeof log.value !== "number" || !Number.isFinite(log.value)) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
if (log.agent_id !== undefined && typeof log.agent_id !== "string") {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
if (log.meta !== undefined) {
|
|
185
|
+
try {
|
|
186
|
+
var serializedMeta = JSON.stringify(log.meta);
|
|
187
|
+
if (serializedMeta === undefined) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (_a) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (log.occurred_at !== undefined) {
|
|
196
|
+
var occurredAtMillis = log.occurred_at instanceof Date
|
|
197
|
+
? log.occurred_at.getTime()
|
|
198
|
+
: new Date(log.occurred_at).getTime();
|
|
199
|
+
if (!Number.isFinite(occurredAtMillis)) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
if (occurredAtMillis < oldestAllowed || occurredAtMillis > newestAllowed) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
153
205
|
}
|
|
154
|
-
return
|
|
206
|
+
return true;
|
|
155
207
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
208
|
+
Client.prototype.normalizeLog = function (log) {
|
|
209
|
+
var normalizedLog = {
|
|
210
|
+
event: log.event.trim(),
|
|
211
|
+
value: log.value,
|
|
212
|
+
};
|
|
213
|
+
if (typeof log.agent_id === "string") {
|
|
214
|
+
var trimmedAgentID = log.agent_id.trim();
|
|
215
|
+
if (trimmedAgentID.length > 0) {
|
|
216
|
+
normalizedLog.agent_id = trimmedAgentID;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (log.meta !== undefined) {
|
|
220
|
+
normalizedLog.meta = log.meta;
|
|
221
|
+
}
|
|
222
|
+
if (log.occurred_at !== undefined) {
|
|
223
|
+
var occurredAtDate = log.occurred_at instanceof Date ? log.occurred_at : new Date(log.occurred_at);
|
|
224
|
+
normalizedLog.occurred_at = occurredAtDate.toISOString();
|
|
225
|
+
}
|
|
226
|
+
return normalizedLog;
|
|
168
227
|
};
|
|
169
|
-
|
|
170
|
-
* Monitors an event by adding it to the queue and scheduling a flush if necessary.
|
|
171
|
-
* @param event - The event to monitor.
|
|
172
|
-
*/
|
|
173
|
-
Chirpier.prototype.monitor = function (event) {
|
|
228
|
+
Client.prototype.log = function (log) {
|
|
174
229
|
return __awaiter(this, void 0, void 0, function () {
|
|
230
|
+
var normalizedLog, queueFull;
|
|
175
231
|
var _this = this;
|
|
176
232
|
return __generator(this, function (_a) {
|
|
177
233
|
switch (_a.label) {
|
|
178
234
|
case 0:
|
|
179
|
-
if (!this.
|
|
180
|
-
|
|
181
|
-
console.debug("Invalid event format, dropping event:", event);
|
|
182
|
-
}
|
|
183
|
-
return [2 /*return*/]; // Silently drop the event
|
|
235
|
+
if (!this.isValidLog(log)) {
|
|
236
|
+
throw new ChirpierError("Invalid log format: event must not be empty, value must be a finite number, agent_id must be a string when provided, meta must be JSON-encodable, and occurred_at must be within the last 30 days and no more than 1 day in the future", "INVALID_LOG");
|
|
184
237
|
}
|
|
238
|
+
normalizedLog = this.normalizeLog(log);
|
|
239
|
+
queueFull = false;
|
|
185
240
|
return [4 /*yield*/, this.queueLock.acquire("queue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
186
241
|
return __generator(this, function (_a) {
|
|
187
|
-
if (this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
return [2 /*return*/]; // Silently drop the event
|
|
242
|
+
if (this.logQueue.length >= this.maxQueueSize) {
|
|
243
|
+
queueFull = true;
|
|
244
|
+
return [2 /*return*/];
|
|
192
245
|
}
|
|
193
|
-
this.
|
|
246
|
+
this.logQueue.push({ log: normalizedLog, timestamp: Date.now(), retryCount: 0 });
|
|
194
247
|
return [2 /*return*/];
|
|
195
248
|
});
|
|
196
249
|
}); })];
|
|
197
250
|
case 1:
|
|
198
251
|
_a.sent();
|
|
199
|
-
if (
|
|
252
|
+
if (queueFull) {
|
|
253
|
+
throw new ChirpierError("Log queue is full (max size: ".concat(this.maxQueueSize, ")"), "QUEUE_FULL");
|
|
254
|
+
}
|
|
255
|
+
if (!(this.logQueue.length >= this.batchSize)) return [3 /*break*/, 3];
|
|
200
256
|
return [4 /*yield*/, this.flushQueue()];
|
|
201
257
|
case 2:
|
|
202
258
|
_a.sent();
|
|
@@ -211,84 +267,70 @@ var Chirpier = /** @class */ (function () {
|
|
|
211
267
|
});
|
|
212
268
|
});
|
|
213
269
|
};
|
|
214
|
-
|
|
215
|
-
* Flushes the event queue by sending all events to the API.
|
|
216
|
-
*/
|
|
217
|
-
Chirpier.prototype.flushQueue = function () {
|
|
270
|
+
Client.prototype.flushQueue = function () {
|
|
218
271
|
return __awaiter(this, void 0, void 0, function () {
|
|
219
272
|
var _this = this;
|
|
220
273
|
return __generator(this, function (_a) {
|
|
221
274
|
switch (_a.label) {
|
|
222
|
-
case 0:
|
|
223
|
-
|
|
224
|
-
return [4 /*yield*/, this.flushLock.acquire("flush", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
225
|
-
var eventsToSend, error_1, retryableEvents_1, _i, eventsToSend_1, queuedEvent;
|
|
275
|
+
case 0: return [4 /*yield*/, this.flushLock.acquire("flush", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
276
|
+
var logsToSend, error_1, retryableLogs_1, _i, logsToSend_1, queuedLog;
|
|
226
277
|
var _this = this;
|
|
227
278
|
return __generator(this, function (_a) {
|
|
228
279
|
switch (_a.label) {
|
|
229
280
|
case 0:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return [4 /*yield*/, this.queueLock.acquire("eventQueue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
281
|
+
logsToSend = [];
|
|
282
|
+
return [4 /*yield*/, this.queueLock.acquire("logQueue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
233
283
|
return __generator(this, function (_a) {
|
|
234
|
-
if (this.
|
|
235
|
-
|
|
236
|
-
this.
|
|
284
|
+
if (this.logQueue.length > 0) {
|
|
285
|
+
logsToSend = __spreadArray([], this.logQueue, true);
|
|
286
|
+
this.logQueue = [];
|
|
237
287
|
}
|
|
238
288
|
return [2 /*return*/];
|
|
239
289
|
});
|
|
240
290
|
}); })];
|
|
241
291
|
case 1:
|
|
242
|
-
// Extract events from the queue under the queue lock
|
|
243
292
|
_a.sent();
|
|
244
|
-
if (
|
|
293
|
+
if (logsToSend.length === 0) {
|
|
245
294
|
return [2 /*return*/];
|
|
246
295
|
}
|
|
247
296
|
_a.label = 2;
|
|
248
297
|
case 2:
|
|
249
298
|
_a.trys.push([2, 4, , 6]);
|
|
250
|
-
// Clear any pending flush timeout
|
|
251
299
|
if (this.flushTimeoutId) {
|
|
252
300
|
clearTimeout(this.flushTimeoutId);
|
|
253
301
|
this.flushTimeoutId = null;
|
|
254
302
|
}
|
|
255
|
-
|
|
256
|
-
return [4 /*yield*/, this.sendEvents(eventsToSend.map(function (qe) { return qe.event; }))];
|
|
303
|
+
return [4 /*yield*/, this.sendLogs(logsToSend.map(function (queuedLog) { return queuedLog.log; }))];
|
|
257
304
|
case 3:
|
|
258
|
-
// Attempt to send events
|
|
259
305
|
_a.sent();
|
|
260
|
-
if (this.logLevel >= LogLevel.Info) {
|
|
261
|
-
console.info("Successfully sent ".concat(
|
|
306
|
+
if (this.logLevel >= 2 /* LogLevel.Info */) {
|
|
307
|
+
console.info("Successfully sent ".concat(logsToSend.length, " logs"));
|
|
262
308
|
}
|
|
263
309
|
return [3 /*break*/, 6];
|
|
264
310
|
case 4:
|
|
265
311
|
error_1 = _a.sent();
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
console.error("Failed to send events:", error_1);
|
|
312
|
+
if (this.logLevel >= 1 /* LogLevel.Error */) {
|
|
313
|
+
console.error("Failed to send logs:", error_1);
|
|
269
314
|
}
|
|
270
|
-
|
|
271
|
-
for (_i = 0,
|
|
272
|
-
|
|
273
|
-
if (
|
|
274
|
-
if (this.logLevel >= LogLevel.Error) {
|
|
275
|
-
console.error("Dropping
|
|
315
|
+
retryableLogs_1 = [];
|
|
316
|
+
for (_i = 0, logsToSend_1 = logsToSend; _i < logsToSend_1.length; _i++) {
|
|
317
|
+
queuedLog = logsToSend_1[_i];
|
|
318
|
+
if (queuedLog.retryCount >= this.retries) {
|
|
319
|
+
if (this.logLevel >= 1 /* LogLevel.Error */) {
|
|
320
|
+
console.error("Dropping log after ".concat(this.retries, " retries:"), queuedLog.log);
|
|
276
321
|
}
|
|
277
|
-
continue;
|
|
322
|
+
continue;
|
|
278
323
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
retryableEvents_1.push(queuedEvent);
|
|
324
|
+
queuedLog.retryCount++;
|
|
325
|
+
retryableLogs_1.push(queuedLog);
|
|
282
326
|
}
|
|
283
|
-
|
|
284
|
-
return [4 /*yield*/, this.queueLock.acquire("eventQueue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
327
|
+
return [4 /*yield*/, this.queueLock.acquire("logQueue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
285
328
|
return __generator(this, function (_a) {
|
|
286
|
-
this.
|
|
329
|
+
this.logQueue = __spreadArray(__spreadArray([], retryableLogs_1, true), this.logQueue, true);
|
|
287
330
|
return [2 /*return*/];
|
|
288
331
|
});
|
|
289
332
|
}); })];
|
|
290
333
|
case 5:
|
|
291
|
-
// Requeue remaining retryable events
|
|
292
334
|
_a.sent();
|
|
293
335
|
return [3 /*break*/, 6];
|
|
294
336
|
case 6: return [2 /*return*/];
|
|
@@ -296,22 +338,29 @@ var Chirpier = /** @class */ (function () {
|
|
|
296
338
|
});
|
|
297
339
|
}); })];
|
|
298
340
|
case 1:
|
|
299
|
-
// Acquire the flush lock
|
|
300
341
|
_a.sent();
|
|
301
342
|
return [2 /*return*/];
|
|
302
343
|
}
|
|
303
344
|
});
|
|
304
345
|
});
|
|
305
346
|
};
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
347
|
+
Client.prototype.sendLogs = function (logs) {
|
|
348
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
349
|
+
return __generator(this, function (_a) {
|
|
350
|
+
switch (_a.label) {
|
|
351
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post(this.apiEndpoint, logs)];
|
|
352
|
+
case 1:
|
|
353
|
+
_a.sent();
|
|
354
|
+
return [2 /*return*/];
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
Client.prototype.flush = function () {
|
|
311
360
|
return __awaiter(this, void 0, void 0, function () {
|
|
312
361
|
return __generator(this, function (_a) {
|
|
313
362
|
switch (_a.label) {
|
|
314
|
-
case 0: return [4 /*yield*/, this.
|
|
363
|
+
case 0: return [4 /*yield*/, this.flushQueue()];
|
|
315
364
|
case 1:
|
|
316
365
|
_a.sent();
|
|
317
366
|
return [2 /*return*/];
|
|
@@ -319,89 +368,287 @@ var Chirpier = /** @class */ (function () {
|
|
|
319
368
|
});
|
|
320
369
|
});
|
|
321
370
|
};
|
|
322
|
-
|
|
323
|
-
Chirpier.stop = function () {
|
|
371
|
+
Client.prototype.shutdown = function () {
|
|
324
372
|
return __awaiter(this, void 0, void 0, function () {
|
|
325
373
|
return __generator(this, function (_a) {
|
|
326
374
|
switch (_a.label) {
|
|
327
375
|
case 0:
|
|
328
|
-
if (
|
|
329
|
-
|
|
376
|
+
if (this.flushTimeoutId) {
|
|
377
|
+
clearTimeout(this.flushTimeoutId);
|
|
378
|
+
this.flushTimeoutId = null;
|
|
330
379
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
380
|
+
return [4 /*yield*/, this.flushQueue()];
|
|
381
|
+
case 1:
|
|
382
|
+
_a.sent();
|
|
383
|
+
return [2 /*return*/];
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
};
|
|
388
|
+
Client.prototype.close = function () {
|
|
389
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
390
|
+
return __generator(this, function (_a) {
|
|
391
|
+
switch (_a.label) {
|
|
392
|
+
case 0: return [4 /*yield*/, this.shutdown()];
|
|
393
|
+
case 1:
|
|
394
|
+
_a.sent();
|
|
395
|
+
return [2 /*return*/];
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
Client.prototype.listEvents = function () {
|
|
401
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
402
|
+
var response;
|
|
403
|
+
return __generator(this, function (_a) {
|
|
404
|
+
switch (_a.label) {
|
|
405
|
+
case 0: return [4 /*yield*/, this.axiosInstance.get("".concat(this.servicerEndpoint, "/events"))];
|
|
406
|
+
case 1:
|
|
407
|
+
response = _a.sent();
|
|
408
|
+
return [2 /*return*/, response.data];
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
Client.prototype.getEvent = function (eventID) {
|
|
414
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
415
|
+
var response;
|
|
416
|
+
return __generator(this, function (_a) {
|
|
417
|
+
switch (_a.label) {
|
|
418
|
+
case 0: return [4 /*yield*/, this.axiosInstance.get("".concat(this.servicerEndpoint, "/events/").concat(eventID))];
|
|
419
|
+
case 1:
|
|
420
|
+
response = _a.sent();
|
|
421
|
+
return [2 /*return*/, response.data];
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
};
|
|
426
|
+
Client.prototype.updateEvent = function (eventID, payload) {
|
|
427
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
428
|
+
var response;
|
|
429
|
+
return __generator(this, function (_a) {
|
|
430
|
+
switch (_a.label) {
|
|
431
|
+
case 0: return [4 /*yield*/, this.axiosInstance.put("".concat(this.servicerEndpoint, "/events/").concat(eventID), payload)];
|
|
432
|
+
case 1:
|
|
433
|
+
response = _a.sent();
|
|
434
|
+
return [2 /*return*/, response.data];
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
Client.prototype.listPolicies = function () {
|
|
440
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
441
|
+
var response;
|
|
442
|
+
return __generator(this, function (_a) {
|
|
443
|
+
switch (_a.label) {
|
|
444
|
+
case 0: return [4 /*yield*/, this.axiosInstance.get("".concat(this.servicerEndpoint, "/policies"))];
|
|
445
|
+
case 1:
|
|
446
|
+
response = _a.sent();
|
|
447
|
+
return [2 /*return*/, response.data];
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
};
|
|
452
|
+
Client.prototype.createPolicy = function (payload) {
|
|
453
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
454
|
+
var response;
|
|
455
|
+
return __generator(this, function (_a) {
|
|
456
|
+
switch (_a.label) {
|
|
457
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post("".concat(this.servicerEndpoint, "/policies"), payload)];
|
|
458
|
+
case 1:
|
|
459
|
+
response = _a.sent();
|
|
460
|
+
return [2 /*return*/, response.data];
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
};
|
|
465
|
+
Client.prototype.listAlerts = function (status) {
|
|
466
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
467
|
+
var endpoint, response;
|
|
468
|
+
return __generator(this, function (_a) {
|
|
469
|
+
switch (_a.label) {
|
|
470
|
+
case 0:
|
|
471
|
+
endpoint = status
|
|
472
|
+
? "".concat(this.servicerEndpoint, "/alerts?status=").concat(encodeURIComponent(status))
|
|
473
|
+
: "".concat(this.servicerEndpoint, "/alerts");
|
|
474
|
+
return [4 /*yield*/, this.axiosInstance.get(endpoint)];
|
|
475
|
+
case 1:
|
|
476
|
+
response = _a.sent();
|
|
477
|
+
return [2 /*return*/, response.data];
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
};
|
|
482
|
+
Client.prototype.getAlertDeliveries = function (alertID, options) {
|
|
483
|
+
if (options === void 0) { options = {}; }
|
|
484
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
485
|
+
var params, suffix, response;
|
|
486
|
+
return __generator(this, function (_a) {
|
|
487
|
+
switch (_a.label) {
|
|
488
|
+
case 0:
|
|
489
|
+
params = new URLSearchParams();
|
|
490
|
+
if (options.kind) {
|
|
491
|
+
params.set("kind", options.kind);
|
|
492
|
+
}
|
|
493
|
+
if (typeof options.limit === "number") {
|
|
494
|
+
params.set("limit", String(options.limit));
|
|
334
495
|
}
|
|
335
|
-
|
|
336
|
-
|
|
496
|
+
if (typeof options.offset === "number") {
|
|
497
|
+
params.set("offset", String(options.offset));
|
|
498
|
+
}
|
|
499
|
+
suffix = params.toString() ? "?".concat(params.toString()) : "";
|
|
500
|
+
return [4 /*yield*/, this.axiosInstance.get("".concat(this.servicerEndpoint, "/alerts/").concat(alertID, "/deliveries").concat(suffix))];
|
|
501
|
+
case 1:
|
|
502
|
+
response = _a.sent();
|
|
503
|
+
return [2 /*return*/, response.data];
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
|
+
Client.prototype.acknowledgeAlert = function (alertID) {
|
|
509
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
510
|
+
var response;
|
|
511
|
+
return __generator(this, function (_a) {
|
|
512
|
+
switch (_a.label) {
|
|
513
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post("".concat(this.servicerEndpoint, "/alerts/").concat(alertID, "/acknowledge"))];
|
|
514
|
+
case 1:
|
|
515
|
+
response = _a.sent();
|
|
516
|
+
return [2 /*return*/, response.data];
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
Client.prototype.archiveAlert = function (alertID) {
|
|
522
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
523
|
+
var response;
|
|
524
|
+
return __generator(this, function (_a) {
|
|
525
|
+
switch (_a.label) {
|
|
526
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post("".concat(this.servicerEndpoint, "/alerts/").concat(alertID, "/archive"))];
|
|
527
|
+
case 1:
|
|
528
|
+
response = _a.sent();
|
|
529
|
+
return [2 /*return*/, response.data];
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
Client.prototype.testWebhook = function (webhookID) {
|
|
535
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
536
|
+
return __generator(this, function (_a) {
|
|
537
|
+
switch (_a.label) {
|
|
538
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post("".concat(this.servicerEndpoint, "/webhooks/").concat(webhookID, "/test"))];
|
|
337
539
|
case 1:
|
|
338
|
-
// Flush any remaining events in the queue
|
|
339
540
|
_a.sent();
|
|
340
|
-
// Uninitialize the Chirpier instance
|
|
341
|
-
Chirpier.instance = null;
|
|
342
541
|
return [2 /*return*/];
|
|
343
542
|
}
|
|
344
543
|
});
|
|
345
544
|
});
|
|
346
545
|
};
|
|
347
|
-
|
|
348
|
-
|
|
546
|
+
Client.prototype.getEventLogs = function (eventID, options) {
|
|
547
|
+
if (options === void 0) { options = {}; }
|
|
548
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
549
|
+
var params, suffix, response;
|
|
550
|
+
return __generator(this, function (_a) {
|
|
551
|
+
switch (_a.label) {
|
|
552
|
+
case 0:
|
|
553
|
+
params = new URLSearchParams();
|
|
554
|
+
if (options.period) {
|
|
555
|
+
params.set("period", options.period);
|
|
556
|
+
}
|
|
557
|
+
if (typeof options.limit === "number") {
|
|
558
|
+
params.set("limit", String(options.limit));
|
|
559
|
+
}
|
|
560
|
+
if (typeof options.offset === "number") {
|
|
561
|
+
params.set("offset", String(options.offset));
|
|
562
|
+
}
|
|
563
|
+
suffix = params.toString() ? "?".concat(params.toString()) : "";
|
|
564
|
+
return [4 /*yield*/, this.axiosInstance.get("".concat(this.servicerEndpoint, "/events/").concat(eventID, "/logs").concat(suffix))];
|
|
565
|
+
case 1:
|
|
566
|
+
response = _a.sent();
|
|
567
|
+
return [2 /*return*/, response.data];
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
};
|
|
572
|
+
Client.prototype.resolveAlert = function (alertID) {
|
|
573
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
574
|
+
var response;
|
|
575
|
+
return __generator(this, function (_a) {
|
|
576
|
+
switch (_a.label) {
|
|
577
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post("".concat(this.servicerEndpoint, "/alerts/").concat(alertID, "/resolve"))];
|
|
578
|
+
case 1:
|
|
579
|
+
response = _a.sent();
|
|
580
|
+
return [2 /*return*/, response.data];
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
};
|
|
585
|
+
return Client;
|
|
349
586
|
}());
|
|
350
|
-
exports.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
*/
|
|
356
|
-
function base64UrlDecode(str) {
|
|
357
|
-
// Replace '-' with '+' and '_' with '/'
|
|
358
|
-
var base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
359
|
-
// Pad the base64 string
|
|
360
|
-
var padding = base64.length % 4;
|
|
361
|
-
if (padding !== 0) {
|
|
362
|
-
base64 += "=".repeat(4 - padding);
|
|
363
|
-
}
|
|
364
|
-
return js_base64_1.Base64.decode(base64);
|
|
587
|
+
exports.Client = Client;
|
|
588
|
+
var instance = null;
|
|
589
|
+
function createClient(config) {
|
|
590
|
+
if (config === void 0) { config = {}; }
|
|
591
|
+
return new Client(config);
|
|
365
592
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
593
|
+
exports.createClient = createClient;
|
|
594
|
+
function isNodeEnvironment() {
|
|
595
|
+
return typeof process !== "undefined" && !!(process.versions && process.versions.node);
|
|
596
|
+
}
|
|
597
|
+
function isValidAPIKey(token) {
|
|
598
|
+
return token.startsWith("chp_") && token.length > "chp_".length;
|
|
599
|
+
}
|
|
600
|
+
function loadDotEnvKey() {
|
|
601
|
+
if (!isNodeEnvironment()) {
|
|
602
|
+
return undefined;
|
|
375
603
|
}
|
|
376
604
|
try {
|
|
377
|
-
|
|
378
|
-
var payload = JSON.parse(base64UrlDecode(parts[1]));
|
|
379
|
-
return typeof header === "object" && typeof payload === "object";
|
|
605
|
+
dotenv_1.default.config({ path: ".env", override: false });
|
|
380
606
|
}
|
|
381
|
-
catch (
|
|
382
|
-
|
|
383
|
-
return false;
|
|
607
|
+
catch (_a) {
|
|
608
|
+
return undefined;
|
|
384
609
|
}
|
|
610
|
+
var envKey = process.env.CHIRPIER_API_KEY;
|
|
611
|
+
if (typeof envKey !== "string") {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
var trimmedKey = envKey.trim();
|
|
615
|
+
return trimmedKey.length > 0 ? trimmedKey : undefined;
|
|
616
|
+
}
|
|
617
|
+
function resolveAPIKey(providedKey) {
|
|
618
|
+
if (typeof providedKey === "string" && providedKey.trim().length > 0) {
|
|
619
|
+
return providedKey.trim();
|
|
620
|
+
}
|
|
621
|
+
if (typeof process !== "undefined" && process.env && typeof process.env.CHIRPIER_API_KEY === "string") {
|
|
622
|
+
var envKey = process.env.CHIRPIER_API_KEY.trim();
|
|
623
|
+
if (envKey.length > 0) {
|
|
624
|
+
return envKey;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return loadDotEnvKey();
|
|
385
628
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Initializes the Chirpier SDK.
|
|
388
|
-
* @param options - Configuration options for the SDK.
|
|
389
|
-
*/
|
|
390
629
|
function initialize(options) {
|
|
391
|
-
if (
|
|
392
|
-
|
|
630
|
+
if (options === void 0) { options = {}; }
|
|
631
|
+
var resolvedKey = resolveAPIKey(options.key);
|
|
632
|
+
if (!resolvedKey) {
|
|
633
|
+
throw new ChirpierError("API key is required", "INVALID_KEY");
|
|
634
|
+
}
|
|
635
|
+
if (!isValidAPIKey(resolvedKey)) {
|
|
636
|
+
throw new ChirpierError("Invalid API key: must start with 'chp_'", "INVALID_KEY");
|
|
637
|
+
}
|
|
638
|
+
if (instance) {
|
|
639
|
+
return;
|
|
393
640
|
}
|
|
394
641
|
try {
|
|
395
|
-
|
|
642
|
+
instance = new Client(__assign(__assign({}, options), { key: resolvedKey }));
|
|
396
643
|
}
|
|
397
644
|
catch (error) {
|
|
398
645
|
if (error instanceof ChirpierError) {
|
|
399
|
-
if (options.logLevel && options.logLevel >= LogLevel.Error) {
|
|
646
|
+
if (options.logLevel && options.logLevel >= 1 /* LogLevel.Error */) {
|
|
400
647
|
console.error("Failed to initialize Chirpier SDK:", error.message);
|
|
401
648
|
}
|
|
402
649
|
}
|
|
403
650
|
else {
|
|
404
|
-
if (options.logLevel && options.logLevel >= LogLevel.Error) {
|
|
651
|
+
if (options.logLevel && options.logLevel >= 1 /* LogLevel.Error */) {
|
|
405
652
|
console.error("An unexpected error occurred during Chirpier SDK initialization:", error);
|
|
406
653
|
}
|
|
407
654
|
}
|
|
@@ -409,17 +656,55 @@ function initialize(options) {
|
|
|
409
656
|
}
|
|
410
657
|
}
|
|
411
658
|
exports.initialize = initialize;
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
659
|
+
function logEvent(log) {
|
|
660
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
661
|
+
return __generator(this, function (_a) {
|
|
662
|
+
switch (_a.label) {
|
|
663
|
+
case 0:
|
|
664
|
+
if (!instance) {
|
|
665
|
+
throw new ChirpierError("Chirpier SDK is not initialized. Please call initialize() first.", "NOT_INITIALIZED");
|
|
666
|
+
}
|
|
667
|
+
return [4 /*yield*/, instance.log(log)];
|
|
668
|
+
case 1:
|
|
669
|
+
_a.sent();
|
|
670
|
+
return [2 /*return*/];
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
exports.logEvent = logEvent;
|
|
676
|
+
function stop() {
|
|
677
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
678
|
+
return __generator(this, function (_a) {
|
|
679
|
+
switch (_a.label) {
|
|
680
|
+
case 0:
|
|
681
|
+
if (!instance) {
|
|
682
|
+
return [2 /*return*/];
|
|
683
|
+
}
|
|
684
|
+
return [4 /*yield*/, instance.shutdown()];
|
|
685
|
+
case 1:
|
|
686
|
+
_a.sent();
|
|
687
|
+
instance = null;
|
|
688
|
+
return [2 /*return*/];
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
exports.stop = stop;
|
|
694
|
+
function flush() {
|
|
695
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
696
|
+
return __generator(this, function (_a) {
|
|
697
|
+
switch (_a.label) {
|
|
698
|
+
case 0:
|
|
699
|
+
if (!instance) {
|
|
700
|
+
throw new ChirpierError("Chirpier SDK is not initialized. Please call initialize() first.", "NOT_INITIALIZED");
|
|
701
|
+
}
|
|
702
|
+
return [4 /*yield*/, instance.flush()];
|
|
703
|
+
case 1:
|
|
704
|
+
_a.sent();
|
|
705
|
+
return [2 /*return*/];
|
|
706
|
+
}
|
|
707
|
+
});
|
|
423
708
|
});
|
|
424
709
|
}
|
|
425
|
-
exports.
|
|
710
|
+
exports.flush = flush;
|