@rstreamlabs/rstream 1.4.0 → 1.6.1
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 +1 -1
- package/dist/index.d.mts +2833 -78
- package/dist/index.d.ts +2833 -78
- package/dist/index.js +203 -56
- package/dist/index.mjs +194 -52
- package/package.json +8 -8
package/dist/index.mjs
CHANGED
|
@@ -6,11 +6,11 @@ var RstreamAuthRessource = class {
|
|
|
6
6
|
constructor(client) {
|
|
7
7
|
this.client = client;
|
|
8
8
|
}
|
|
9
|
-
async
|
|
9
|
+
async createAuthToken(params, options) {
|
|
10
10
|
const credentials = options?.credentials || this.client.credentials;
|
|
11
11
|
if (!credentials || !("clientId" in credentials)) {
|
|
12
12
|
throw new Error(
|
|
13
|
-
"Application credentials (client id, client secret) are required to create
|
|
13
|
+
"Application credentials (client id, client secret) are required to create an auth token."
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
const now = Math.floor(Date.now() / 1e3);
|
|
@@ -22,9 +22,10 @@ var RstreamAuthRessource = class {
|
|
|
22
22
|
// Expiration time
|
|
23
23
|
type: "app",
|
|
24
24
|
clientId: credentials.clientId,
|
|
25
|
+
permissions: null,
|
|
25
26
|
metadata: {
|
|
26
27
|
engine: this.client.engine,
|
|
27
|
-
|
|
28
|
+
scopes: params?.scopes
|
|
28
29
|
}
|
|
29
30
|
};
|
|
30
31
|
const pk = crypto.createPrivateKey({
|
|
@@ -91,6 +92,8 @@ var tunnelSchema = z2.object({
|
|
|
91
92
|
// common properties
|
|
92
93
|
client_id: z2.string(),
|
|
93
94
|
user_id: z2.string(),
|
|
95
|
+
project_id: z2.string(),
|
|
96
|
+
workspace_id: z2.string(),
|
|
94
97
|
status: z2.enum(["online", "offline"]),
|
|
95
98
|
// tunnel properties
|
|
96
99
|
id: z2.string(),
|
|
@@ -132,66 +135,89 @@ var listTunnelsResponseSchema = z2.array(tunnelSchema);
|
|
|
132
135
|
|
|
133
136
|
// src/auth.ts
|
|
134
137
|
import * as z3 from "zod";
|
|
135
|
-
var
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
138
|
+
var authTokenPermissionsSchema = z3.array(z3.string());
|
|
139
|
+
var authTokenTunnelsScopesSchema = z3.object({
|
|
140
|
+
// Scopes for creating tunnels
|
|
141
|
+
create: z3.union([
|
|
142
|
+
z3.boolean(),
|
|
143
|
+
z3.object({
|
|
144
|
+
filters: filters(
|
|
145
|
+
tunnelSchema.omit({
|
|
146
|
+
client_id: true,
|
|
147
|
+
project_id: true,
|
|
148
|
+
workspace_id: true,
|
|
149
|
+
user_id: true,
|
|
150
|
+
status: true,
|
|
151
|
+
creation_date: true
|
|
152
|
+
})
|
|
153
|
+
).optional()
|
|
154
|
+
})
|
|
155
|
+
]).optional(),
|
|
156
|
+
// Scopes for connecting to tunnels
|
|
157
|
+
connect: z3.union([
|
|
158
|
+
z3.boolean(),
|
|
159
|
+
z3.object({
|
|
160
|
+
filters: filters(tunnelSchema).optional(),
|
|
161
|
+
params: filters(
|
|
162
|
+
z3.object({
|
|
163
|
+
path: z3.string().optional()
|
|
164
|
+
})
|
|
165
|
+
).optional()
|
|
166
|
+
})
|
|
167
|
+
]).optional(),
|
|
168
|
+
// Scopes for listing tunnels
|
|
169
|
+
list: z3.union([
|
|
170
|
+
z3.boolean(),
|
|
171
|
+
z3.object({
|
|
172
|
+
filters: filters(tunnelSchema).optional(),
|
|
173
|
+
select: select(tunnelSchema).optional()
|
|
174
|
+
})
|
|
175
|
+
]).optional()
|
|
169
176
|
});
|
|
170
|
-
var
|
|
171
|
-
|
|
177
|
+
var authTokenScopesSchema = z3.object({
|
|
178
|
+
tunnels: authTokenTunnelsScopesSchema.optional()
|
|
179
|
+
// Scopes related to tunnels
|
|
172
180
|
});
|
|
173
|
-
var
|
|
181
|
+
var authTokenSchema = z3.union([
|
|
182
|
+
z3.object({
|
|
183
|
+
type: z3.literal("auth"),
|
|
184
|
+
userId: z3.string(),
|
|
185
|
+
permissions: authTokenPermissionsSchema.nullable()
|
|
186
|
+
}),
|
|
174
187
|
z3.object({
|
|
175
188
|
type: z3.literal("pat")
|
|
176
189
|
}),
|
|
177
190
|
z3.object({
|
|
178
191
|
type: z3.literal("app"),
|
|
179
|
-
clientId: z3.string()
|
|
192
|
+
clientId: z3.string(),
|
|
193
|
+
permissions: authTokenPermissionsSchema.nullable()
|
|
180
194
|
})
|
|
181
195
|
]).and(
|
|
182
196
|
z3.object({
|
|
183
197
|
metadata: z3.object({
|
|
184
198
|
engine: z3.string().optional(),
|
|
185
|
-
|
|
199
|
+
scopes: authTokenScopesSchema.optional()
|
|
186
200
|
}).optional()
|
|
187
201
|
})
|
|
188
202
|
);
|
|
203
|
+
var createAuthTokenParamsSchema = z3.object({
|
|
204
|
+
expires_in: z3.number().default(60),
|
|
205
|
+
// 1 minute
|
|
206
|
+
scopes: authTokenScopesSchema.optional(),
|
|
207
|
+
metadata: z3.unknown().optional()
|
|
208
|
+
// Additional metadata
|
|
209
|
+
});
|
|
210
|
+
var createAuthTokenResponseSchema = z3.object({
|
|
211
|
+
token: z3.string()
|
|
212
|
+
});
|
|
189
213
|
|
|
190
214
|
// src/client.ts
|
|
191
215
|
import * as z4 from "zod";
|
|
192
216
|
var clientSchema = z4.object({
|
|
193
217
|
id: z4.string(),
|
|
194
218
|
user_id: z4.string(),
|
|
219
|
+
project_id: z4.string(),
|
|
220
|
+
workspace_id: z4.string(),
|
|
195
221
|
status: z4.enum(["online", "offline"]),
|
|
196
222
|
details: z4.object({
|
|
197
223
|
agent: z4.string().optional(),
|
|
@@ -355,7 +381,13 @@ var RstreamClient = class {
|
|
|
355
381
|
this.cfg = config;
|
|
356
382
|
}
|
|
357
383
|
get engine() {
|
|
358
|
-
|
|
384
|
+
if (this.cfg?.engine) {
|
|
385
|
+
return this.cfg.engine;
|
|
386
|
+
}
|
|
387
|
+
if (process.env.RSTREAM_DEFAULT_ENGINE) {
|
|
388
|
+
return process.env.RSTREAM_DEFAULT_ENGINE;
|
|
389
|
+
}
|
|
390
|
+
return void 0;
|
|
359
391
|
}
|
|
360
392
|
get credentials() {
|
|
361
393
|
if (this.cfg?.credentials && "token" in this.cfg.credentials) {
|
|
@@ -378,7 +410,13 @@ var RstreamClient = class {
|
|
|
378
410
|
return void 0;
|
|
379
411
|
}
|
|
380
412
|
get api() {
|
|
381
|
-
|
|
413
|
+
const engine = this.engine;
|
|
414
|
+
if (!engine) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
"Engine URL is not defined. Please provide an engine in the rstream client configuration or set the RSTREAM_DEFAULT_ENGINE environment variable."
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
return `https://${engine}/api`;
|
|
382
420
|
}
|
|
383
421
|
get auth() {
|
|
384
422
|
return new RstreamAuthRessource(this);
|
|
@@ -398,7 +436,7 @@ var RstreamClient = class {
|
|
|
398
436
|
return credentials.token;
|
|
399
437
|
}
|
|
400
438
|
if (credentials && "clientId" in credentials) {
|
|
401
|
-
return (await this.auth.
|
|
439
|
+
return (await this.auth.createAuthToken(void 0, {
|
|
402
440
|
credentials: {
|
|
403
441
|
clientId: credentials.clientId,
|
|
404
442
|
clientSecret: credentials.clientSecret
|
|
@@ -442,11 +480,16 @@ var Watch = class {
|
|
|
442
480
|
throw new Error("Watch: Connection already started or closed.");
|
|
443
481
|
}
|
|
444
482
|
this.connectionState = "connecting";
|
|
445
|
-
const token = await this.config.auth
|
|
446
|
-
const payload =
|
|
483
|
+
const token = typeof this.config.auth === "function" ? await this.config.auth() : this.config.auth;
|
|
484
|
+
const payload = authTokenSchema.parse(
|
|
447
485
|
jwt2.decode(token, { complete: false })
|
|
448
486
|
);
|
|
449
|
-
|
|
487
|
+
if (this.config.engine === void 0 && payload.metadata?.engine === void 0) {
|
|
488
|
+
throw new Error(
|
|
489
|
+
"Watch: No engine specified in configuration or token metadata."
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const base = `https://${this.config.engine || payload.metadata?.engine}`;
|
|
450
493
|
if (this.config.transport === "sse") {
|
|
451
494
|
const url = new URL(`/api/sse`, base);
|
|
452
495
|
url.searchParams.set("rstream.token", token);
|
|
@@ -470,6 +513,13 @@ var Watch = class {
|
|
|
470
513
|
this.disconnect();
|
|
471
514
|
}
|
|
472
515
|
};
|
|
516
|
+
if (this.connection instanceof WebSocket) {
|
|
517
|
+
this.connection.onclose = () => {
|
|
518
|
+
if (this.connectionState !== "closed") {
|
|
519
|
+
this.disconnect();
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
}
|
|
473
523
|
}
|
|
474
524
|
disconnect() {
|
|
475
525
|
if (this.connection) {
|
|
@@ -485,6 +535,93 @@ var Watch = class {
|
|
|
485
535
|
}
|
|
486
536
|
}
|
|
487
537
|
};
|
|
538
|
+
|
|
539
|
+
// src/webtty.ts
|
|
540
|
+
import * as z6 from "zod";
|
|
541
|
+
var osFamilies = [
|
|
542
|
+
"linux",
|
|
543
|
+
"macos",
|
|
544
|
+
"windows",
|
|
545
|
+
"netbsd",
|
|
546
|
+
"openbsd",
|
|
547
|
+
"freebsd"
|
|
548
|
+
];
|
|
549
|
+
var architectures = [
|
|
550
|
+
"x86_i386",
|
|
551
|
+
"x86_i686",
|
|
552
|
+
"x86_64",
|
|
553
|
+
"x86_64_v2",
|
|
554
|
+
"x86_64_v3",
|
|
555
|
+
"x86_64_v4",
|
|
556
|
+
"armv6",
|
|
557
|
+
"armv6hf",
|
|
558
|
+
"armv7",
|
|
559
|
+
"armv7hf",
|
|
560
|
+
"arm64",
|
|
561
|
+
"mips",
|
|
562
|
+
"mipsle",
|
|
563
|
+
"mips64",
|
|
564
|
+
"mips64le",
|
|
565
|
+
"ppc64",
|
|
566
|
+
"ppc64le",
|
|
567
|
+
"riscv64"
|
|
568
|
+
];
|
|
569
|
+
var webttyServerSchema = z6.object({
|
|
570
|
+
tunnel_id: z6.string(),
|
|
571
|
+
host: z6.string(),
|
|
572
|
+
token_auth: z6.boolean(),
|
|
573
|
+
os_family: z6.enum(osFamilies).optional(),
|
|
574
|
+
arch: z6.enum(architectures).optional(),
|
|
575
|
+
os_id: z6.string().optional(),
|
|
576
|
+
// /etc/os-release::ID (ubuntu, debian, rocky, etc.)
|
|
577
|
+
os_version_id: z6.string().optional(),
|
|
578
|
+
// /etc/os-release::VERSION_ID (24.04, 22.04, 11, 10.0.19045, ...)
|
|
579
|
+
os_version_codename: z6.string().optional(),
|
|
580
|
+
// /etc/os-release::VERSION_CODENAME (jammy, noble...)
|
|
581
|
+
os_pretty_name: z6.string().optional(),
|
|
582
|
+
// /etc/os-release::PRETTY_NAME
|
|
583
|
+
kernel_release: z6.string().optional(),
|
|
584
|
+
// uname -r
|
|
585
|
+
hostname: z6.string().optional(),
|
|
586
|
+
// uname -n
|
|
587
|
+
labels: z6.record(z6.string(), z6.string().optional()).optional()
|
|
588
|
+
});
|
|
589
|
+
function parser(tunnel) {
|
|
590
|
+
if (tunnel.status !== "online") return null;
|
|
591
|
+
if (tunnel.publish !== true) return null;
|
|
592
|
+
if (tunnel.protocol !== "http") return null;
|
|
593
|
+
const tunnelLabels = tunnel.labels ?? {};
|
|
594
|
+
if (tunnelLabels["application-protocol"] !== "rstream.webtty") {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
const labels = {};
|
|
598
|
+
for (const [key, value] of Object.entries(tunnelLabels)) {
|
|
599
|
+
if (!key.startsWith("rstream.webtty.label.")) continue;
|
|
600
|
+
const labelKey = key.slice("rstream.webtty.label.".length);
|
|
601
|
+
if (labelKey.length === 0) continue;
|
|
602
|
+
labels[labelKey] = value;
|
|
603
|
+
}
|
|
604
|
+
const candidate = {
|
|
605
|
+
tunnel_id: tunnel.id,
|
|
606
|
+
host: tunnel.host,
|
|
607
|
+
token_auth: tunnel.token_auth === true,
|
|
608
|
+
os_family: tunnelLabels["rstream.webtty.os_family"],
|
|
609
|
+
arch: tunnelLabels["rstream.webtty.arch"],
|
|
610
|
+
os_id: tunnelLabels["rstream.webtty.os_id"],
|
|
611
|
+
os_version_id: tunnelLabels["rstream.webtty.os_version_id"],
|
|
612
|
+
os_version_codename: tunnelLabels["rstream.webtty.os_version_codename"],
|
|
613
|
+
os_pretty_name: tunnelLabels["rstream.webtty.os_pretty_name"],
|
|
614
|
+
kernel_release: tunnelLabels["rstream.webtty.kernel_release"],
|
|
615
|
+
hostname: tunnelLabels["rstream.webtty.hostname"],
|
|
616
|
+
labels: Object.keys(labels).length > 0 ? labels : void 0
|
|
617
|
+
};
|
|
618
|
+
const parsed = webttyServerSchema.safeParse(candidate);
|
|
619
|
+
if (!parsed.success) return null;
|
|
620
|
+
return parsed.data;
|
|
621
|
+
}
|
|
622
|
+
function parseWebTTYServers(tunnels) {
|
|
623
|
+
return tunnels.map((tunnel) => parser(tunnel)).filter((server) => server !== null);
|
|
624
|
+
}
|
|
488
625
|
export {
|
|
489
626
|
RstreamClient as Rstream,
|
|
490
627
|
RstreamAuthRessource,
|
|
@@ -493,14 +630,19 @@ export {
|
|
|
493
630
|
RstreamTunnelsRessource,
|
|
494
631
|
RstreamWebHooksRessource,
|
|
495
632
|
Watch,
|
|
633
|
+
authTokenPermissionsSchema,
|
|
634
|
+
authTokenSchema,
|
|
635
|
+
authTokenScopesSchema,
|
|
636
|
+
authTokenTunnelsScopesSchema,
|
|
496
637
|
clientSchema,
|
|
497
|
-
|
|
498
|
-
|
|
638
|
+
createAuthTokenParamsSchema,
|
|
639
|
+
createAuthTokenResponseSchema,
|
|
499
640
|
eventSchema,
|
|
500
641
|
listClientsParamsSchema,
|
|
501
642
|
listClientsResponseSchema,
|
|
502
643
|
listTunnelsParamsSchema,
|
|
503
644
|
listTunnelsResponseSchema,
|
|
504
|
-
|
|
505
|
-
tunnelSchema
|
|
645
|
+
parseWebTTYServers,
|
|
646
|
+
tunnelSchema,
|
|
647
|
+
webttyServerSchema
|
|
506
648
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rstreamlabs/rstream",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "JS SDK for rstream
|
|
3
|
+
"version": "1.6.1",
|
|
4
|
+
"description": "JS/TS SDK for rstream - serverless networking",
|
|
5
5
|
"author": "@uartnet <hello@rstream.io>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"type-check": "tsc --noEmit"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@turbo/gen": "^2.
|
|
22
|
+
"@turbo/gen": "^2.7.4",
|
|
23
23
|
"@types/jsonwebtoken": "^9.0.10",
|
|
24
|
-
"@types/node": "^
|
|
24
|
+
"@types/node": "^25",
|
|
25
25
|
"eslint-config": "*",
|
|
26
|
-
"eslint": "9.
|
|
27
|
-
"tsup": "^8.5.
|
|
26
|
+
"eslint": "9.39.2",
|
|
27
|
+
"tsup": "^8.5.1",
|
|
28
28
|
"typescript-config": "*",
|
|
29
|
-
"typescript": "5.9.
|
|
29
|
+
"typescript": "5.9.3"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"jsonwebtoken": "^9.0.
|
|
32
|
+
"jsonwebtoken": "^9.0.3",
|
|
33
33
|
"zod": "^3.25.76"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|