@rstreamlabs/tunnels 1.0.11 → 3.0.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/dist/index.js CHANGED
@@ -43,18 +43,11 @@ __export(index_exports, {
43
43
  RstreamWebhookRessource: () => RstreamWebhookResource,
44
44
  Tunnels: () => RstreamTunnelsClient,
45
45
  Watch: () => Watch,
46
- authTokenPermissionsSchema: () => authTokenPermissionsSchema,
47
- authTokenSchema: () => authTokenSchema,
48
- authTokenScopesSchema: () => authTokenScopesSchema,
49
- authTokenTunnelGrantSchema: () => authTokenTunnelGrantSchema,
50
- authTokenTunnelsScopesSchema: () => authTokenTunnelsScopesSchema,
51
46
  clientFilterSchema: () => clientFilterSchema,
52
47
  clientSchema: () => clientSchema,
53
48
  createAPITURNCredentials: () => createAPITURNCredentials,
54
49
  createAPPTURNCredentials: () => createAPPTURNCredentials,
55
50
  createAuthTokenFromClientCredentials: () => createAuthTokenFromClientCredentials,
56
- createAuthTokenParamsSchema: () => createAuthTokenParamsSchema,
57
- createAuthTokenResponseSchema: () => createAuthTokenResponseSchema,
58
51
  createPATTURNCredentials: () => createPATTURNCredentials,
59
52
  createTURNCredentials: () => createTURNCredentials,
60
53
  engineOpenApiDocument: () => engineOpenApiDocument,
@@ -75,9 +68,7 @@ __export(index_exports, {
75
68
  streamEndpointSchema: () => streamEndpointSchema,
76
69
  streamSummarySchema: () => streamSummarySchema,
77
70
  streamTLSInfoSchema: () => streamTLSInfoSchema,
78
- tokenSchema: () => tokenSchema,
79
71
  tunnelFilterSchema: () => tunnelFilterSchema,
80
- tunnelSchema: () => tunnelSchema,
81
72
  turnCredentialModeSchema: () => turnCredentialModeSchema,
82
73
  webhookEventsSchema: () => webhookEventsSchema,
83
74
  webttyServerSchema: () => webttyServerSchema,
@@ -86,270 +77,8 @@ __export(index_exports, {
86
77
  module.exports = __toCommonJS(index_exports);
87
78
 
88
79
  // src/auth-resource.ts
80
+ var import_auth_token = require("@rstreamlabs/rstream/auth-token");
89
81
  var import_rstream = require("@rstreamlabs/rstream");
90
-
91
- // src/zod.ts
92
- var z = __toESM(require("zod"));
93
- var StringFilter = z.union([
94
- z.string(),
95
- z.object({ exact: z.string() }).strict(),
96
- z.object({ oneof: z.array(z.string()) }).strict(),
97
- z.object({ regex: z.string() }).strict()
98
- ]);
99
- function transform(field) {
100
- if (field instanceof z.ZodOptional) {
101
- return z.optional(transform(field.unwrap()));
102
- }
103
- if (field instanceof z.ZodString) {
104
- return z.optional(StringFilter);
105
- }
106
- if (field instanceof z.ZodRecord) {
107
- return z.optional(z.record(field.keyType, transform(field.valueType)));
108
- }
109
- return z.optional(field);
110
- }
111
- function filters(base) {
112
- const entries = Object.entries(base.shape).map(([key, field]) => [
113
- key,
114
- transform(field)
115
- ]);
116
- const shape = Object.fromEntries(entries);
117
- const node = z.lazy(
118
- () => z.union([
119
- z.object(shape).strict(),
120
- z.object({ AND: z.array(node) }).strict(),
121
- z.object({ OR: z.array(node) }).strict()
122
- ])
123
- );
124
- return node;
125
- }
126
- function select(base) {
127
- const entries = Object.entries(base.shape).map(([key]) => {
128
- return [key, z.boolean().optional()];
129
- });
130
- const shape = Object.fromEntries(entries);
131
- return z.object(shape).strict();
132
- }
133
-
134
- // src/tunnel.ts
135
- var z2 = __toESM(require("zod"));
136
- var DEFAULT_PUBLISHED_PORT = 443;
137
- var tunnelSchema = z2.object({
138
- // common properties
139
- client_id: z2.string(),
140
- user_id: z2.string().optional(),
141
- workspace_id: z2.string().optional(),
142
- project_id: z2.string().optional(),
143
- cluster_id: z2.string().optional(),
144
- plan: z2.string().optional(),
145
- provider: z2.string().optional(),
146
- region: z2.string().optional(),
147
- status: z2.enum(["online", "offline"]),
148
- // tunnel properties
149
- id: z2.string(),
150
- creation_date: z2.union([z2.string().datetime(), z2.date()]).optional(),
151
- name: z2.string().optional(),
152
- type: z2.enum(["bytestream", "datagram"]).optional(),
153
- publish: z2.boolean().optional(),
154
- protocol: z2.enum(["tls", "dtls", "quic", "http"]).optional(),
155
- labels: z2.record(z2.string(), z2.string()).optional(),
156
- geo_ip: z2.array(z2.string()).optional(),
157
- trusted_ips: z2.array(z2.string()).optional(),
158
- host: z2.string().optional(),
159
- hostname: z2.string().optional(),
160
- port: z2.number().int().min(1).max(65535).optional(),
161
- tls_mode: z2.enum(["passthrough", "terminated"]).optional(),
162
- tls_alpns: z2.array(z2.string()).optional(),
163
- tls_min_version: z2.string().optional(),
164
- tls_ciphers: z2.array(z2.string()).optional(),
165
- mtls_auth: z2.boolean().optional(),
166
- http_version: z2.enum(["http/1.1", "h2", "h2c", "h3"]).optional(),
167
- http_use_tls: z2.boolean().optional(),
168
- upstream_tls: z2.boolean().optional(),
169
- token_auth: z2.boolean().optional(),
170
- rstream_auth: z2.boolean().optional(),
171
- challenge_mode: z2.boolean().optional()
172
- });
173
- var tunnelFilterSchema = tunnelSchema.pick({
174
- id: true,
175
- name: true,
176
- type: true,
177
- status: true,
178
- client_id: true,
179
- user_id: true,
180
- publish: true,
181
- protocol: true,
182
- hostname: true,
183
- http_version: true,
184
- labels: true
185
- }).partial();
186
- var listTunnelsParamsSchema = z2.object({
187
- limit: z2.number().int().min(1).optional(),
188
- filters: tunnelFilterSchema.optional()
189
- });
190
- var listTunnelsResponseSchema = z2.array(tunnelSchema);
191
- function formatTunnelHost(tunnel) {
192
- if (!tunnel.hostname) return tunnel.host;
193
- if (!tunnel.port || tunnel.port === DEFAULT_PUBLISHED_PORT) {
194
- return tunnel.hostname;
195
- }
196
- return `${tunnel.hostname}:${tunnel.port}`;
197
- }
198
-
199
- // src/auth.ts
200
- var z3 = __toESM(require("zod"));
201
- var nonEmptyStringSchema = z3.string().trim().min(1);
202
- var authTokenPermissionsSchema = z3.array(z3.string());
203
- var authTokenTunnelsScopesSchema = z3.object({
204
- // Scopes for creating tunnels
205
- create: z3.union([
206
- z3.boolean(),
207
- z3.object({
208
- filters: filters(
209
- tunnelSchema.omit({
210
- client_id: true,
211
- user_id: true,
212
- workspace_id: true,
213
- project_id: true,
214
- cluster_id: true,
215
- plan: true,
216
- provider: true,
217
- region: true,
218
- status: true,
219
- id: true,
220
- creation_date: true
221
- })
222
- ).optional()
223
- }).strict()
224
- ]).optional(),
225
- // Scopes for connecting to tunnels
226
- connect: z3.union([
227
- z3.boolean(),
228
- z3.object({
229
- filters: filters(tunnelSchema).optional(),
230
- params: filters(
231
- z3.object({
232
- path: z3.string().optional()
233
- })
234
- ).optional()
235
- }).strict()
236
- ]).optional(),
237
- // Scopes for listing tunnels
238
- list: z3.union([
239
- z3.boolean(),
240
- z3.object({
241
- filters: filters(tunnelSchema).optional(),
242
- select: select(tunnelSchema).optional()
243
- }).strict()
244
- ]).optional()
245
- }).strict().superRefine((scopes, ctx) => {
246
- if (scopes.create === void 0 && scopes.connect === void 0 && scopes.list === void 0) {
247
- ctx.addIssue({
248
- code: z3.ZodIssueCode.custom,
249
- message: "At least one tunnel scope action is required."
250
- });
251
- }
252
- });
253
- var authTokenScopesSchema = z3.object({
254
- tunnels: authTokenTunnelsScopesSchema.optional()
255
- // Scopes related to tunnels
256
- }).strict().superRefine((scopes, ctx) => {
257
- if (scopes.tunnels === void 0) {
258
- ctx.addIssue({
259
- code: z3.ZodIssueCode.custom,
260
- message: "Tunnel scopes are required.",
261
- path: ["tunnels"]
262
- });
263
- }
264
- });
265
- var authTokenTunnelGrantLeafSchema = z3.object({
266
- workspaces: z3.array(nonEmptyStringSchema).min(1).optional(),
267
- projects: z3.array(nonEmptyStringSchema).min(1).optional(),
268
- scopes: authTokenScopesSchema.optional()
269
- }).strict().superRefine((grant, ctx) => {
270
- if (grant.workspaces !== void 0 && grant.projects !== void 0) {
271
- ctx.addIssue({
272
- code: z3.ZodIssueCode.custom,
273
- message: "A grant cannot target workspaces and projects at the same time.",
274
- path: ["projects"]
275
- });
276
- }
277
- if (grant.workspaces === void 0 && grant.projects === void 0 && grant.scopes === void 0) {
278
- ctx.addIssue({
279
- code: z3.ZodIssueCode.custom,
280
- message: "A grant must target workspaces, projects, or scopes.",
281
- path: ["workspaces"]
282
- });
283
- }
284
- });
285
- var authTokenTunnelGrantSchema = z3.lazy(
286
- () => z3.union([
287
- authTokenTunnelGrantLeafSchema,
288
- z3.object({ AND: z3.array(authTokenTunnelGrantSchema).min(1) }).strict(),
289
- z3.object({ OR: z3.array(authTokenTunnelGrantSchema).min(1) }).strict()
290
- ])
291
- );
292
- var authTokenCommonSchema = {
293
- aud: z3.union([z3.string(), z3.array(z3.string())]).optional(),
294
- exp: z3.number().optional(),
295
- tunnelsGrants: authTokenTunnelGrantSchema.optional(),
296
- iat: z3.number().optional(),
297
- iss: z3.string().optional(),
298
- jti: z3.string().optional(),
299
- metadata: z3.object({
300
- engine: z3.string().optional()
301
- }).strict().optional(),
302
- nbf: z3.number().optional(),
303
- sub: z3.string().optional()
304
- };
305
- var authTokenSchema = z3.union([
306
- z3.object({
307
- type: z3.literal("auth"),
308
- userId: z3.string(),
309
- permissions: authTokenPermissionsSchema.nullable(),
310
- ...authTokenCommonSchema
311
- }).strict(),
312
- z3.object({
313
- type: z3.literal("pat"),
314
- tokendpoint: z3.string().optional(),
315
- token_endpoint: z3.string().optional(),
316
- ...authTokenCommonSchema
317
- }).strict(),
318
- z3.object({
319
- type: z3.literal("app"),
320
- clientId: z3.string(),
321
- permissions: authTokenPermissionsSchema.nullable(),
322
- ...authTokenCommonSchema
323
- }).strict()
324
- ]);
325
- var tokenSchema = authTokenSchema;
326
- var createAuthTokenParamsSchema = z3.object({
327
- expires_in: z3.number().int().min(1).max(3600).default(60),
328
- scopes: authTokenScopesSchema.optional(),
329
- tunnelsGrants: authTokenTunnelGrantSchema.optional(),
330
- metadata: z3.unknown().optional()
331
- // Additional metadata
332
- }).strict().superRefine((params, ctx) => {
333
- if (params.scopes !== void 0 && params.tunnelsGrants !== void 0) {
334
- ctx.addIssue({
335
- code: z3.ZodIssueCode.custom,
336
- message: "Use either scopes or tunnelsGrants, not both.",
337
- path: ["tunnelsGrants"]
338
- });
339
- }
340
- if (params.scopes === void 0 && params.tunnelsGrants === void 0) {
341
- ctx.addIssue({
342
- code: z3.ZodIssueCode.custom,
343
- message: "Explicit scopes or tunnelsGrants are required.",
344
- path: ["scopes"]
345
- });
346
- }
347
- });
348
- var createAuthTokenResponseSchema = z3.object({
349
- token: z3.string()
350
- });
351
-
352
- // src/auth-resource.ts
353
82
  var import_rstream2 = require("@rstreamlabs/rstream");
354
83
  var RstreamAuthResource = class {
355
84
  client;
@@ -371,14 +100,14 @@ var RstreamAuthResource = class {
371
100
  });
372
101
  }
373
102
  async resolveScopeOptions(params, options) {
374
- const tokenParams = createAuthTokenParamsSchema.parse(params);
103
+ const tokenParams = import_auth_token.createAuthTokenParamsSchema.parse(params);
375
104
  if (options?.projectScoped === false) {
376
105
  return options ?? {};
377
106
  }
378
107
  if (options?.projectId !== void 0 || options?.workspaceId !== void 0) {
379
108
  return options;
380
109
  }
381
- if (tokenParams.scopes === void 0 && !tunnelGrantsNeedDefaultTarget(tokenParams.tunnelsGrants)) {
110
+ if (!tunnelResourcesNeedDefaultTarget(tokenParams.resources?.tunnels)) {
382
111
  return options ?? {};
383
112
  }
384
113
  const target = await this.client.getEngineAuthTokenTarget();
@@ -390,13 +119,13 @@ var RstreamAuthResource = class {
390
119
  }
391
120
  };
392
121
  function createAuthTokenFromClientCredentials(credentials, params, options) {
393
- const tokenParams = createAuthTokenParamsSchema.parse(params);
122
+ const tokenParams = import_auth_token.createAuthTokenParamsSchema.parse(params);
394
123
  const payload = {
395
124
  metadata: {
396
125
  engine: options?.engine
397
126
  },
398
- tunnelsGrants: normalizeAuthTokenTunnelGrants(tokenParams, options),
399
- permissions: null
127
+ permissions: null,
128
+ resources: normalizeAuthTokenResources(tokenParams, options)
400
129
  };
401
130
  const { token } = (0, import_rstream.createClientCredentialsToken)(credentials, {
402
131
  claims: payload,
@@ -404,70 +133,73 @@ function createAuthTokenFromClientCredentials(credentials, params, options) {
404
133
  });
405
134
  return { token };
406
135
  }
407
- function normalizeAuthTokenTunnelGrants(params, options) {
408
- const tunnelsGrants = params.tunnelsGrants;
409
- if (tunnelsGrants !== void 0) {
410
- return applyDefaultTunnelGrantTarget(tunnelsGrants, options);
411
- }
412
- if (params.scopes) {
413
- return { ...normalizeTunnelGrantTarget(options), scopes: params.scopes };
414
- }
415
- return void 0;
136
+ function normalizeAuthTokenResources(params, options) {
137
+ return {
138
+ tunnels: applyDefaultTunnelResourceTarget(
139
+ requireTunnelResource(params),
140
+ options
141
+ )
142
+ };
143
+ }
144
+ function requireTunnelResource(params) {
145
+ const tunnels = params.resources?.tunnels;
146
+ if (tunnels !== void 0) return tunnels;
147
+ throw new Error("Explicit resources.tunnels is required.");
416
148
  }
417
- function applyDefaultTunnelGrantTarget(grants, options, inheritedTarget = false) {
149
+ function applyDefaultTunnelResourceTarget(resource, options, inheritedTarget = false) {
418
150
  if (options?.projectScoped === false) {
419
- return grants;
151
+ return resource;
420
152
  }
421
- if ("AND" in grants) {
422
- const branchHasTarget = inheritedTarget || grants.AND.some((grant) => tunnelGrantTreeHasTarget(grant));
153
+ if ("AND" in resource) {
154
+ const branchHasTarget = inheritedTarget || resource.AND.some((child) => tunnelResourceTreeHasTarget(child));
423
155
  return {
424
- AND: grants.AND.map(
425
- (grant) => applyDefaultTunnelGrantTarget(grant, options, branchHasTarget)
156
+ AND: resource.AND.map(
157
+ (child) => applyDefaultTunnelResourceTarget(child, options, branchHasTarget)
426
158
  )
427
159
  };
428
160
  }
429
- if ("OR" in grants) {
161
+ if ("OR" in resource) {
430
162
  return {
431
- OR: grants.OR.map(
432
- (grant) => applyDefaultTunnelGrantTarget(grant, options, inheritedTarget)
163
+ OR: resource.OR.map(
164
+ (child) => applyDefaultTunnelResourceTarget(child, options, inheritedTarget)
433
165
  )
434
166
  };
435
167
  }
436
- if (grants.scopes === void 0 || tunnelGrantHasTarget(grants) || inheritedTarget) {
437
- return grants;
168
+ if (resource.scopes === void 0 || tunnelResourceHasTarget(resource) || inheritedTarget) {
169
+ return resource;
438
170
  }
439
- return { ...normalizeTunnelGrantTarget(options), scopes: grants.scopes };
171
+ return { ...normalizeTunnelResourceTarget(options), scopes: resource.scopes };
440
172
  }
441
- function tunnelGrantsNeedDefaultTarget(grants, inheritedTarget = false) {
442
- if (grants === void 0) {
173
+ function tunnelResourcesNeedDefaultTarget(resource, inheritedTarget = false) {
174
+ if (resource === void 0) {
443
175
  return false;
444
176
  }
445
- if ("AND" in grants) {
446
- const branchHasTarget = inheritedTarget || grants.AND.some((grant) => tunnelGrantTreeHasTarget(grant));
447
- return grants.AND.some(
448
- (grant) => tunnelGrantsNeedDefaultTarget(grant, branchHasTarget)
177
+ if ("AND" in resource) {
178
+ const branchHasTarget = inheritedTarget || resource.AND.some((child) => tunnelResourceTreeHasTarget(child));
179
+ return resource.AND.some(
180
+ (child) => tunnelResourcesNeedDefaultTarget(child, branchHasTarget)
449
181
  );
450
182
  }
451
- if ("OR" in grants) {
452
- return grants.OR.some(
453
- (grant) => tunnelGrantsNeedDefaultTarget(grant, inheritedTarget)
183
+ if ("OR" in resource) {
184
+ return resource.OR.some(
185
+ (child) => tunnelResourcesNeedDefaultTarget(child, inheritedTarget)
454
186
  );
455
187
  }
456
- return grants.scopes !== void 0 && !tunnelGrantHasTarget(grants) && !inheritedTarget;
188
+ return resource.scopes !== void 0 && !tunnelResourceHasTarget(resource) && !inheritedTarget;
457
189
  }
458
- function tunnelGrantHasTarget(grant) {
459
- return grant.projects !== void 0 || grant.workspaces !== void 0;
190
+ function tunnelResourceHasTarget(resource) {
191
+ return resource.projects !== void 0 || resource.workspaces !== void 0;
460
192
  }
461
- function tunnelGrantTreeHasTarget(grants) {
462
- if ("AND" in grants) {
463
- return grants.AND.some((grant) => tunnelGrantTreeHasTarget(grant));
193
+ function tunnelResourceTreeHasTarget(resource) {
194
+ if ("AND" in resource) {
195
+ return resource.AND.some((child) => tunnelResourceTreeHasTarget(child));
464
196
  }
465
- if ("OR" in grants) {
466
- return grants.OR.some((grant) => tunnelGrantTreeHasTarget(grant));
197
+ if ("OR" in resource) {
198
+ return resource.OR.some((child) => tunnelResourceTreeHasTarget(child));
467
199
  }
468
- return tunnelGrantHasTarget(grants);
200
+ return tunnelResourceHasTarget(resource);
469
201
  }
470
- function normalizeTunnelGrantTarget(options) {
202
+ function normalizeTunnelResourceTarget(options) {
471
203
  const projectId = normalizeOptionalString(options?.projectId);
472
204
  const workspaceId = normalizeOptionalString(options?.workspaceId);
473
205
  if (projectId !== void 0 && workspaceId !== void 0) {
@@ -483,7 +215,7 @@ function normalizeTunnelGrantTarget(options) {
483
215
  return {};
484
216
  }
485
217
  throw new Error(
486
- "Project ID or workspace ID is required when using scope-only tunnel grants."
218
+ "Project ID or workspace ID is required when using scope-only tunnel resources."
487
219
  );
488
220
  }
489
221
  function normalizeOptionalString(value) {
@@ -492,24 +224,24 @@ function normalizeOptionalString(value) {
492
224
  }
493
225
 
494
226
  // src/client.ts
495
- var z4 = __toESM(require("zod"));
496
- var clientSchema = z4.object({
497
- id: z4.string(),
498
- status: z4.enum(["online", "offline"]),
499
- user_id: z4.string().optional(),
500
- workspace_id: z4.string().optional(),
501
- project_id: z4.string().optional(),
502
- cluster_id: z4.string().optional(),
503
- plan: z4.string().optional(),
504
- provider: z4.string().optional(),
505
- region: z4.string().optional(),
506
- agent: z4.string().optional(),
507
- channel: z4.string().optional(),
508
- version: z4.string().optional(),
509
- os: z4.string().optional(),
510
- arch: z4.string().optional(),
511
- protocol_version: z4.string().optional(),
512
- labels: z4.record(z4.string(), z4.string()).optional()
227
+ var z = __toESM(require("zod"));
228
+ var clientSchema = z.object({
229
+ id: z.string(),
230
+ status: z.enum(["online", "offline"]),
231
+ user_id: z.string().optional(),
232
+ workspace_id: z.string().optional(),
233
+ project_id: z.string().optional(),
234
+ cluster_id: z.string().optional(),
235
+ plan: z.string().optional(),
236
+ provider: z.string().optional(),
237
+ region: z.string().optional(),
238
+ agent: z.string().optional(),
239
+ channel: z.string().optional(),
240
+ version: z.string().optional(),
241
+ os: z.string().optional(),
242
+ arch: z.string().optional(),
243
+ protocol_version: z.string().optional(),
244
+ labels: z.record(z.string(), z.string()).optional()
513
245
  });
514
246
  var clientFilterSchema = clientSchema.pick({
515
247
  id: true,
@@ -523,11 +255,11 @@ var clientFilterSchema = clientSchema.pick({
523
255
  protocol_version: true,
524
256
  labels: true
525
257
  }).partial();
526
- var listClientsParamsSchema = z4.object({
527
- limit: z4.number().int().min(1).optional(),
258
+ var listClientsParamsSchema = z.object({
259
+ limit: z.number().int().min(1).optional(),
528
260
  filters: clientFilterSchema.optional()
529
261
  });
530
- var listClientsResponseSchema = z4.array(clientSchema);
262
+ var listClientsResponseSchema = z.array(clientSchema);
531
263
 
532
264
  // src/clients-resource.ts
533
265
  function clientPathId(id) {
@@ -561,200 +293,200 @@ var RstreamClientsResource = class {
561
293
  };
562
294
 
563
295
  // src/stream.ts
564
- var z5 = __toESM(require("zod"));
565
- var nonEmptyStringSchema2 = z5.string().min(1);
566
- var isoDateTimeSchema = z5.string().datetime({ offset: true });
567
- var ipAddressSchema = z5.string();
568
- var intNonNegSchema = z5.number().int().nonnegative();
569
- var numNonNegSchema = z5.number().nonnegative();
570
- var geolocationSchema = z5.object({
571
- country: z5.string().optional(),
572
- region: z5.string().optional()
296
+ var z2 = __toESM(require("zod"));
297
+ var nonEmptyStringSchema = z2.string().min(1);
298
+ var isoDateTimeSchema = z2.string().datetime({ offset: true });
299
+ var ipAddressSchema = z2.string();
300
+ var intNonNegSchema = z2.number().int().nonnegative();
301
+ var numNonNegSchema = z2.number().nonnegative();
302
+ var geolocationSchema = z2.object({
303
+ country: z2.string().optional(),
304
+ region: z2.string().optional()
573
305
  });
574
- var streamTLSInfoSchema = z5.object({
575
- version: z5.string().min(1).optional(),
576
- cipher: z5.string().min(1).optional(),
577
- protocol: z5.string().min(1).optional(),
578
- curve: z5.string().min(1).optional(),
579
- ech: z5.boolean().optional()
306
+ var streamTLSInfoSchema = z2.object({
307
+ version: z2.string().min(1).optional(),
308
+ cipher: z2.string().min(1).optional(),
309
+ protocol: z2.string().min(1).optional(),
310
+ curve: z2.string().min(1).optional(),
311
+ ech: z2.boolean().optional()
580
312
  });
581
- var streamEndpointSchema = z5.object({
313
+ var streamEndpointSchema = z2.object({
582
314
  ip: ipAddressSchema.optional(),
583
315
  geolocation: geolocationSchema.optional(),
584
316
  tls: streamTLSInfoSchema.optional()
585
317
  });
586
- var httpHeadersSchema = z5.record(
587
- z5.string(),
588
- z5.union([z5.string(), z5.array(z5.string())])
318
+ var httpHeadersSchema = z2.record(
319
+ z2.string(),
320
+ z2.union([z2.string(), z2.array(z2.string())])
589
321
  );
590
- var httpProtocolSchema = z5.enum(["http/1.1", "h2", "h2c", "h3"]);
591
- var httpRequestSchema = z5.object({
592
- method: nonEmptyStringSchema2,
593
- scheme: z5.string().min(1).optional(),
594
- host: nonEmptyStringSchema2.optional(),
595
- path: nonEmptyStringSchema2.optional(),
596
- query: z5.string().optional(),
597
- url: nonEmptyStringSchema2.optional(),
322
+ var httpProtocolSchema = z2.enum(["http/1.1", "h2", "h2c", "h3"]);
323
+ var httpRequestSchema = z2.object({
324
+ method: nonEmptyStringSchema,
325
+ scheme: z2.string().min(1).optional(),
326
+ host: nonEmptyStringSchema.optional(),
327
+ path: nonEmptyStringSchema.optional(),
328
+ query: z2.string().optional(),
329
+ url: nonEmptyStringSchema.optional(),
598
330
  headers: httpHeadersSchema.optional(),
599
- userAgent: z5.string().optional()
331
+ userAgent: z2.string().optional()
600
332
  });
601
- var httpResponseSchema = z5.object({
602
- status: z5.number().int().min(100).max(999),
333
+ var httpResponseSchema = z2.object({
334
+ status: z2.number().int().min(100).max(999),
603
335
  headers: httpHeadersSchema.optional()
604
336
  });
605
- var httpRequestStageSchema = z5.object({
337
+ var httpRequestStageSchema = z2.object({
606
338
  protocol: httpProtocolSchema.optional(),
607
339
  request: httpRequestSchema
608
340
  });
609
- var httpResponseStageSchema = z5.object({
341
+ var httpResponseStageSchema = z2.object({
610
342
  protocol: httpProtocolSchema.optional(),
611
343
  response: httpResponseSchema
612
344
  });
613
- var tokenSourceSchema = z5.enum([
345
+ var tokenSourceSchema = z2.enum([
614
346
  "authorization",
615
347
  "query",
616
348
  "client",
617
349
  "unknown"
618
350
  ]);
619
- var tokenTypeSchema = z5.enum(["auth", "pat", "app", "unknown"]);
620
- var firewallRuleSchema = z5.discriminatedUnion("kind", [
621
- z5.object({ kind: z5.literal("none") }),
622
- z5.object({ kind: z5.literal("mtls") }),
623
- z5.object({
624
- kind: z5.literal("rstream_auth"),
625
- source: z5.literal("rstream_auth")
351
+ var tokenTypeSchema = z2.enum(["auth", "pat", "app", "unknown"]);
352
+ var firewallRuleSchema = z2.discriminatedUnion("kind", [
353
+ z2.object({ kind: z2.literal("none") }),
354
+ z2.object({ kind: z2.literal("mtls") }),
355
+ z2.object({
356
+ kind: z2.literal("rstream_auth"),
357
+ source: z2.literal("rstream_auth")
626
358
  }),
627
- z5.object({
628
- kind: z5.literal("token"),
359
+ z2.object({
360
+ kind: z2.literal("token"),
629
361
  source: tokenSourceSchema.optional(),
630
362
  tokenType: tokenTypeSchema.optional()
631
363
  })
632
364
  ]);
633
- var unauthorizedSourceSchema = z5.object({
365
+ var unauthorizedSourceSchema = z2.object({
634
366
  source: tokenSourceSchema
635
367
  });
636
- var unauthorizedReasonSchema = (shape) => z5.object(shape).merge(unauthorizedSourceSchema);
637
- var unauthorizedSchema = z5.discriminatedUnion("reason", [
368
+ var unauthorizedReasonSchema = (shape) => z2.object(shape).merge(unauthorizedSourceSchema);
369
+ var unauthorizedSchema = z2.discriminatedUnion("reason", [
638
370
  unauthorizedReasonSchema({
639
- reason: z5.literal("missing_token")
371
+ reason: z2.literal("missing_token")
640
372
  }),
641
373
  unauthorizedReasonSchema({
642
- reason: z5.literal("invalid_token")
374
+ reason: z2.literal("invalid_token")
643
375
  }),
644
376
  unauthorizedReasonSchema({
645
- reason: z5.literal("expired_token")
377
+ reason: z2.literal("expired_token")
646
378
  }),
647
379
  unauthorizedReasonSchema({
648
- reason: z5.literal("invalid_secret")
380
+ reason: z2.literal("invalid_secret")
649
381
  }),
650
382
  unauthorizedReasonSchema({
651
- reason: z5.literal("user_mismatch")
383
+ reason: z2.literal("user_mismatch")
652
384
  }),
653
385
  unauthorizedReasonSchema({
654
- reason: z5.literal("insufficient_scope")
386
+ reason: z2.literal("insufficient_scope")
655
387
  }),
656
388
  unauthorizedReasonSchema({
657
- reason: z5.literal("policy_denied"),
658
- policy: z5.enum(["ip", "geo", "mtls", "challenge", "other"]),
659
- value: z5.string().optional()
389
+ reason: z2.literal("policy_denied"),
390
+ policy: z2.enum(["ip", "geo", "mtls", "challenge", "other"]),
391
+ value: z2.string().optional()
660
392
  })
661
393
  ]);
662
- var failureSchema = z5.discriminatedUnion("kind", [
663
- z5.object({
664
- kind: z5.literal("timeout"),
394
+ var failureSchema = z2.discriminatedUnion("kind", [
395
+ z2.object({
396
+ kind: z2.literal("timeout"),
665
397
  timeoutMs: intNonNegSchema.optional(),
666
- message: z5.string().optional()
398
+ message: z2.string().optional()
667
399
  }),
668
- z5.object({
669
- kind: z5.literal("unauthorized"),
400
+ z2.object({
401
+ kind: z2.literal("unauthorized"),
670
402
  why: unauthorizedSchema,
671
- message: z5.string().optional()
403
+ message: z2.string().optional()
672
404
  }),
673
- z5.object({
674
- kind: z5.literal("not_found"),
675
- resource: z5.enum(["tunnel", "client", "route"]),
676
- message: z5.string().optional()
405
+ z2.object({
406
+ kind: z2.literal("not_found"),
407
+ resource: z2.enum(["tunnel", "client", "route"]),
408
+ message: z2.string().optional()
677
409
  }),
678
- z5.object({
679
- kind: z5.literal("refused"),
680
- reason: z5.enum(["capacity", "policy", "unsupported", "other"]),
681
- message: z5.string().optional()
410
+ z2.object({
411
+ kind: z2.literal("refused"),
412
+ reason: z2.enum(["capacity", "policy", "unsupported", "other"]),
413
+ message: z2.string().optional()
682
414
  }),
683
- z5.object({ kind: z5.literal("io"), message: z5.string().optional() }),
684
- z5.object({ kind: z5.literal("internal"), message: z5.string().optional() })
415
+ z2.object({ kind: z2.literal("io"), message: z2.string().optional() }),
416
+ z2.object({ kind: z2.literal("internal"), message: z2.string().optional() })
685
417
  ]);
686
- var firewallSchema = z5.discriminatedUnion("decision", [
687
- z5.object({ decision: z5.literal("allowed"), rule: firewallRuleSchema }),
688
- z5.object({
689
- decision: z5.literal("denied"),
418
+ var firewallSchema = z2.discriminatedUnion("decision", [
419
+ z2.object({ decision: z2.literal("allowed"), rule: firewallRuleSchema }),
420
+ z2.object({
421
+ decision: z2.literal("denied"),
690
422
  rule: firewallRuleSchema,
691
423
  failure: failureSchema
692
424
  })
693
425
  ]);
694
- var routedTunnelSchema = z5.object({
695
- tunnelId: nonEmptyStringSchema2.optional(),
696
- tunnelName: z5.string().optional(),
697
- hostname: z5.string().optional(),
698
- protocol: z5.string().optional(),
699
- published: z5.boolean().optional(),
700
- type: z5.string().optional(),
701
- tlsMode: z5.string().optional(),
702
- httpVersion: z5.string().optional(),
703
- httpUseTls: z5.boolean().optional(),
704
- upstreamTls: z5.boolean().optional(),
705
- tokenAuth: z5.boolean().optional(),
706
- mtls_auth: z5.boolean().optional()
426
+ var routedTunnelSchema = z2.object({
427
+ tunnelId: nonEmptyStringSchema.optional(),
428
+ tunnelName: z2.string().optional(),
429
+ hostname: z2.string().optional(),
430
+ protocol: z2.string().optional(),
431
+ published: z2.boolean().optional(),
432
+ type: z2.string().optional(),
433
+ tlsMode: z2.string().optional(),
434
+ httpVersion: z2.string().optional(),
435
+ httpUseTls: z2.boolean().optional(),
436
+ upstreamTls: z2.boolean().optional(),
437
+ tokenAuth: z2.boolean().optional(),
438
+ mtls_auth: z2.boolean().optional()
707
439
  });
708
- var routingSchema = z5.discriminatedUnion("decision", [
709
- z5.object({ decision: z5.literal("routed"), tunnel: routedTunnelSchema }),
710
- z5.object({ decision: z5.literal("not_routed"), failure: failureSchema })
440
+ var routingSchema = z2.discriminatedUnion("decision", [
441
+ z2.object({ decision: z2.literal("routed"), tunnel: routedTunnelSchema }),
442
+ z2.object({ decision: z2.literal("not_routed"), failure: failureSchema })
711
443
  ]);
712
- var streamConnectedMetricsSchema = z5.object({
444
+ var streamConnectedMetricsSchema = z2.object({
713
445
  establish_ms: numNonNegSchema,
714
446
  duration_ms: numNonNegSchema,
715
447
  upstream_bytes: intNonNegSchema,
716
448
  downstream_bytes: intNonNegSchema
717
449
  });
718
- var streamFailedMetricsSchema = z5.object({
450
+ var streamFailedMetricsSchema = z2.object({
719
451
  time_to_fail_ms: numNonNegSchema.optional(),
720
452
  establish_ms: numNonNegSchema.optional()
721
453
  });
722
- var terminationSchema = z5.object({
723
- by: z5.enum(["downstream", "upstream", "server", "unknown"]),
724
- reason: z5.enum(["closed", "reset", "timeout", "error", "unknown"]),
725
- message: z5.string().optional()
454
+ var terminationSchema = z2.object({
455
+ by: z2.enum(["downstream", "upstream", "server", "unknown"]),
456
+ reason: z2.enum(["closed", "reset", "timeout", "error", "unknown"]),
457
+ message: z2.string().optional()
726
458
  });
727
- var responseConnectedSchema = z5.object({
728
- outcome: z5.literal("connected"),
459
+ var responseConnectedSchema = z2.object({
460
+ outcome: z2.literal("connected"),
729
461
  established_at: isoDateTimeSchema,
730
462
  upstream: streamEndpointSchema.optional(),
731
463
  metrics: streamConnectedMetricsSchema,
732
464
  termination: terminationSchema.optional(),
733
465
  http: httpResponseStageSchema.optional()
734
466
  });
735
- var responseFailedSchema = z5.object({
736
- outcome: z5.literal("failed"),
467
+ var responseFailedSchema = z2.object({
468
+ outcome: z2.literal("failed"),
737
469
  failure: failureSchema,
738
470
  upstream: streamEndpointSchema.optional(),
739
471
  metrics: streamFailedMetricsSchema.optional(),
740
472
  termination: terminationSchema.optional(),
741
473
  http: httpResponseStageSchema.optional()
742
474
  });
743
- var responseSchema = z5.discriminatedUnion("outcome", [
475
+ var responseSchema = z2.discriminatedUnion("outcome", [
744
476
  responseConnectedSchema,
745
477
  responseFailedSchema
746
478
  ]);
747
- var streamSummarySchema = z5.object({
748
- workspace_id: nonEmptyStringSchema2.optional(),
749
- project_id: nonEmptyStringSchema2.optional(),
750
- cluster_id: nonEmptyStringSchema2.optional(),
751
- user_id: nonEmptyStringSchema2.optional(),
752
- client_id: nonEmptyStringSchema2.optional(),
753
- tunnel_id: nonEmptyStringSchema2.optional(),
754
- stream_id: nonEmptyStringSchema2,
479
+ var streamSummarySchema = z2.object({
480
+ workspace_id: nonEmptyStringSchema.optional(),
481
+ project_id: nonEmptyStringSchema.optional(),
482
+ cluster_id: nonEmptyStringSchema.optional(),
483
+ user_id: nonEmptyStringSchema.optional(),
484
+ client_id: nonEmptyStringSchema.optional(),
485
+ tunnel_id: nonEmptyStringSchema.optional(),
486
+ stream_id: nonEmptyStringSchema,
755
487
  created_at: isoDateTimeSchema,
756
488
  terminated_at: isoDateTimeSchema,
757
- request: z5.object({
489
+ request: z2.object({
758
490
  downstream: streamEndpointSchema,
759
491
  http: httpRequestStageSchema.optional()
760
492
  }),
@@ -764,68 +496,100 @@ var streamSummarySchema = z5.object({
764
496
  });
765
497
 
766
498
  // src/event.ts
767
- var z6 = __toESM(require("zod"));
768
- var isoDateTimeSchema2 = z6.string().datetime({ offset: true });
769
- var initialStateSchema = z6.object({
499
+ var import_tunnel = require("@rstreamlabs/rstream/tunnel");
500
+ var z3 = __toESM(require("zod"));
501
+ var isoDateTimeSchema2 = z3.string().datetime({ offset: true });
502
+ var initialStateSchema = z3.object({
770
503
  snapshot_at: isoDateTimeSchema2,
771
- clients: z6.array(clientSchema),
772
- tunnels: z6.array(tunnelSchema)
504
+ clients: z3.array(clientSchema),
505
+ tunnels: z3.array(import_tunnel.tunnelSchema)
773
506
  });
774
- var eventBaseSchema = z6.object({
775
- id: z6.string().optional(),
507
+ var eventBaseSchema = z3.object({
508
+ id: z3.string().optional(),
776
509
  created_at: isoDateTimeSchema2.optional(),
777
- user_id: z6.string().optional(),
778
- workspace_id: z6.string().optional(),
779
- project_id: z6.string().optional(),
780
- cluster_id: z6.string().optional()
510
+ user_id: z3.string().optional(),
511
+ workspace_id: z3.string().optional(),
512
+ project_id: z3.string().optional(),
513
+ cluster_id: z3.string().optional()
781
514
  });
782
- var withEventBase = (shape) => z6.object(shape).merge(eventBaseSchema).passthrough();
515
+ var withEventBase = (shape) => z3.object(shape).merge(eventBaseSchema).passthrough();
783
516
  var stateInitialEventSchema = withEventBase({
784
- type: z6.literal("state.initial"),
517
+ type: z3.literal("state.initial"),
785
518
  object: initialStateSchema
786
519
  });
787
520
  var streamSummaryEventSchema = withEventBase({
788
- type: z6.literal("stream.summary"),
521
+ type: z3.literal("stream.summary"),
789
522
  object: streamSummarySchema
790
523
  });
791
524
  var commonEventsSchema = [
792
525
  withEventBase({
793
- type: z6.literal("client.created"),
526
+ type: z3.literal("client.created"),
794
527
  object: clientSchema
795
528
  }),
796
529
  withEventBase({
797
- type: z6.literal("client.updated"),
530
+ type: z3.literal("client.updated"),
798
531
  object: clientSchema
799
532
  }),
800
533
  withEventBase({
801
- type: z6.literal("client.deleted"),
534
+ type: z3.literal("client.deleted"),
802
535
  object: clientSchema
803
536
  }),
804
537
  withEventBase({
805
- type: z6.literal("tunnel.created"),
806
- object: tunnelSchema
538
+ type: z3.literal("tunnel.created"),
539
+ object: import_tunnel.tunnelSchema
807
540
  }),
808
541
  withEventBase({
809
- type: z6.literal("tunnel.updated"),
810
- object: tunnelSchema
542
+ type: z3.literal("tunnel.updated"),
543
+ object: import_tunnel.tunnelSchema
811
544
  }),
812
545
  withEventBase({
813
- type: z6.literal("tunnel.deleted"),
814
- object: tunnelSchema
546
+ type: z3.literal("tunnel.deleted"),
547
+ object: import_tunnel.tunnelSchema
815
548
  })
816
549
  ];
817
- var wsEventsSchema = z6.union([
550
+ var wsEventsSchema = z3.union([
818
551
  stateInitialEventSchema,
819
552
  ...commonEventsSchema
820
553
  ]);
821
- var webhookEventsSchema = z6.union([
554
+ var webhookEventsSchema = z3.union([
822
555
  ...commonEventsSchema,
823
556
  streamSummaryEventSchema
824
557
  ]);
825
- var eventSchema = z6.union([wsEventsSchema, webhookEventsSchema]);
558
+ var eventSchema = z3.union([wsEventsSchema, webhookEventsSchema]);
559
+
560
+ // src/tunnel.ts
561
+ var import_tunnel2 = require("@rstreamlabs/rstream/tunnel");
562
+ var z4 = __toESM(require("zod"));
563
+ var DEFAULT_PUBLISHED_PORT = 443;
564
+ var tunnelFilterSchema = import_tunnel2.tunnelSchema.pick({
565
+ id: true,
566
+ name: true,
567
+ type: true,
568
+ status: true,
569
+ client_id: true,
570
+ user_id: true,
571
+ publish: true,
572
+ protocol: true,
573
+ hostname: true,
574
+ http_version: true,
575
+ labels: true
576
+ }).partial();
577
+ var listTunnelsParamsSchema = z4.object({
578
+ limit: z4.number().int().min(1).optional(),
579
+ filters: tunnelFilterSchema.optional()
580
+ });
581
+ var listTunnelsResponseSchema = z4.array(import_tunnel2.tunnelSchema);
582
+ function formatTunnelHost(tunnel) {
583
+ if (!tunnel.hostname) return tunnel.host;
584
+ if (!tunnel.port || tunnel.port === DEFAULT_PUBLISHED_PORT) {
585
+ return tunnel.hostname;
586
+ }
587
+ return `${tunnel.hostname}:${tunnel.port}`;
588
+ }
826
589
 
827
590
  // src/openapi.ts
828
- var z7 = __toESM(require("zod"));
591
+ var import_tunnel5 = require("@rstreamlabs/rstream/tunnel");
592
+ var z5 = __toESM(require("zod"));
829
593
  var jsonContentType = "application/json";
830
594
  var openApiContentType = "application/vnd.oai.openapi+json;version=3.1";
831
595
  function isRecord(value) {
@@ -839,10 +603,10 @@ function dropSchemaKeyword(value) {
839
603
  }
840
604
  function jsonSchemaFor(schema) {
841
605
  return dropSchemaKeyword(
842
- z7.toJSONSchema(schema, {
606
+ z5.toJSONSchema(schema, {
843
607
  unrepresentable: "any",
844
608
  override: (ctx) => {
845
- if (ctx.zodSchema instanceof z7.ZodDate) {
609
+ if (ctx.zodSchema instanceof z5.ZodDate) {
846
610
  ctx.jsonSchema.type = "string";
847
611
  ctx.jsonSchema.format = "date-time";
848
612
  }
@@ -909,7 +673,7 @@ var readEngineStreamsRules = [
909
673
  action: "read"
910
674
  }
911
675
  ];
912
- var watchParamsSchema = z7.object({
676
+ var watchParamsSchema = z5.object({
913
677
  clients: clientFilterSchema.optional(),
914
678
  tunnels: tunnelFilterSchema.optional()
915
679
  });
@@ -1037,7 +801,7 @@ var engineOpenApiDocument = {
1037
801
  Event: jsonSchemaFor(wsEventsSchema),
1038
802
  ListClientsParams: jsonSchemaFor(listClientsParamsSchema),
1039
803
  ListTunnelsParams: jsonSchemaFor(listTunnelsParamsSchema),
1040
- TunnelListItem: jsonSchemaFor(tunnelSchema),
804
+ TunnelListItem: jsonSchemaFor(import_tunnel5.tunnelSchema),
1041
805
  WatchParams: jsonSchemaFor(watchParamsSchema)
1042
806
  }
1043
807
  },
@@ -1288,6 +1052,7 @@ async function resolveManagedTunnelsProject(config) {
1288
1052
  }
1289
1053
 
1290
1054
  // src/tunnels-resource.ts
1055
+ var import_tunnel7 = require("@rstreamlabs/rstream/tunnel");
1291
1056
  function tunnelPathId(id) {
1292
1057
  const normalized = id.trim();
1293
1058
  if (!normalized) {
@@ -1314,34 +1079,34 @@ var RstreamTunnelsResource = class {
1314
1079
  method: "GET"
1315
1080
  }
1316
1081
  );
1317
- return tunnelSchema.parse(response);
1082
+ return import_tunnel7.tunnelSchema.parse(response);
1318
1083
  }
1319
1084
  };
1320
1085
 
1321
1086
  // src/tunnels.ts
1087
+ var import_rstream11 = require("@rstreamlabs/rstream");
1322
1088
  var import_rstream12 = require("@rstreamlabs/rstream");
1323
1089
  var import_rstream13 = require("@rstreamlabs/rstream");
1324
- var import_rstream14 = require("@rstreamlabs/rstream");
1325
1090
 
1326
1091
  // src/turn.ts
1327
1092
  var import_rstream8 = require("@rstreamlabs/rstream");
1328
1093
  var import_rstream9 = require("@rstreamlabs/rstream");
1329
1094
  var import_rstream10 = require("@rstreamlabs/rstream");
1330
- var import_rstream11 = require("@rstreamlabs/rstream");
1331
- var z8 = __toESM(require("zod"));
1095
+ var import_turn = require("@rstreamlabs/rstream/turn");
1096
+ var z6 = __toESM(require("zod"));
1332
1097
  var import_crypto = __toESM(require("crypto"));
1333
1098
  var defaultTURNPort = 3478;
1334
1099
  var defaultTURNSPort = 5349;
1335
1100
  var defaultTURNCredentialTTLSeconds = 10 * 60;
1336
1101
  var maxTURNCredentialTTLSeconds = 60 * 60;
1337
- var turnTokenClaimsSchema = z8.object({
1338
- exp: z8.number().int().optional(),
1339
- iat: z8.number().int().optional(),
1340
- token_endpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
1341
- tokendpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
1342
- type: z8.enum(["app", "auth", "pat"])
1102
+ var turnTokenClaimsSchema = z6.object({
1103
+ exp: z6.number().int().optional(),
1104
+ iat: z6.number().int().optional(),
1105
+ token_endpoint: z6.string().regex(/^[0-9a-f]{8}$/i).optional(),
1106
+ tokendpoint: z6.string().regex(/^[0-9a-f]{8}$/i).optional(),
1107
+ type: z6.enum(["app", "auth", "pat"])
1343
1108
  });
1344
- var turnCredentialModeSchema = z8.enum(["api", "app", "pat"]);
1109
+ var turnCredentialModeSchema = z6.enum(["api", "app", "pat"]);
1345
1110
  function normalizeOptionalString2(value) {
1346
1111
  const normalized = value?.trim();
1347
1112
  return normalized ? normalized : void 0;
@@ -1367,6 +1132,9 @@ function normalizeTTLSeconds(ttlSeconds) {
1367
1132
  }
1368
1133
  return ttl;
1369
1134
  }
1135
+ function createAPITURNCredentialsParams(ttlSeconds) {
1136
+ return ttlSeconds === void 0 ? {} : { ttlSeconds: normalizeTTLSeconds(ttlSeconds) };
1137
+ }
1370
1138
  function normalizePort(port, fallback, name) {
1371
1139
  const normalized = port ?? fallback;
1372
1140
  if (!Number.isInteger(normalized) || normalized < 1 || normalized > 65535) {
@@ -1396,19 +1164,21 @@ function parseTURNTokenClaims(token) {
1396
1164
  if (!payloadPart) {
1397
1165
  throw new Error("Invalid token format.");
1398
1166
  }
1399
- let decoded;
1400
- try {
1401
- const payload = Buffer.from(payloadPart, "base64url").toString("utf8");
1402
- decoded = JSON.parse(payload);
1403
- } catch {
1404
- throw new Error("Invalid token format.");
1405
- }
1167
+ const decoded = parseTURNTokenPayload(payloadPart);
1406
1168
  const parsed = turnTokenClaimsSchema.safeParse(decoded);
1407
1169
  if (!parsed.success) {
1408
1170
  throw new Error("Invalid token format.");
1409
1171
  }
1410
1172
  return parsed.data;
1411
1173
  }
1174
+ function parseTURNTokenPayload(payloadPart) {
1175
+ try {
1176
+ const payload = Buffer.from(payloadPart, "base64url").toString("utf8");
1177
+ return JSON.parse(payload);
1178
+ } catch {
1179
+ throw new Error("Invalid token format.");
1180
+ }
1181
+ }
1412
1182
  function requirePATExpiration(claims, now) {
1413
1183
  const exp = claims.exp;
1414
1184
  if (typeof exp !== "number") {
@@ -1482,8 +1252,12 @@ async function createAPITURNCredentials(options) {
1482
1252
  apiUrl: options.apiUrl,
1483
1253
  credentials: options.credentials
1484
1254
  });
1255
+ const params = createAPITURNCredentialsParams(options.ttlSeconds);
1485
1256
  if (projectId) {
1486
- return await client.tunnels.projects.createTurnCredentials(projectId);
1257
+ return await client.tunnels.projects.createTurnCredentials(
1258
+ projectId,
1259
+ params
1260
+ );
1487
1261
  }
1488
1262
  if (!projectEndpoint) {
1489
1263
  throw new Error(
@@ -1491,7 +1265,8 @@ async function createAPITURNCredentials(options) {
1491
1265
  );
1492
1266
  }
1493
1267
  return await client.tunnels.projects.createTurnCredentialsByEndpoint(
1494
- projectEndpoint
1268
+ projectEndpoint,
1269
+ params
1495
1270
  );
1496
1271
  }
1497
1272
  function createPATTURNCredentials(options) {
@@ -1535,7 +1310,7 @@ function createPATTURNCredentials(options) {
1535
1310
  )
1536
1311
  );
1537
1312
  const credential = import_crypto.default.createHmac("sha256", key).update(username, "utf8").digest("base64");
1538
- return import_rstream11.turnCredentialsSchema.parse({
1313
+ return import_turn.turnCredentialsSchema.parse({
1539
1314
  credential,
1540
1315
  ttl,
1541
1316
  urls: createTURNURLs(clusterDomain, options.turnPort, options.turnsPort),
@@ -1587,7 +1362,7 @@ async function createAPPTURNCredentials(options) {
1587
1362
  )
1588
1363
  );
1589
1364
  const credential = import_crypto.default.createHmac("sha256", key).update(username, "utf8").digest("base64");
1590
- return import_rstream11.turnCredentialsSchema.parse({
1365
+ return import_turn.turnCredentialsSchema.parse({
1591
1366
  credential,
1592
1367
  ttl: ttlSeconds,
1593
1368
  urls: createTURNURLs(clusterDomain, options.turnPort, options.turnsPort),
@@ -1609,7 +1384,8 @@ async function createTURNCredentials(options) {
1609
1384
  apiUrl: options.apiUrl,
1610
1385
  credentials: controlPlaneCredentials,
1611
1386
  projectEndpoint,
1612
- projectId: options.projectId
1387
+ projectId: options.projectId,
1388
+ ttlSeconds: options.ttlSeconds
1613
1389
  });
1614
1390
  }
1615
1391
  const clusterDomain = normalizeClusterDomain(options.clusterDomain) ?? (projectEndpoint && options.engine ? deriveClusterDomainFromEngine(projectEndpoint, options.engine) : void 0);
@@ -1802,10 +1578,10 @@ var RstreamTunnelsClient = class {
1802
1578
  const projectEndpoint = normalizeOptionalString3(
1803
1579
  this.config?.projectEndpoint
1804
1580
  );
1805
- if (projectEndpoint !== void 0 && normalizeOptionalString3(this.config?.engine) === void 0 && (0, import_rstream14.readEnvironment)().engine === void 0) {
1581
+ if (projectEndpoint !== void 0 && normalizeOptionalString3(this.config?.engine) === void 0 && (0, import_rstream13.readEnvironment)().engine === void 0) {
1806
1582
  const project = await this.getManagedProject();
1807
1583
  if (project !== void 0) {
1808
- const engine = (0, import_rstream12.getTunnelsProjectEngine)(project);
1584
+ const engine = (0, import_rstream11.getTunnelsProjectEngine)(project);
1809
1585
  if (engine) {
1810
1586
  return normalizeEngineAddress(engine);
1811
1587
  }
@@ -1845,9 +1621,11 @@ var RstreamTunnelsClient = class {
1845
1621
  async getEngineAuthTokenParams() {
1846
1622
  const target = await this.getEngineAuthTokenTarget();
1847
1623
  return {
1848
- tunnelsGrants: {
1849
- ...target,
1850
- scopes: engineAuthTokenScopes
1624
+ resources: {
1625
+ tunnels: {
1626
+ ...target,
1627
+ scopes: engineAuthTokenScopes
1628
+ }
1851
1629
  }
1852
1630
  };
1853
1631
  }
@@ -1891,7 +1669,7 @@ var RstreamTunnelsClient = class {
1891
1669
  if (!credentials) {
1892
1670
  return void 0;
1893
1671
  }
1894
- if (!(0, import_rstream13.isClientCredentials)(credentials)) {
1672
+ if (!(0, import_rstream12.isClientCredentials)(credentials)) {
1895
1673
  return credentials.token;
1896
1674
  }
1897
1675
  const tokenParams = await this.getEngineAuthTokenParams();
@@ -1929,6 +1707,7 @@ function normalizeOptionalString3(value) {
1929
1707
  }
1930
1708
 
1931
1709
  // src/watch.ts
1710
+ var import_auth_token2 = require("@rstreamlabs/rstream/auth-token");
1932
1711
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
1933
1712
  var maxWatchTokenLifetimeSeconds = 3600;
1934
1713
  var watchTokenIssuedAtSkewSeconds = 300;
@@ -1942,7 +1721,7 @@ function normalizeTransport(transport) {
1942
1721
  throw new Error("Watch: Unsupported transport.");
1943
1722
  }
1944
1723
  function validateWatchQueryToken(token) {
1945
- const parsed = authTokenSchema.safeParse(import_jsonwebtoken.default.decode(token));
1724
+ const parsed = import_auth_token2.authTokenSchema.safeParse(import_jsonwebtoken.default.decode(token));
1946
1725
  if (!parsed.success || parsed.data.type === "pat") {
1947
1726
  throw new Error(
1948
1727
  "Watch requires a short-lived auth or app token for URL-based authentication."
@@ -1956,37 +1735,38 @@ function validateWatchQueryToken(token) {
1956
1735
  "Watch requires a token with a bounded lifetime of at most 3600 seconds."
1957
1736
  );
1958
1737
  }
1959
- if (!hasWatchOnlyTunnelGrants(parsed.data)) {
1738
+ if (!hasWatchOnlyTunnelResources(parsed.data)) {
1960
1739
  throw new Error(
1961
- "Watch requires a fine-grained token limited to tunnel list grants for URL-based authentication."
1740
+ "Watch requires a fine-grained token limited to tunnel list resources for URL-based authentication."
1962
1741
  );
1963
1742
  }
1964
1743
  }
1965
- function hasWatchOnlyTunnelGrants(token) {
1744
+ function hasWatchOnlyTunnelResources(token) {
1966
1745
  if (!hasWatchOnlyPermissions(token.permissions)) {
1967
1746
  return false;
1968
1747
  }
1969
- if (token.tunnelsGrants === void 0) {
1748
+ const resource = token.resources?.tunnels;
1749
+ if (resource === void 0) {
1970
1750
  return false;
1971
1751
  }
1972
- return hasWatchOnlyTunnelGrant(token.tunnelsGrants);
1752
+ return hasWatchOnlyTunnelResource(resource);
1973
1753
  }
1974
- function hasWatchOnlyTunnelGrant(grant) {
1975
- return watchGrantBranches(grant).every(
1754
+ function hasWatchOnlyTunnelResource(resource) {
1755
+ return watchResourceBranches(resource).every(
1976
1756
  (branch) => branch.hasList && !branch.hasMutationOrConnect
1977
1757
  );
1978
1758
  }
1979
- function watchGrantBranches(grant) {
1980
- if ("AND" in grant) {
1981
- return grant.AND.reduce(
1982
- (branches, child) => combineWatchGrantBranches(branches, child),
1759
+ function watchResourceBranches(resource) {
1760
+ if ("AND" in resource) {
1761
+ return resource.AND.reduce(
1762
+ (branches, child) => combineWatchResourceBranches(branches, child),
1983
1763
  [{ hasList: false, hasMutationOrConnect: false }]
1984
1764
  );
1985
1765
  }
1986
- if ("OR" in grant) {
1987
- return grant.OR.flatMap(watchGrantBranches);
1766
+ if ("OR" in resource) {
1767
+ return resource.OR.flatMap(watchResourceBranches);
1988
1768
  }
1989
- const tunnels = grant.scopes?.tunnels;
1769
+ const tunnels = resource.scopes?.tunnels;
1990
1770
  if (tunnels === void 0) {
1991
1771
  return [{ hasList: false, hasMutationOrConnect: false }];
1992
1772
  }
@@ -1997,9 +1777,9 @@ function watchGrantBranches(grant) {
1997
1777
  }
1998
1778
  ];
1999
1779
  }
2000
- function combineWatchGrantBranches(branches, child) {
1780
+ function combineWatchResourceBranches(branches, child) {
2001
1781
  return branches.flatMap(
2002
- (branch) => watchGrantBranches(child).map((childBranch) => ({
1782
+ (branch) => watchResourceBranches(child).map((childBranch) => ({
2003
1783
  hasList: branch.hasList || childBranch.hasList,
2004
1784
  hasMutationOrConnect: branch.hasMutationOrConnect || childBranch.hasMutationOrConnect
2005
1785
  }))
@@ -2010,7 +1790,7 @@ function hasWatchOnlyPermissions(permissions) {
2010
1790
  return true;
2011
1791
  }
2012
1792
  return permissions.every(
2013
- (permission) => permission === "tunnels.resources.read-only" || permission === "network.resources.read-only"
1793
+ (permission) => permission === "tunnels.resources.read-only"
2014
1794
  );
2015
1795
  }
2016
1796
  var Watch = class {
@@ -2095,7 +1875,7 @@ var Watch = class {
2095
1875
  };
2096
1876
 
2097
1877
  // src/webtty.ts
2098
- var z9 = __toESM(require("zod"));
1878
+ var z7 = __toESM(require("zod"));
2099
1879
  var osFamilies = [
2100
1880
  "linux",
2101
1881
  "macos",
@@ -2104,25 +1884,25 @@ var osFamilies = [
2104
1884
  "openbsd",
2105
1885
  "freebsd"
2106
1886
  ];
2107
- var webttyServerSchema = z9.object({
2108
- tunnel_id: z9.string(),
2109
- host: z9.string(),
2110
- token_auth: z9.boolean(),
2111
- os_family: z9.enum(osFamilies).optional(),
2112
- arch: z9.string().optional(),
2113
- os_id: z9.string().optional(),
1887
+ var webttyServerSchema = z7.object({
1888
+ tunnel_id: z7.string(),
1889
+ host: z7.string(),
1890
+ token_auth: z7.boolean(),
1891
+ os_family: z7.enum(osFamilies).optional(),
1892
+ arch: z7.string().optional(),
1893
+ os_id: z7.string().optional(),
2114
1894
  // /etc/os-release::ID (ubuntu, debian, rocky, etc.)
2115
- os_version_id: z9.string().optional(),
1895
+ os_version_id: z7.string().optional(),
2116
1896
  // /etc/os-release::VERSION_ID (24.04, 22.04, 11, 10.0.19045, ...)
2117
- os_version_codename: z9.string().optional(),
1897
+ os_version_codename: z7.string().optional(),
2118
1898
  // /etc/os-release::VERSION_CODENAME (jammy, noble...)
2119
- os_pretty_name: z9.string().optional(),
1899
+ os_pretty_name: z7.string().optional(),
2120
1900
  // /etc/os-release::PRETTY_NAME
2121
- kernel_release: z9.string().optional(),
1901
+ kernel_release: z7.string().optional(),
2122
1902
  // uname -r
2123
- hostname: z9.string().optional(),
1903
+ hostname: z7.string().optional(),
2124
1904
  // uname -n
2125
- labels: z9.record(z9.string(), z9.string().optional()).optional()
1905
+ labels: z7.record(z7.string(), z7.string().optional()).optional()
2126
1906
  });
2127
1907
  function parser(tunnel) {
2128
1908
  if (tunnel.status !== "online") return null;
@@ -2175,18 +1955,11 @@ function parseWebTTYServers(tunnels) {
2175
1955
  RstreamWebhookRessource,
2176
1956
  Tunnels,
2177
1957
  Watch,
2178
- authTokenPermissionsSchema,
2179
- authTokenSchema,
2180
- authTokenScopesSchema,
2181
- authTokenTunnelGrantSchema,
2182
- authTokenTunnelsScopesSchema,
2183
1958
  clientFilterSchema,
2184
1959
  clientSchema,
2185
1960
  createAPITURNCredentials,
2186
1961
  createAPPTURNCredentials,
2187
1962
  createAuthTokenFromClientCredentials,
2188
- createAuthTokenParamsSchema,
2189
- createAuthTokenResponseSchema,
2190
1963
  createPATTURNCredentials,
2191
1964
  createTURNCredentials,
2192
1965
  engineOpenApiDocument,
@@ -2207,9 +1980,7 @@ function parseWebTTYServers(tunnels) {
2207
1980
  streamEndpointSchema,
2208
1981
  streamSummarySchema,
2209
1982
  streamTLSInfoSchema,
2210
- tokenSchema,
2211
1983
  tunnelFilterSchema,
2212
- tunnelSchema,
2213
1984
  turnCredentialModeSchema,
2214
1985
  webhookEventsSchema,
2215
1986
  webttyServerSchema,