@chirpier/chirpier-js 0.1.6 → 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 +477 -197
- package/package.json +2 -2
- package/src/__tests__/chirpier.test.ts +265 -93
- package/src/constants.ts +7 -6
- package/src/index.ts +492 -195
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,56 +93,74 @@ 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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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");
|
|
113
127
|
}
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
throw new ChirpierError("Region must be one of: us-west, eu-west, asia-southeast");
|
|
128
|
+
if (timeout <= 0) {
|
|
129
|
+
throw new ChirpierError("Timeout must be positive", "INVALID_TIMEOUT");
|
|
117
130
|
}
|
|
118
|
-
|
|
131
|
+
if (batchSize <= 0 || !Number.isInteger(batchSize)) {
|
|
132
|
+
throw new ChirpierError("Batch size must be a positive integer", "INVALID_BATCH_SIZE");
|
|
133
|
+
}
|
|
134
|
+
if (flushDelay < 0) {
|
|
135
|
+
throw new ChirpierError("Flush delay must be non-negative", "INVALID_FLUSH_DELAY");
|
|
136
|
+
}
|
|
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;
|
|
119
142
|
this.apiKey = key;
|
|
120
|
-
this.retries =
|
|
121
|
-
this.timeout =
|
|
122
|
-
this.batchSize =
|
|
123
|
-
this.flushDelay =
|
|
143
|
+
this.retries = retries;
|
|
144
|
+
this.timeout = timeout;
|
|
145
|
+
this.batchSize = batchSize;
|
|
146
|
+
this.flushDelay = flushDelay;
|
|
147
|
+
this.maxQueueSize = maxQueueSize;
|
|
124
148
|
this.logLevel = logLevel;
|
|
125
|
-
|
|
149
|
+
this.queueLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
|
|
150
|
+
this.flushLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
|
|
126
151
|
this.axiosInstance = axios_1.default.create({
|
|
127
152
|
headers: { Authorization: "Bearer ".concat(this.apiKey) },
|
|
128
153
|
timeout: this.timeout,
|
|
129
154
|
});
|
|
130
|
-
|
|
131
|
-
this.axiosInstance.interceptors.response.use(function (response) { return response; }, function (error) {
|
|
132
|
-
// Don't handle the error here; let axios-retry handle it
|
|
133
|
-
return Promise.reject(error);
|
|
134
|
-
});
|
|
135
|
-
// Apply axios-retry to your Axios instance
|
|
155
|
+
this.axiosInstance.interceptors.response.use(function (response) { return response; }, function (error) { return Promise.reject(error); });
|
|
136
156
|
(0, axios_retry_1.default)(this.axiosInstance, {
|
|
137
157
|
retries: this.retries,
|
|
138
158
|
retryDelay: function (retryCount) {
|
|
139
|
-
|
|
159
|
+
var baseDelay = Math.pow(2, retryCount) * 1000;
|
|
160
|
+
var jitter = Math.random() * 0.3 * baseDelay;
|
|
161
|
+
return baseDelay + jitter;
|
|
140
162
|
},
|
|
141
163
|
retryCondition: function (error) {
|
|
142
|
-
// Retry on network errors, 5xx errors, and 429 (Too Many Requests)
|
|
143
164
|
return (axios_retry_1.default.isNetworkError(error) ||
|
|
144
165
|
axios_retry_1.default.isRetryableError(error) ||
|
|
145
166
|
(error.response && error.response.status) === 429);
|
|
@@ -147,61 +168,91 @@ var Chirpier = /** @class */ (function () {
|
|
|
147
168
|
shouldResetTimeout: true,
|
|
148
169
|
});
|
|
149
170
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
}
|
|
158
205
|
}
|
|
159
|
-
return
|
|
206
|
+
return true;
|
|
160
207
|
};
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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;
|
|
173
227
|
};
|
|
174
|
-
|
|
175
|
-
* Monitors an event by adding it to the queue and scheduling a flush if necessary.
|
|
176
|
-
* @param event - The event to monitor.
|
|
177
|
-
*/
|
|
178
|
-
Chirpier.prototype.monitor = function (event) {
|
|
228
|
+
Client.prototype.log = function (log) {
|
|
179
229
|
return __awaiter(this, void 0, void 0, function () {
|
|
230
|
+
var normalizedLog, queueFull;
|
|
180
231
|
var _this = this;
|
|
181
232
|
return __generator(this, function (_a) {
|
|
182
233
|
switch (_a.label) {
|
|
183
234
|
case 0:
|
|
184
|
-
if (!this.
|
|
185
|
-
|
|
186
|
-
console.debug("Invalid event format, dropping event:", event);
|
|
187
|
-
}
|
|
188
|
-
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");
|
|
189
237
|
}
|
|
238
|
+
normalizedLog = this.normalizeLog(log);
|
|
239
|
+
queueFull = false;
|
|
190
240
|
return [4 /*yield*/, this.queueLock.acquire("queue", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
191
241
|
return __generator(this, function (_a) {
|
|
192
|
-
if (this.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
return [2 /*return*/]; // Silently drop the event
|
|
242
|
+
if (this.logQueue.length >= this.maxQueueSize) {
|
|
243
|
+
queueFull = true;
|
|
244
|
+
return [2 /*return*/];
|
|
197
245
|
}
|
|
198
|
-
this.
|
|
246
|
+
this.logQueue.push({ log: normalizedLog, timestamp: Date.now(), retryCount: 0 });
|
|
199
247
|
return [2 /*return*/];
|
|
200
248
|
});
|
|
201
249
|
}); })];
|
|
202
250
|
case 1:
|
|
203
251
|
_a.sent();
|
|
204
|
-
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];
|
|
205
256
|
return [4 /*yield*/, this.flushQueue()];
|
|
206
257
|
case 2:
|
|
207
258
|
_a.sent();
|
|
@@ -216,84 +267,70 @@ var Chirpier = /** @class */ (function () {
|
|
|
216
267
|
});
|
|
217
268
|
});
|
|
218
269
|
};
|
|
219
|
-
|
|
220
|
-
* Flushes the event queue by sending all events to the API.
|
|
221
|
-
*/
|
|
222
|
-
Chirpier.prototype.flushQueue = function () {
|
|
270
|
+
Client.prototype.flushQueue = function () {
|
|
223
271
|
return __awaiter(this, void 0, void 0, function () {
|
|
224
272
|
var _this = this;
|
|
225
273
|
return __generator(this, function (_a) {
|
|
226
274
|
switch (_a.label) {
|
|
227
|
-
case 0:
|
|
228
|
-
|
|
229
|
-
return [4 /*yield*/, this.flushLock.acquire("flush", function () { return __awaiter(_this, void 0, void 0, function () {
|
|
230
|
-
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;
|
|
231
277
|
var _this = this;
|
|
232
278
|
return __generator(this, function (_a) {
|
|
233
279
|
switch (_a.label) {
|
|
234
280
|
case 0:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
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 () {
|
|
238
283
|
return __generator(this, function (_a) {
|
|
239
|
-
if (this.
|
|
240
|
-
|
|
241
|
-
this.
|
|
284
|
+
if (this.logQueue.length > 0) {
|
|
285
|
+
logsToSend = __spreadArray([], this.logQueue, true);
|
|
286
|
+
this.logQueue = [];
|
|
242
287
|
}
|
|
243
288
|
return [2 /*return*/];
|
|
244
289
|
});
|
|
245
290
|
}); })];
|
|
246
291
|
case 1:
|
|
247
|
-
// Extract events from the queue under the queue lock
|
|
248
292
|
_a.sent();
|
|
249
|
-
if (
|
|
293
|
+
if (logsToSend.length === 0) {
|
|
250
294
|
return [2 /*return*/];
|
|
251
295
|
}
|
|
252
296
|
_a.label = 2;
|
|
253
297
|
case 2:
|
|
254
298
|
_a.trys.push([2, 4, , 6]);
|
|
255
|
-
// Clear any pending flush timeout
|
|
256
299
|
if (this.flushTimeoutId) {
|
|
257
300
|
clearTimeout(this.flushTimeoutId);
|
|
258
301
|
this.flushTimeoutId = null;
|
|
259
302
|
}
|
|
260
|
-
|
|
261
|
-
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; }))];
|
|
262
304
|
case 3:
|
|
263
|
-
// Attempt to send events
|
|
264
305
|
_a.sent();
|
|
265
|
-
if (this.logLevel >= LogLevel.Info) {
|
|
266
|
-
console.info("Successfully sent ".concat(
|
|
306
|
+
if (this.logLevel >= 2 /* LogLevel.Info */) {
|
|
307
|
+
console.info("Successfully sent ".concat(logsToSend.length, " logs"));
|
|
267
308
|
}
|
|
268
309
|
return [3 /*break*/, 6];
|
|
269
310
|
case 4:
|
|
270
311
|
error_1 = _a.sent();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
console.error("Failed to send events:", error_1);
|
|
312
|
+
if (this.logLevel >= 1 /* LogLevel.Error */) {
|
|
313
|
+
console.error("Failed to send logs:", error_1);
|
|
274
314
|
}
|
|
275
|
-
|
|
276
|
-
for (_i = 0,
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
if (this.logLevel >= LogLevel.Error) {
|
|
280
|
-
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);
|
|
281
321
|
}
|
|
282
|
-
continue;
|
|
322
|
+
continue;
|
|
283
323
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
retryableEvents_1.push(queuedEvent);
|
|
324
|
+
queuedLog.retryCount++;
|
|
325
|
+
retryableLogs_1.push(queuedLog);
|
|
287
326
|
}
|
|
288
|
-
|
|
289
|
-
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 () {
|
|
290
328
|
return __generator(this, function (_a) {
|
|
291
|
-
this.
|
|
329
|
+
this.logQueue = __spreadArray(__spreadArray([], retryableLogs_1, true), this.logQueue, true);
|
|
292
330
|
return [2 /*return*/];
|
|
293
331
|
});
|
|
294
332
|
}); })];
|
|
295
333
|
case 5:
|
|
296
|
-
// Requeue remaining retryable events
|
|
297
334
|
_a.sent();
|
|
298
335
|
return [3 /*break*/, 6];
|
|
299
336
|
case 6: return [2 /*return*/];
|
|
@@ -301,22 +338,17 @@ var Chirpier = /** @class */ (function () {
|
|
|
301
338
|
});
|
|
302
339
|
}); })];
|
|
303
340
|
case 1:
|
|
304
|
-
// Acquire the flush lock
|
|
305
341
|
_a.sent();
|
|
306
342
|
return [2 /*return*/];
|
|
307
343
|
}
|
|
308
344
|
});
|
|
309
345
|
});
|
|
310
346
|
};
|
|
311
|
-
|
|
312
|
-
* Sends multiple events to the API in a batch.
|
|
313
|
-
* @param events - The array of events to send.
|
|
314
|
-
*/
|
|
315
|
-
Chirpier.prototype.sendEvents = function (events) {
|
|
347
|
+
Client.prototype.sendLogs = function (logs) {
|
|
316
348
|
return __awaiter(this, void 0, void 0, function () {
|
|
317
349
|
return __generator(this, function (_a) {
|
|
318
350
|
switch (_a.label) {
|
|
319
|
-
case 0: return [4 /*yield*/, this.axiosInstance.post(this.apiEndpoint,
|
|
351
|
+
case 0: return [4 /*yield*/, this.axiosInstance.post(this.apiEndpoint, logs)];
|
|
320
352
|
case 1:
|
|
321
353
|
_a.sent();
|
|
322
354
|
return [2 /*return*/];
|
|
@@ -324,89 +356,299 @@ var Chirpier = /** @class */ (function () {
|
|
|
324
356
|
});
|
|
325
357
|
});
|
|
326
358
|
};
|
|
327
|
-
|
|
328
|
-
|
|
359
|
+
Client.prototype.flush = function () {
|
|
360
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
361
|
+
return __generator(this, function (_a) {
|
|
362
|
+
switch (_a.label) {
|
|
363
|
+
case 0: return [4 /*yield*/, this.flushQueue()];
|
|
364
|
+
case 1:
|
|
365
|
+
_a.sent();
|
|
366
|
+
return [2 /*return*/];
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
Client.prototype.shutdown = function () {
|
|
329
372
|
return __awaiter(this, void 0, void 0, function () {
|
|
330
373
|
return __generator(this, function (_a) {
|
|
331
374
|
switch (_a.label) {
|
|
332
375
|
case 0:
|
|
333
|
-
if (
|
|
334
|
-
|
|
376
|
+
if (this.flushTimeoutId) {
|
|
377
|
+
clearTimeout(this.flushTimeoutId);
|
|
378
|
+
this.flushTimeoutId = null;
|
|
335
379
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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));
|
|
495
|
+
}
|
|
496
|
+
if (typeof options.offset === "number") {
|
|
497
|
+
params.set("offset", String(options.offset));
|
|
339
498
|
}
|
|
340
|
-
|
|
341
|
-
return [4 /*yield*/,
|
|
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"))];
|
|
342
539
|
case 1:
|
|
343
|
-
// Flush any remaining events in the queue
|
|
344
540
|
_a.sent();
|
|
345
|
-
// Uninitialize the Chirpier instance
|
|
346
|
-
Chirpier.instance = null;
|
|
347
541
|
return [2 /*return*/];
|
|
348
542
|
}
|
|
349
543
|
});
|
|
350
544
|
});
|
|
351
545
|
};
|
|
352
|
-
|
|
353
|
-
|
|
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;
|
|
354
586
|
}());
|
|
355
|
-
exports.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
*/
|
|
361
|
-
function base64UrlDecode(str) {
|
|
362
|
-
// Replace '-' with '+' and '_' with '/'
|
|
363
|
-
var base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
364
|
-
// Pad the base64 string
|
|
365
|
-
var padding = base64.length % 4;
|
|
366
|
-
if (padding !== 0) {
|
|
367
|
-
base64 += "=".repeat(4 - padding);
|
|
368
|
-
}
|
|
369
|
-
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);
|
|
370
592
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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;
|
|
380
603
|
}
|
|
381
604
|
try {
|
|
382
|
-
|
|
383
|
-
var payload = JSON.parse(base64UrlDecode(parts[1]));
|
|
384
|
-
return typeof header === "object" && typeof payload === "object";
|
|
605
|
+
dotenv_1.default.config({ path: ".env", override: false });
|
|
385
606
|
}
|
|
386
|
-
catch (
|
|
387
|
-
|
|
388
|
-
return false;
|
|
607
|
+
catch (_a) {
|
|
608
|
+
return undefined;
|
|
389
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();
|
|
390
628
|
}
|
|
391
|
-
/**
|
|
392
|
-
* Initializes the Chirpier SDK.
|
|
393
|
-
* @param options - Configuration options for the SDK.
|
|
394
|
-
*/
|
|
395
629
|
function initialize(options) {
|
|
396
|
-
if (
|
|
397
|
-
|
|
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;
|
|
398
640
|
}
|
|
399
641
|
try {
|
|
400
|
-
|
|
642
|
+
instance = new Client(__assign(__assign({}, options), { key: resolvedKey }));
|
|
401
643
|
}
|
|
402
644
|
catch (error) {
|
|
403
645
|
if (error instanceof ChirpierError) {
|
|
404
|
-
if (options.logLevel && options.logLevel >= LogLevel.Error) {
|
|
646
|
+
if (options.logLevel && options.logLevel >= 1 /* LogLevel.Error */) {
|
|
405
647
|
console.error("Failed to initialize Chirpier SDK:", error.message);
|
|
406
648
|
}
|
|
407
649
|
}
|
|
408
650
|
else {
|
|
409
|
-
if (options.logLevel && options.logLevel >= LogLevel.Error) {
|
|
651
|
+
if (options.logLevel && options.logLevel >= 1 /* LogLevel.Error */) {
|
|
410
652
|
console.error("An unexpected error occurred during Chirpier SDK initialization:", error);
|
|
411
653
|
}
|
|
412
654
|
}
|
|
@@ -414,17 +656,55 @@ function initialize(options) {
|
|
|
414
656
|
}
|
|
415
657
|
}
|
|
416
658
|
exports.initialize = initialize;
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
+
});
|
|
428
708
|
});
|
|
429
709
|
}
|
|
430
|
-
exports.
|
|
710
|
+
exports.flush = flush;
|