trusera-sdk 0.2.0 → 1.1.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 +2 -0
- package/dist/index.cjs +124 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +124 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Trusera SDK for JavaScript/TypeScript
|
|
2
2
|
|
|
3
|
+
> **Beta** — This SDK is under active development. Expected GA: April 2026.
|
|
4
|
+
|
|
3
5
|
[](https://www.npmjs.com/package/trusera-sdk)
|
|
4
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
7
|
|
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(index_exports);
|
|
43
43
|
|
|
44
44
|
// src/client.ts
|
|
45
|
+
var SDK_VERSION = "1.0.0";
|
|
45
46
|
var TruseraClient = class {
|
|
46
47
|
apiKey;
|
|
47
48
|
baseUrl;
|
|
@@ -52,6 +53,14 @@ var TruseraClient = class {
|
|
|
52
53
|
eventQueue = [];
|
|
53
54
|
flushTimer;
|
|
54
55
|
isClosed = false;
|
|
56
|
+
// Fleet auto-registration
|
|
57
|
+
autoRegister;
|
|
58
|
+
agentName;
|
|
59
|
+
agentType;
|
|
60
|
+
environment;
|
|
61
|
+
heartbeatInterval;
|
|
62
|
+
fleetAgentId;
|
|
63
|
+
heartbeatTimer;
|
|
55
64
|
constructor(options) {
|
|
56
65
|
this.apiKey = options.apiKey;
|
|
57
66
|
this.baseUrl = options.baseUrl ?? "https://api.trusera.io";
|
|
@@ -59,11 +68,28 @@ var TruseraClient = class {
|
|
|
59
68
|
this.batchSize = options.batchSize ?? 100;
|
|
60
69
|
this.flushInterval = options.flushInterval ?? 5e3;
|
|
61
70
|
this.debug = options.debug ?? false;
|
|
71
|
+
const envAuto = (typeof process !== "undefined" ? process.env?.TRUSERA_AUTO_REGISTER : void 0) ?? "";
|
|
72
|
+
if (envAuto.toLowerCase() === "true" || envAuto === "1") {
|
|
73
|
+
this.autoRegister = true;
|
|
74
|
+
} else if (envAuto.toLowerCase() === "false" || envAuto === "0") {
|
|
75
|
+
this.autoRegister = false;
|
|
76
|
+
} else {
|
|
77
|
+
this.autoRegister = options.autoRegister ?? false;
|
|
78
|
+
}
|
|
79
|
+
const hostname = typeof process !== "undefined" && process.env?.HOSTNAME ? process.env.HOSTNAME : typeof globalThis !== "undefined" && "navigator" in globalThis ? "browser" : "unknown";
|
|
80
|
+
this.agentName = options.agentName ?? (typeof process !== "undefined" ? process.env?.TRUSERA_AGENT_NAME : void 0) ?? hostname;
|
|
81
|
+
this.agentType = options.agentType ?? (typeof process !== "undefined" ? process.env?.TRUSERA_AGENT_TYPE : void 0) ?? "";
|
|
82
|
+
this.environment = options.environment ?? (typeof process !== "undefined" ? process.env?.TRUSERA_ENVIRONMENT : void 0) ?? "";
|
|
83
|
+
const envHb = typeof process !== "undefined" ? process.env?.TRUSERA_HEARTBEAT_INTERVAL : void 0;
|
|
84
|
+
this.heartbeatInterval = envHb ? parseInt(envHb, 10) * 1e3 : options.heartbeatInterval ?? 6e4;
|
|
62
85
|
if (!this.apiKey.startsWith("tsk_")) {
|
|
63
86
|
throw new Error("Invalid API key format. Must start with 'tsk_'");
|
|
64
87
|
}
|
|
65
88
|
this.startFlushTimer();
|
|
66
|
-
this.
|
|
89
|
+
if (this.autoRegister) {
|
|
90
|
+
void this.registerWithFleet();
|
|
91
|
+
}
|
|
92
|
+
this.log("TruseraClient initialized", { baseUrl: this.baseUrl, batchSize: this.batchSize, autoRegister: this.autoRegister });
|
|
67
93
|
}
|
|
68
94
|
/**
|
|
69
95
|
* Registers a new agent with Trusera backend.
|
|
@@ -167,6 +193,7 @@ var TruseraClient = class {
|
|
|
167
193
|
this.log("Closing client");
|
|
168
194
|
this.isClosed = true;
|
|
169
195
|
this.stopFlushTimer();
|
|
196
|
+
this.stopHeartbeat();
|
|
170
197
|
await this.flush();
|
|
171
198
|
this.log("Client closed");
|
|
172
199
|
}
|
|
@@ -182,6 +209,102 @@ var TruseraClient = class {
|
|
|
182
209
|
getAgentId() {
|
|
183
210
|
return this.agentId;
|
|
184
211
|
}
|
|
212
|
+
// -- Fleet auto-registration --
|
|
213
|
+
getProcessInfo() {
|
|
214
|
+
if (typeof process === "undefined") return {};
|
|
215
|
+
return {
|
|
216
|
+
pid: process.pid,
|
|
217
|
+
argv: process.argv?.slice(0, 10),
|
|
218
|
+
node_version: process.version,
|
|
219
|
+
platform: process.platform,
|
|
220
|
+
arch: process.arch
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
getNetworkInfo() {
|
|
224
|
+
const info = {};
|
|
225
|
+
if (typeof process !== "undefined") {
|
|
226
|
+
try {
|
|
227
|
+
const os = require("os");
|
|
228
|
+
info.hostname = os.hostname?.();
|
|
229
|
+
} catch {
|
|
230
|
+
info.hostname = process.env?.HOSTNAME ?? "unknown";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return info;
|
|
234
|
+
}
|
|
235
|
+
async registerWithFleet() {
|
|
236
|
+
const payload = {
|
|
237
|
+
name: this.agentName,
|
|
238
|
+
discovery_method: "sdk",
|
|
239
|
+
sdk_version: SDK_VERSION,
|
|
240
|
+
hostname: this.agentName,
|
|
241
|
+
process_info: this.getProcessInfo(),
|
|
242
|
+
network_info: this.getNetworkInfo()
|
|
243
|
+
};
|
|
244
|
+
if (this.agentType) payload.framework = this.agentType;
|
|
245
|
+
if (this.environment) payload.environment = this.environment;
|
|
246
|
+
try {
|
|
247
|
+
const response = await fetch(`${this.baseUrl}/api/v1/fleet/register`, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: {
|
|
250
|
+
"Content-Type": "application/json",
|
|
251
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(payload)
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
this.log("Fleet auto-register failed", { status: response.status });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const data = await response.json();
|
|
260
|
+
const agentData = data.data ?? data;
|
|
261
|
+
const fleetId = agentData.id;
|
|
262
|
+
if (fleetId) {
|
|
263
|
+
this.fleetAgentId = String(fleetId);
|
|
264
|
+
this.startHeartbeat();
|
|
265
|
+
this.log("Fleet auto-register succeeded", { fleetAgentId: this.fleetAgentId });
|
|
266
|
+
}
|
|
267
|
+
} catch (err) {
|
|
268
|
+
this.log("Fleet auto-register error (continuing without)", { error: String(err) });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
startHeartbeat() {
|
|
272
|
+
this.heartbeatTimer = setInterval(() => {
|
|
273
|
+
void this.sendHeartbeat();
|
|
274
|
+
}, this.heartbeatInterval);
|
|
275
|
+
if (this.heartbeatTimer.unref) {
|
|
276
|
+
this.heartbeatTimer.unref();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
stopHeartbeat() {
|
|
280
|
+
if (this.heartbeatTimer) {
|
|
281
|
+
clearInterval(this.heartbeatTimer);
|
|
282
|
+
this.heartbeatTimer = void 0;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async sendHeartbeat() {
|
|
286
|
+
if (!this.fleetAgentId) return;
|
|
287
|
+
try {
|
|
288
|
+
const payload = {
|
|
289
|
+
process_info: this.getProcessInfo(),
|
|
290
|
+
network_info: this.getNetworkInfo()
|
|
291
|
+
};
|
|
292
|
+
const response = await fetch(`${this.baseUrl}/api/v1/fleet/${this.fleetAgentId}/heartbeat`, {
|
|
293
|
+
method: "POST",
|
|
294
|
+
headers: {
|
|
295
|
+
"Content-Type": "application/json",
|
|
296
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
297
|
+
},
|
|
298
|
+
body: JSON.stringify(payload)
|
|
299
|
+
});
|
|
300
|
+
if (!response.ok) {
|
|
301
|
+
this.log("Fleet heartbeat failed", { status: response.status });
|
|
302
|
+
}
|
|
303
|
+
} catch (err) {
|
|
304
|
+
this.log("Fleet heartbeat error", { error: String(err) });
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// -- Timers --
|
|
185
308
|
startFlushTimer() {
|
|
186
309
|
this.flushTimer = setInterval(() => {
|
|
187
310
|
void this.flush();
|