@rstreamlabs/rstream 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 +3 -0
- package/dist/index.d.mts +2286 -0
- package/dist/index.d.ts +2286 -0
- package/dist/index.js +543 -0
- package/dist/index.mjs +490 -0
- package/package.json +37 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Rstream: () => RstreamClient,
|
|
34
|
+
RstreamAuthRessource: () => RstreamAuthRessource,
|
|
35
|
+
RstreamClient: () => RstreamClient,
|
|
36
|
+
RstreamClientsRessource: () => RstreamClientsRessource,
|
|
37
|
+
RstreamTunnelsRessource: () => RstreamTunnelsRessource,
|
|
38
|
+
RstreamWebHooksRessource: () => RstreamWebHooksRessource,
|
|
39
|
+
Watch: () => Watch,
|
|
40
|
+
clientSchema: () => clientSchema,
|
|
41
|
+
createShortTermTokenParamsSchema: () => createShortTermTokenParamsSchema,
|
|
42
|
+
createShortTermTokenResponseSchema: () => createShortTermTokenResponseSchema,
|
|
43
|
+
eventSchema: () => eventSchema,
|
|
44
|
+
listClientsParamsSchema: () => listClientsParamsSchema,
|
|
45
|
+
listClientsResponseSchema: () => listClientsResponseSchema,
|
|
46
|
+
listTunnelsParamsSchema: () => listTunnelsParamsSchema,
|
|
47
|
+
listTunnelsResponseSchema: () => listTunnelsResponseSchema,
|
|
48
|
+
rstreamAuthPayloadSchema: () => rstreamAuthPayloadSchema,
|
|
49
|
+
tunnelSchema: () => tunnelSchema
|
|
50
|
+
});
|
|
51
|
+
module.exports = __toCommonJS(index_exports);
|
|
52
|
+
|
|
53
|
+
// src/auth-ressource.ts
|
|
54
|
+
var import_crypto = __toESM(require("crypto"));
|
|
55
|
+
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
56
|
+
var RstreamAuthRessource = class {
|
|
57
|
+
client;
|
|
58
|
+
constructor(client) {
|
|
59
|
+
this.client = client;
|
|
60
|
+
}
|
|
61
|
+
async createShortTermToken(params, options) {
|
|
62
|
+
const credentials = options?.credentials || this.client.credentials;
|
|
63
|
+
if (!credentials || !("clientId" in credentials)) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"Application credentials (client id, client secret) are required to create a short term token."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
69
|
+
const exp = now + (params?.expires_in ?? 60);
|
|
70
|
+
const payload = {
|
|
71
|
+
iat: now,
|
|
72
|
+
// Issued at
|
|
73
|
+
exp,
|
|
74
|
+
// Expiration time
|
|
75
|
+
type: "app",
|
|
76
|
+
clientId: credentials.clientId,
|
|
77
|
+
metadata: {
|
|
78
|
+
engine: this.client.engine,
|
|
79
|
+
permissions: params?.permissions
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const pk = import_crypto.default.createPrivateKey({
|
|
83
|
+
key: Buffer.from(credentials.clientSecret, "hex"),
|
|
84
|
+
format: "der",
|
|
85
|
+
type: "pkcs8"
|
|
86
|
+
});
|
|
87
|
+
const token = import_jsonwebtoken.default.sign(payload, pk, {
|
|
88
|
+
algorithm: "ES512"
|
|
89
|
+
});
|
|
90
|
+
const result = {
|
|
91
|
+
token
|
|
92
|
+
};
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// src/zod.ts
|
|
98
|
+
var z = __toESM(require("zod"));
|
|
99
|
+
var StringFilter = z.union([
|
|
100
|
+
z.string(),
|
|
101
|
+
z.object({ exact: z.string() }),
|
|
102
|
+
z.object({ oneof: z.array(z.string()) }),
|
|
103
|
+
z.object({ regex: z.string() })
|
|
104
|
+
]);
|
|
105
|
+
function transform(field) {
|
|
106
|
+
if (field instanceof z.ZodOptional) {
|
|
107
|
+
return transform(field.unwrap()).optional();
|
|
108
|
+
}
|
|
109
|
+
if (field instanceof z.ZodString) {
|
|
110
|
+
return StringFilter.optional();
|
|
111
|
+
}
|
|
112
|
+
if (field instanceof z.ZodRecord) {
|
|
113
|
+
return z.record(field.keySchema, transform(field.valueSchema)).optional();
|
|
114
|
+
}
|
|
115
|
+
return field.optional();
|
|
116
|
+
}
|
|
117
|
+
function filters(base) {
|
|
118
|
+
const entries = Object.entries(base.shape).map(([key, field]) => [
|
|
119
|
+
key,
|
|
120
|
+
transform(field)
|
|
121
|
+
]);
|
|
122
|
+
const shape = Object.fromEntries(entries);
|
|
123
|
+
const node = z.lazy(
|
|
124
|
+
() => z.union([
|
|
125
|
+
z.object(shape),
|
|
126
|
+
z.object({ AND: z.array(node) }),
|
|
127
|
+
z.object({ OR: z.array(node) })
|
|
128
|
+
])
|
|
129
|
+
);
|
|
130
|
+
return node;
|
|
131
|
+
}
|
|
132
|
+
function select(base) {
|
|
133
|
+
const entries = Object.entries(base.shape).map(([key]) => {
|
|
134
|
+
return [key, z.boolean().optional()];
|
|
135
|
+
});
|
|
136
|
+
const shape = Object.fromEntries(entries);
|
|
137
|
+
return z.object(shape);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/tunnel.ts
|
|
141
|
+
var z2 = __toESM(require("zod"));
|
|
142
|
+
var tunnelSchema = z2.object({
|
|
143
|
+
id: z2.string(),
|
|
144
|
+
client_id: z2.string(),
|
|
145
|
+
user_id: z2.string(),
|
|
146
|
+
status: z2.enum(["online", "offline"]),
|
|
147
|
+
name: z2.string().optional(),
|
|
148
|
+
protocol: z2.string(),
|
|
149
|
+
publish: z2.boolean(),
|
|
150
|
+
labels: z2.record(z2.string().optional()).optional(),
|
|
151
|
+
host: z2.string().optional(),
|
|
152
|
+
tls_mode: z2.string(),
|
|
153
|
+
tls_min_version: z2.string().optional(),
|
|
154
|
+
mtls: z2.boolean(),
|
|
155
|
+
token_auth: z2.boolean(),
|
|
156
|
+
path: z2.string().optional()
|
|
157
|
+
});
|
|
158
|
+
var listTunnelsParamsSchema = z2.object({
|
|
159
|
+
limit: z2.number().optional(),
|
|
160
|
+
filters: tunnelSchema.pick({
|
|
161
|
+
status: true,
|
|
162
|
+
client_id: true,
|
|
163
|
+
protocol: true,
|
|
164
|
+
publish: true,
|
|
165
|
+
labels: true
|
|
166
|
+
}).partial().optional()
|
|
167
|
+
});
|
|
168
|
+
var listTunnelsResponseSchema = z2.object({
|
|
169
|
+
tunnels: z2.array(tunnelSchema)
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// src/auth.ts
|
|
173
|
+
var z3 = __toESM(require("zod"));
|
|
174
|
+
var createShortTermTokenParamsSchema = z3.object({
|
|
175
|
+
expires_in: z3.number().default(60),
|
|
176
|
+
// 1 minute
|
|
177
|
+
permissions: z3.object({
|
|
178
|
+
// Permissions for creating a tunnel
|
|
179
|
+
create: z3.union([
|
|
180
|
+
z3.boolean(),
|
|
181
|
+
z3.object({
|
|
182
|
+
filters: filters(tunnelSchema).optional()
|
|
183
|
+
})
|
|
184
|
+
]).optional(),
|
|
185
|
+
// Permissions for connecting to a tunnel
|
|
186
|
+
connect: z3.union([
|
|
187
|
+
z3.boolean(),
|
|
188
|
+
z3.object({
|
|
189
|
+
filters: filters(tunnelSchema).optional()
|
|
190
|
+
})
|
|
191
|
+
]).optional(),
|
|
192
|
+
// Permissions for listing tunnels
|
|
193
|
+
list: z3.union([
|
|
194
|
+
z3.boolean(),
|
|
195
|
+
z3.object({
|
|
196
|
+
filters: filters(tunnelSchema).optional(),
|
|
197
|
+
select: select(tunnelSchema).optional()
|
|
198
|
+
})
|
|
199
|
+
]).optional()
|
|
200
|
+
}),
|
|
201
|
+
// Additional metadata
|
|
202
|
+
metadata: z3.unknown().optional()
|
|
203
|
+
});
|
|
204
|
+
var createShortTermTokenResponseSchema = z3.object({
|
|
205
|
+
token: z3.string()
|
|
206
|
+
});
|
|
207
|
+
var rstreamAuthPayloadSchema = z3.discriminatedUnion("type", [
|
|
208
|
+
z3.object({
|
|
209
|
+
type: z3.literal("pat")
|
|
210
|
+
}),
|
|
211
|
+
z3.object({
|
|
212
|
+
type: z3.literal("app"),
|
|
213
|
+
clientId: z3.string()
|
|
214
|
+
})
|
|
215
|
+
]).and(
|
|
216
|
+
z3.object({
|
|
217
|
+
metadata: z3.object({
|
|
218
|
+
engine: z3.string().optional(),
|
|
219
|
+
permissions: createShortTermTokenParamsSchema.shape.permissions.optional()
|
|
220
|
+
}).optional()
|
|
221
|
+
})
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// src/client.ts
|
|
225
|
+
var z4 = __toESM(require("zod"));
|
|
226
|
+
var clientSchema = z4.object({
|
|
227
|
+
id: z4.string(),
|
|
228
|
+
user_id: z4.string(),
|
|
229
|
+
status: z4.enum(["online", "offline"]),
|
|
230
|
+
details: z4.object({
|
|
231
|
+
agent: z4.string().optional(),
|
|
232
|
+
os: z4.string().optional(),
|
|
233
|
+
version: z4.string().optional(),
|
|
234
|
+
protocol_version: z4.string().optional()
|
|
235
|
+
}).optional(),
|
|
236
|
+
labels: z4.record(z4.string().optional()).optional()
|
|
237
|
+
});
|
|
238
|
+
var listClientsParamsSchema = z4.object({
|
|
239
|
+
limit: z4.number().optional(),
|
|
240
|
+
filters: clientSchema.pick({
|
|
241
|
+
labels: true
|
|
242
|
+
}).partial().optional()
|
|
243
|
+
});
|
|
244
|
+
var listClientsResponseSchema = z4.object({
|
|
245
|
+
clients: z4.array(clientSchema)
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// src/clients-ressource.ts
|
|
249
|
+
var RstreamClientsRessource = class {
|
|
250
|
+
client;
|
|
251
|
+
constructor(client) {
|
|
252
|
+
this.client = client;
|
|
253
|
+
}
|
|
254
|
+
async list(params) {
|
|
255
|
+
const response = await this.client.request(
|
|
256
|
+
`/clients?params=${encodeURIComponent(JSON.stringify(params))}`,
|
|
257
|
+
{
|
|
258
|
+
method: "GET"
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
return listClientsResponseSchema.parse(response);
|
|
262
|
+
}
|
|
263
|
+
async get(id) {
|
|
264
|
+
const response = await this.client.request(`/clients/${id}`, {
|
|
265
|
+
method: "GET"
|
|
266
|
+
});
|
|
267
|
+
return clientSchema.parse(response);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// src/event.ts
|
|
272
|
+
var z5 = __toESM(require("zod"));
|
|
273
|
+
var eventSchema = z5.union([
|
|
274
|
+
z5.object({
|
|
275
|
+
type: z5.literal("client.created"),
|
|
276
|
+
object: clientSchema
|
|
277
|
+
}),
|
|
278
|
+
z5.object({
|
|
279
|
+
type: z5.literal("client.updated"),
|
|
280
|
+
object: clientSchema
|
|
281
|
+
}),
|
|
282
|
+
z5.object({
|
|
283
|
+
type: z5.literal("client.deleted"),
|
|
284
|
+
object: clientSchema
|
|
285
|
+
}),
|
|
286
|
+
z5.object({
|
|
287
|
+
type: z5.literal("tunnel.created"),
|
|
288
|
+
object: tunnelSchema
|
|
289
|
+
}),
|
|
290
|
+
z5.object({
|
|
291
|
+
type: z5.literal("tunnel.updated"),
|
|
292
|
+
object: tunnelSchema
|
|
293
|
+
}),
|
|
294
|
+
z5.object({
|
|
295
|
+
type: z5.literal("tunnel.deleted"),
|
|
296
|
+
object: tunnelSchema
|
|
297
|
+
})
|
|
298
|
+
]);
|
|
299
|
+
|
|
300
|
+
// src/tunnels-ressource.ts
|
|
301
|
+
var RstreamTunnelsRessource = class {
|
|
302
|
+
client;
|
|
303
|
+
constructor(client) {
|
|
304
|
+
this.client = client;
|
|
305
|
+
}
|
|
306
|
+
async list(params) {
|
|
307
|
+
const response = await this.client.request(
|
|
308
|
+
`/tunnels?params=${encodeURIComponent(JSON.stringify(params))}`,
|
|
309
|
+
{
|
|
310
|
+
method: "GET"
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
return listTunnelsResponseSchema.parse(response);
|
|
314
|
+
}
|
|
315
|
+
async get(id) {
|
|
316
|
+
const response = await this.client.request(`/tunnels/${id}`, {
|
|
317
|
+
method: "GET"
|
|
318
|
+
});
|
|
319
|
+
return tunnelSchema.parse(response);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// src/webhooks-ressource.ts
|
|
324
|
+
var import_crypto2 = __toESM(require("crypto"));
|
|
325
|
+
var RstreamWebHooksRessource = class {
|
|
326
|
+
client;
|
|
327
|
+
constructor(client) {
|
|
328
|
+
this.client = client;
|
|
329
|
+
}
|
|
330
|
+
// Constructs and verifies the signature of an Event from the provided details.
|
|
331
|
+
async event(payload, header, secret, tolerance = 300, receivedAt = Date.now()) {
|
|
332
|
+
const payloadBuffer = Buffer.isBuffer(payload) ? payload : Buffer.from(payload);
|
|
333
|
+
const signatureHeader = Array.isArray(header) ? header[0] : header.toString();
|
|
334
|
+
if (!signatureHeader) {
|
|
335
|
+
throw new Error("No signature header");
|
|
336
|
+
}
|
|
337
|
+
const elements = signatureHeader.split(",").map((element) => element.trim());
|
|
338
|
+
let timestamp;
|
|
339
|
+
const signatures = [];
|
|
340
|
+
for (const element of elements) {
|
|
341
|
+
if (element.startsWith("t=")) {
|
|
342
|
+
timestamp = element.substring(2);
|
|
343
|
+
} else if (element.startsWith("v1=")) {
|
|
344
|
+
signatures.push(element.substring(3));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (!timestamp || signatures.length === 0) {
|
|
348
|
+
throw new Error("Invalid signature header format");
|
|
349
|
+
}
|
|
350
|
+
const timestampNum = parseInt(timestamp, 10);
|
|
351
|
+
const now = Math.floor(receivedAt / 1e3);
|
|
352
|
+
if (Math.abs(now - timestampNum) > tolerance) {
|
|
353
|
+
throw new Error(
|
|
354
|
+
`Webhook signature timestamp outside tolerance: ${now}, ${timestampNum}`
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
const signedPayload = `${timestamp}.${payloadBuffer.toString("utf8")}`;
|
|
358
|
+
const expectedSignature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload).digest("hex");
|
|
359
|
+
let signatureMatched = false;
|
|
360
|
+
for (const signature of signatures) {
|
|
361
|
+
try {
|
|
362
|
+
if (import_crypto2.default.timingSafeEqual(
|
|
363
|
+
Buffer.from(signature),
|
|
364
|
+
Buffer.from(expectedSignature)
|
|
365
|
+
)) {
|
|
366
|
+
signatureMatched = true;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
} catch (error) {
|
|
370
|
+
console.log("Error comparing signatures:", error);
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (!signatureMatched) {
|
|
375
|
+
throw new Error("Signature verification failed");
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
return eventSchema.parse(JSON.parse(payloadBuffer.toString("utf8")));
|
|
379
|
+
} catch (error) {
|
|
380
|
+
throw new Error(
|
|
381
|
+
`Failed to parse webhook payload: ${error instanceof Error ? error.message : String(error)}`
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
// src/rstream.ts
|
|
388
|
+
var RstreamClient = class {
|
|
389
|
+
cfg;
|
|
390
|
+
constructor(config) {
|
|
391
|
+
this.cfg = config;
|
|
392
|
+
}
|
|
393
|
+
get engine() {
|
|
394
|
+
return this.cfg?.engine || process.env.RSTREAM_DEFAULT_ENGINE || "engine.rstream.io:443";
|
|
395
|
+
}
|
|
396
|
+
get credentials() {
|
|
397
|
+
if (this.cfg?.credentials && "token" in this.cfg.credentials) {
|
|
398
|
+
return this.cfg.credentials;
|
|
399
|
+
}
|
|
400
|
+
if (process.env.RSTREAM_DEFAULT_AUTHENTICATION_TOKEN) {
|
|
401
|
+
return {
|
|
402
|
+
token: process.env.RSTREAM_DEFAULT_AUTHENTICATION_TOKEN
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
if (this.cfg?.credentials && "clientId" in this.cfg.credentials) {
|
|
406
|
+
return this.cfg.credentials;
|
|
407
|
+
}
|
|
408
|
+
if (process.env.RSTREAM_DEFAULT_CLIENT_ID && process.env.RSTREAM_DEFAULT_CLIENT_SECRET) {
|
|
409
|
+
return {
|
|
410
|
+
clientId: process.env.RSTREAM_DEFAULT_CLIENT_ID,
|
|
411
|
+
clientSecret: process.env.RSTREAM_DEFAULT_CLIENT_SECRET
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return void 0;
|
|
415
|
+
}
|
|
416
|
+
get api() {
|
|
417
|
+
return `https://${this.engine}/api`;
|
|
418
|
+
}
|
|
419
|
+
get auth() {
|
|
420
|
+
return new RstreamAuthRessource(this);
|
|
421
|
+
}
|
|
422
|
+
get clients() {
|
|
423
|
+
return new RstreamClientsRessource(this);
|
|
424
|
+
}
|
|
425
|
+
get tunnels() {
|
|
426
|
+
return new RstreamTunnelsRessource(this);
|
|
427
|
+
}
|
|
428
|
+
get webhooks() {
|
|
429
|
+
return new RstreamWebHooksRessource(this);
|
|
430
|
+
}
|
|
431
|
+
async getToken() {
|
|
432
|
+
const credentials = this.credentials;
|
|
433
|
+
if (credentials && "token" in credentials) {
|
|
434
|
+
return credentials.token;
|
|
435
|
+
}
|
|
436
|
+
if (credentials && "clientId" in credentials) {
|
|
437
|
+
return (await this.auth.createShortTermToken(void 0, {
|
|
438
|
+
credentials: {
|
|
439
|
+
clientId: credentials.clientId,
|
|
440
|
+
clientSecret: credentials.clientSecret
|
|
441
|
+
}
|
|
442
|
+
})).token;
|
|
443
|
+
}
|
|
444
|
+
return void 0;
|
|
445
|
+
}
|
|
446
|
+
async request(path, options) {
|
|
447
|
+
const url = `${this.api}${path}`;
|
|
448
|
+
const headers = new Headers(options?.headers || {});
|
|
449
|
+
const token = await this.getToken();
|
|
450
|
+
if (token) {
|
|
451
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
452
|
+
}
|
|
453
|
+
const response = await fetch(url, {
|
|
454
|
+
...options,
|
|
455
|
+
headers
|
|
456
|
+
});
|
|
457
|
+
if (!response.ok) {
|
|
458
|
+
const errorText = await response.text();
|
|
459
|
+
throw new Error(`HTTP error ${response.status}: ${errorText}`);
|
|
460
|
+
}
|
|
461
|
+
return await response.json();
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
// src/watch.ts
|
|
466
|
+
var import_jsonwebtoken2 = __toESM(require("jsonwebtoken"));
|
|
467
|
+
var Watch = class {
|
|
468
|
+
connection = null;
|
|
469
|
+
connectionState = "preparing";
|
|
470
|
+
config;
|
|
471
|
+
events;
|
|
472
|
+
constructor(config, events) {
|
|
473
|
+
this.config = config;
|
|
474
|
+
this.events = events;
|
|
475
|
+
}
|
|
476
|
+
async connect() {
|
|
477
|
+
if (this.connectionState !== "preparing") {
|
|
478
|
+
throw new Error("Watch: Connection already started or closed.");
|
|
479
|
+
}
|
|
480
|
+
this.connectionState = "connecting";
|
|
481
|
+
const token = await this.config.auth.token();
|
|
482
|
+
const payload = rstreamAuthPayloadSchema.parse(
|
|
483
|
+
import_jsonwebtoken2.default.decode(token, { complete: false })
|
|
484
|
+
);
|
|
485
|
+
const base = `https://${this.config.engine || payload.metadata?.engine || "engine.rstream.io:443"}`;
|
|
486
|
+
if (this.config.transport === "sse") {
|
|
487
|
+
const url = new URL(`/api/sse`, base);
|
|
488
|
+
url.searchParams.set("rstream.token", token);
|
|
489
|
+
this.connection = new EventSource(url.toString());
|
|
490
|
+
} else {
|
|
491
|
+
const url = new URL(`/api/websocket`, base);
|
|
492
|
+
url.searchParams.set("rstream.token", token);
|
|
493
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
494
|
+
this.connection = new WebSocket(url.toString());
|
|
495
|
+
}
|
|
496
|
+
this.connection.onopen = () => {
|
|
497
|
+
this.connectionState = "connected";
|
|
498
|
+
this.events.onConnect?.();
|
|
499
|
+
};
|
|
500
|
+
this.connection.onmessage = (msg) => {
|
|
501
|
+
const parsed = eventSchema.parse(JSON.parse(msg.data));
|
|
502
|
+
this.events.onEvent?.(parsed);
|
|
503
|
+
};
|
|
504
|
+
this.connection.onerror = () => {
|
|
505
|
+
if (this.connectionState !== "closed") {
|
|
506
|
+
this.disconnect();
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
disconnect() {
|
|
511
|
+
if (this.connection) {
|
|
512
|
+
this.connection.onerror = null;
|
|
513
|
+
this.connection.onmessage = null;
|
|
514
|
+
this.connection.onopen = null;
|
|
515
|
+
this.connection.close();
|
|
516
|
+
this.connection = null;
|
|
517
|
+
}
|
|
518
|
+
if (this.connectionState !== "closed") {
|
|
519
|
+
this.connectionState = "closed";
|
|
520
|
+
this.events.onClose?.();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
525
|
+
0 && (module.exports = {
|
|
526
|
+
Rstream,
|
|
527
|
+
RstreamAuthRessource,
|
|
528
|
+
RstreamClient,
|
|
529
|
+
RstreamClientsRessource,
|
|
530
|
+
RstreamTunnelsRessource,
|
|
531
|
+
RstreamWebHooksRessource,
|
|
532
|
+
Watch,
|
|
533
|
+
clientSchema,
|
|
534
|
+
createShortTermTokenParamsSchema,
|
|
535
|
+
createShortTermTokenResponseSchema,
|
|
536
|
+
eventSchema,
|
|
537
|
+
listClientsParamsSchema,
|
|
538
|
+
listClientsResponseSchema,
|
|
539
|
+
listTunnelsParamsSchema,
|
|
540
|
+
listTunnelsResponseSchema,
|
|
541
|
+
rstreamAuthPayloadSchema,
|
|
542
|
+
tunnelSchema
|
|
543
|
+
});
|