@rstreamlabs/tunnels 1.0.6 → 1.0.7

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
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  authTokenScopesSchema: () => authTokenScopesSchema,
49
49
  authTokenTunnelGrantSchema: () => authTokenTunnelGrantSchema,
50
50
  authTokenTunnelsScopesSchema: () => authTokenTunnelsScopesSchema,
51
+ clientFilterSchema: () => clientFilterSchema,
51
52
  clientSchema: () => clientSchema,
52
53
  createAPITURNCredentials: () => createAPITURNCredentials,
53
54
  createAPPTURNCredentials: () => createAPPTURNCredentials,
@@ -56,6 +57,8 @@ __export(index_exports, {
56
57
  createAuthTokenResponseSchema: () => createAuthTokenResponseSchema,
57
58
  createPATTURNCredentials: () => createPATTURNCredentials,
58
59
  createTURNCredentials: () => createTURNCredentials,
60
+ engineOpenApiDocument: () => engineOpenApiDocument,
61
+ engineOpenApiJson: () => engineOpenApiJson,
59
62
  eventSchema: () => eventSchema,
60
63
  formatTunnelHost: () => formatTunnelHost,
61
64
  listClientsParamsSchema: () => listClientsParamsSchema,
@@ -71,6 +74,7 @@ __export(index_exports, {
71
74
  streamSummarySchema: () => streamSummarySchema,
72
75
  streamTLSInfoSchema: () => streamTLSInfoSchema,
73
76
  tokenSchema: () => tokenSchema,
77
+ tunnelFilterSchema: () => tunnelFilterSchema,
74
78
  tunnelSchema: () => tunnelSchema,
75
79
  turnCredentialModeSchema: () => turnCredentialModeSchema,
76
80
  webhookEventsSchema: () => webhookEventsSchema,
@@ -165,16 +169,22 @@ var tunnelSchema = z2.object({
165
169
  rstream_auth: z2.boolean().optional(),
166
170
  challenge_mode: z2.boolean().optional()
167
171
  });
172
+ var tunnelFilterSchema = tunnelSchema.pick({
173
+ id: true,
174
+ name: true,
175
+ type: true,
176
+ status: true,
177
+ client_id: true,
178
+ user_id: true,
179
+ publish: true,
180
+ protocol: true,
181
+ hostname: true,
182
+ http_version: true,
183
+ labels: true
184
+ }).partial();
168
185
  var listTunnelsParamsSchema = z2.object({
169
- limit: z2.number().optional(),
170
- filters: tunnelSchema.pick({
171
- status: true,
172
- client_id: true,
173
- hostname: true,
174
- protocol: true,
175
- publish: true,
176
- labels: true
177
- }).partial().optional()
186
+ limit: z2.number().int().min(1).optional(),
187
+ filters: tunnelFilterSchema.optional()
178
188
  });
179
189
  var listTunnelsResponseSchema = z2.array(tunnelSchema);
180
190
  function formatTunnelHost(tunnel) {
@@ -371,11 +381,21 @@ var clientSchema = z4.object({
371
381
  protocol_version: z4.string().optional(),
372
382
  labels: z4.record(z4.string(), z4.string()).optional()
373
383
  });
384
+ var clientFilterSchema = clientSchema.pick({
385
+ id: true,
386
+ status: true,
387
+ user_id: true,
388
+ agent: true,
389
+ channel: true,
390
+ version: true,
391
+ os: true,
392
+ arch: true,
393
+ protocol_version: true,
394
+ labels: true
395
+ }).partial();
374
396
  var listClientsParamsSchema = z4.object({
375
- limit: z4.number().optional(),
376
- filters: clientSchema.pick({
377
- labels: true
378
- }).partial().optional()
397
+ limit: z4.number().int().min(1).optional(),
398
+ filters: clientFilterSchema.optional()
379
399
  });
380
400
  var listClientsResponseSchema = z4.array(clientSchema);
381
401
 
@@ -664,6 +684,358 @@ var webhookEventsSchema = z6.union([
664
684
  ]);
665
685
  var eventSchema = z6.union([wsEventsSchema, webhookEventsSchema]);
666
686
 
687
+ // src/openapi.ts
688
+ var z7 = __toESM(require("zod"));
689
+ var jsonContentType = "application/json";
690
+ var openApiContentType = "application/vnd.oai.openapi+json;version=3.1";
691
+ function isRecord(value) {
692
+ return typeof value === "object" && value !== null && !Array.isArray(value);
693
+ }
694
+ function dropSchemaKeyword(value) {
695
+ if (!isRecord(value)) return value;
696
+ return Object.fromEntries(
697
+ Object.entries(value).filter(([key]) => key !== "$schema")
698
+ );
699
+ }
700
+ function jsonSchemaFor(schema) {
701
+ return dropSchemaKeyword(
702
+ z7.toJSONSchema(schema, {
703
+ unrepresentable: "any",
704
+ override: (ctx) => {
705
+ if (ctx.zodSchema instanceof z7.ZodDate) {
706
+ ctx.jsonSchema.type = "string";
707
+ ctx.jsonSchema.format = "date-time";
708
+ }
709
+ }
710
+ })
711
+ );
712
+ }
713
+ function jsonArrayResponse(description, itemSchemaRef) {
714
+ return {
715
+ description,
716
+ content: {
717
+ [jsonContentType]: {
718
+ schema: {
719
+ type: "array",
720
+ items: {
721
+ $ref: itemSchemaRef
722
+ }
723
+ }
724
+ }
725
+ }
726
+ };
727
+ }
728
+ function streamResponse(description) {
729
+ return {
730
+ description,
731
+ content: {
732
+ "text/event-stream": {
733
+ schema: {
734
+ type: "string"
735
+ }
736
+ }
737
+ }
738
+ };
739
+ }
740
+ function errorResponse(description) {
741
+ return {
742
+ description
743
+ };
744
+ }
745
+ function queryJsonParameter(name, description, schemaRef, examples) {
746
+ return {
747
+ name,
748
+ in: "query",
749
+ required: false,
750
+ description,
751
+ content: {
752
+ [jsonContentType]: {
753
+ schema: {
754
+ $ref: schemaRef
755
+ },
756
+ ...examples ? { examples } : {}
757
+ }
758
+ }
759
+ };
760
+ }
761
+ var readEngineStateRule = {
762
+ resource: ["engine.tunnels", "engine.streams"],
763
+ action: "read"
764
+ };
765
+ var readEngineStateRules = [readEngineStateRule];
766
+ var readEngineStreamsRules = [
767
+ {
768
+ resource: "engine.streams",
769
+ action: "read"
770
+ }
771
+ ];
772
+ var watchParamsSchema = z7.object({
773
+ clients: clientFilterSchema.optional(),
774
+ tunnels: tunnelFilterSchema.optional()
775
+ });
776
+ var enginePermissions = {
777
+ "tunnels.resources.read-only": {
778
+ name: "Discovery: Read-Only",
779
+ description: "Read active clients, active tunnels, and live state events.",
780
+ rules: [readEngineStateRule]
781
+ },
782
+ "tunnels.tunnels.create-delete": {
783
+ name: "Tunnels: Create and Delete",
784
+ description: "Create and close tunnels through the CLI, SDK, or engine control channel.",
785
+ rules: [
786
+ {
787
+ resource: "engine.tunnels",
788
+ action: ["create", "delete"]
789
+ }
790
+ ]
791
+ },
792
+ "tunnels.streams.create-delete": {
793
+ name: "Connections: Create and Delete",
794
+ description: "Open and close private tunnel streams and WebTTY connections.",
795
+ rules: [
796
+ {
797
+ resource: "engine.streams",
798
+ action: ["create", "delete"]
799
+ }
800
+ ]
801
+ }
802
+ };
803
+ var engineOpenApiDocument = {
804
+ openapi: "3.1.0",
805
+ info: {
806
+ title: "rstream Engine API",
807
+ version: "1.0.0",
808
+ description: "Operational data-plane API exposed by rstream-engine. This surface is scoped to the authenticated engine or project endpoint and covers live clients, live tunnels, and state-change streams."
809
+ },
810
+ servers: [
811
+ {
812
+ url: "https://{engine}",
813
+ description: "Project-scoped rstream engine endpoint.",
814
+ variables: {
815
+ engine: {
816
+ default: "project-endpoint.cluster-host:443",
817
+ description: "Use the engine value returned by project discovery or configured in RSTREAM_ENGINE."
818
+ }
819
+ }
820
+ }
821
+ ],
822
+ security: [
823
+ {
824
+ bearerAuth: []
825
+ }
826
+ ],
827
+ components: {
828
+ securitySchemes: {
829
+ bearerAuth: {
830
+ type: "http",
831
+ scheme: "bearer",
832
+ bearerFormat: "rstream token",
833
+ description: "Preferred authentication mechanism. Send an OAuth-issued rstream access token or compatible rstream credential in Authorization: Bearer <token>."
834
+ },
835
+ queryToken: {
836
+ type: "apiKey",
837
+ in: "query",
838
+ name: "rstream.token",
839
+ description: "Fallback authentication mechanism for transports where setting Authorization is impractical. Prefer bearerAuth whenever possible."
840
+ }
841
+ },
842
+ parameters: {
843
+ ListClientsParams: queryJsonParameter(
844
+ "params",
845
+ "JSON-encoded ListClientsParams object.",
846
+ "#/components/schemas/ListClientsParams",
847
+ {
848
+ filterByAgent: {
849
+ value: {
850
+ limit: 10,
851
+ filters: {
852
+ agent: "rstream",
853
+ channel: "stable"
854
+ }
855
+ }
856
+ }
857
+ }
858
+ ),
859
+ ListTunnelsParams: queryJsonParameter(
860
+ "params",
861
+ "JSON-encoded ListTunnelsParams object.",
862
+ "#/components/schemas/ListTunnelsParams",
863
+ {
864
+ filterByLabels: {
865
+ value: {
866
+ filters: {
867
+ labels: {
868
+ service: "ssh",
869
+ env: "prod"
870
+ }
871
+ }
872
+ }
873
+ }
874
+ }
875
+ ),
876
+ WatchParams: queryJsonParameter(
877
+ "params",
878
+ "JSON-encoded WatchParams object. The same shape is accepted by SSE and WebSocket transports.",
879
+ "#/components/schemas/WatchParams",
880
+ {
881
+ watchTaggedTunnels: {
882
+ value: {
883
+ clients: {
884
+ agent: "rstream"
885
+ },
886
+ tunnels: {
887
+ labels: {
888
+ service: "ssh"
889
+ }
890
+ }
891
+ }
892
+ }
893
+ }
894
+ )
895
+ },
896
+ responses: {
897
+ BadRequest: errorResponse("Request validation failed."),
898
+ Unauthorized: errorResponse("Authentication is required."),
899
+ Forbidden: errorResponse("The token is not authorized.")
900
+ },
901
+ schemas: {
902
+ Client: jsonSchemaFor(clientSchema),
903
+ Event: jsonSchemaFor(wsEventsSchema),
904
+ ListClientsParams: jsonSchemaFor(listClientsParamsSchema),
905
+ ListTunnelsParams: jsonSchemaFor(listTunnelsParamsSchema),
906
+ TunnelListItem: jsonSchemaFor(tunnelSchema),
907
+ WatchParams: jsonSchemaFor(watchParamsSchema)
908
+ }
909
+ },
910
+ "x-rstream-agent-authentication": {
911
+ oauth_authorization_server_metadata: "https://rstream.io/.well-known/oauth-authorization-server",
912
+ oauth_protected_resource_metadata: "https://rstream.io/.well-known/oauth-protected-resource",
913
+ scope_selection: "Use x-rstream-required-rules to understand backend authorization checks. Choose OAuth scopes from x-rstream-permissions or use the task bundles in x-rstream-use-case-permissions."
914
+ },
915
+ "x-rstream-permissions": enginePermissions,
916
+ "x-rstream-use-case-permissions": {
917
+ "inspect-engine-state": ["tunnels.resources.read-only"],
918
+ "expose-service-from-cli": [
919
+ "tunnels.resources.read-only",
920
+ "tunnels.tunnels.create-delete"
921
+ ],
922
+ "connect-private-tunnel": [
923
+ "tunnels.resources.read-only",
924
+ "tunnels.streams.create-delete"
925
+ ],
926
+ "operate-webtty": [
927
+ "tunnels.resources.read-only",
928
+ "tunnels.tunnels.create-delete",
929
+ "tunnels.streams.create-delete"
930
+ ]
931
+ },
932
+ paths: {
933
+ "/api/openapi.json": {
934
+ get: {
935
+ tags: ["Discovery"],
936
+ summary: "Return this OpenAPI description.",
937
+ operationId: "get_engine_openapi",
938
+ security: [],
939
+ responses: {
940
+ "200": {
941
+ description: "OpenAPI document.",
942
+ content: {
943
+ [openApiContentType]: {
944
+ schema: {
945
+ type: "object"
946
+ }
947
+ }
948
+ }
949
+ }
950
+ }
951
+ }
952
+ },
953
+ "/api/clients": {
954
+ get: {
955
+ tags: ["Runtime inventory"],
956
+ summary: "List visible engine clients.",
957
+ operationId: "list_engine_clients",
958
+ parameters: [{ $ref: "#/components/parameters/ListClientsParams" }],
959
+ security: [{ bearerAuth: [] }, { queryToken: [] }],
960
+ responses: {
961
+ "200": jsonArrayResponse(
962
+ "Visible clients.",
963
+ "#/components/schemas/Client"
964
+ ),
965
+ "400": { $ref: "#/components/responses/BadRequest" },
966
+ "401": { $ref: "#/components/responses/Unauthorized" },
967
+ "403": { $ref: "#/components/responses/Forbidden" }
968
+ },
969
+ "x-rstream-required-rules": readEngineStreamsRules
970
+ }
971
+ },
972
+ "/api/tunnels": {
973
+ get: {
974
+ tags: ["Runtime inventory"],
975
+ summary: "List visible engine tunnels.",
976
+ operationId: "list_engine_tunnels",
977
+ parameters: [{ $ref: "#/components/parameters/ListTunnelsParams" }],
978
+ security: [{ bearerAuth: [] }, { queryToken: [] }],
979
+ responses: {
980
+ "200": jsonArrayResponse(
981
+ "Visible tunnels. Fine-grained list scopes may filter objects and project fields.",
982
+ "#/components/schemas/TunnelListItem"
983
+ ),
984
+ "400": { $ref: "#/components/responses/BadRequest" },
985
+ "401": { $ref: "#/components/responses/Unauthorized" },
986
+ "403": { $ref: "#/components/responses/Forbidden" }
987
+ },
988
+ "x-rstream-required-rules": readEngineStateRules,
989
+ "x-rstream-token-metadata-scope": "metadata.scopes.tunnels.list"
990
+ }
991
+ },
992
+ "/api/sse": {
993
+ get: {
994
+ tags: ["Runtime watch"],
995
+ summary: "Subscribe to visible engine state through Server-Sent Events.",
996
+ operationId: "watch_engine_events_sse",
997
+ parameters: [{ $ref: "#/components/parameters/WatchParams" }],
998
+ security: [{ bearerAuth: [] }, { queryToken: [] }],
999
+ responses: {
1000
+ "200": streamResponse(
1001
+ "SSE stream. Each event is emitted as a data line containing a JSON Event object."
1002
+ ),
1003
+ "400": { $ref: "#/components/responses/BadRequest" },
1004
+ "401": { $ref: "#/components/responses/Unauthorized" },
1005
+ "403": { $ref: "#/components/responses/Forbidden" }
1006
+ },
1007
+ "x-rstream-event-schema": "#/components/schemas/Event",
1008
+ "x-rstream-required-rules": readEngineStateRules
1009
+ }
1010
+ },
1011
+ "/api/websocket": {
1012
+ get: {
1013
+ tags: ["Runtime watch"],
1014
+ summary: "Subscribe to visible engine state through a WebSocket upgrade.",
1015
+ operationId: "watch_engine_events_websocket",
1016
+ parameters: [{ $ref: "#/components/parameters/WatchParams" }],
1017
+ security: [{ bearerAuth: [] }, { queryToken: [] }],
1018
+ responses: {
1019
+ "101": {
1020
+ description: "WebSocket connection accepted. Frames contain JSON Event objects."
1021
+ },
1022
+ "400": { $ref: "#/components/responses/BadRequest" },
1023
+ "401": { $ref: "#/components/responses/Unauthorized" },
1024
+ "403": { $ref: "#/components/responses/Forbidden" }
1025
+ },
1026
+ "x-rstream-event-schema": "#/components/schemas/Event",
1027
+ "x-rstream-required-rules": readEngineStateRules
1028
+ }
1029
+ }
1030
+ }
1031
+ };
1032
+ var engineOpenApiJson = `${JSON.stringify(
1033
+ engineOpenApiDocument,
1034
+ null,
1035
+ 2
1036
+ )}
1037
+ `;
1038
+
667
1039
  // src/resolution.ts
668
1040
  var import_rstream3 = require("@rstreamlabs/rstream");
669
1041
  var import_rstream4 = require("@rstreamlabs/rstream");
@@ -789,16 +1161,16 @@ var import_rstream8 = require("@rstreamlabs/rstream");
789
1161
  var import_rstream9 = require("@rstreamlabs/rstream");
790
1162
  var import_rstream10 = require("@rstreamlabs/rstream");
791
1163
  var import_rstream11 = require("@rstreamlabs/rstream");
792
- var z7 = __toESM(require("zod"));
1164
+ var z8 = __toESM(require("zod"));
793
1165
  var import_crypto = __toESM(require("crypto"));
794
1166
  var defaultTURNPort = 3478;
795
1167
  var defaultTURNSPort = 5349;
796
1168
  var defaultTURNCredentialTTLSeconds = 24 * 60 * 60;
797
- var turnTokenClaimsSchema = z7.object({
798
- token_endpoint: z7.string().optional(),
799
- type: z7.string()
1169
+ var turnTokenClaimsSchema = z8.object({
1170
+ token_endpoint: z8.string().optional(),
1171
+ type: z8.string()
800
1172
  });
801
- var turnCredentialModeSchema = z7.enum(["api", "app", "pat"]);
1173
+ var turnCredentialModeSchema = z8.enum(["api", "app", "pat"]);
802
1174
  function normalizeOptionalString(value) {
803
1175
  const normalized = value?.trim();
804
1176
  return normalized ? normalized : void 0;
@@ -1324,7 +1696,7 @@ var Watch = class {
1324
1696
  };
1325
1697
 
1326
1698
  // src/webtty.ts
1327
- var z8 = __toESM(require("zod"));
1699
+ var z9 = __toESM(require("zod"));
1328
1700
  var osFamilies = [
1329
1701
  "linux",
1330
1702
  "macos",
@@ -1333,25 +1705,25 @@ var osFamilies = [
1333
1705
  "openbsd",
1334
1706
  "freebsd"
1335
1707
  ];
1336
- var webttyServerSchema = z8.object({
1337
- tunnel_id: z8.string(),
1338
- host: z8.string(),
1339
- token_auth: z8.boolean(),
1340
- os_family: z8.enum(osFamilies).optional(),
1341
- arch: z8.string().optional(),
1342
- os_id: z8.string().optional(),
1708
+ var webttyServerSchema = z9.object({
1709
+ tunnel_id: z9.string(),
1710
+ host: z9.string(),
1711
+ token_auth: z9.boolean(),
1712
+ os_family: z9.enum(osFamilies).optional(),
1713
+ arch: z9.string().optional(),
1714
+ os_id: z9.string().optional(),
1343
1715
  // /etc/os-release::ID (ubuntu, debian, rocky, etc.)
1344
- os_version_id: z8.string().optional(),
1716
+ os_version_id: z9.string().optional(),
1345
1717
  // /etc/os-release::VERSION_ID (24.04, 22.04, 11, 10.0.19045, ...)
1346
- os_version_codename: z8.string().optional(),
1718
+ os_version_codename: z9.string().optional(),
1347
1719
  // /etc/os-release::VERSION_CODENAME (jammy, noble...)
1348
- os_pretty_name: z8.string().optional(),
1720
+ os_pretty_name: z9.string().optional(),
1349
1721
  // /etc/os-release::PRETTY_NAME
1350
- kernel_release: z8.string().optional(),
1722
+ kernel_release: z9.string().optional(),
1351
1723
  // uname -r
1352
- hostname: z8.string().optional(),
1724
+ hostname: z9.string().optional(),
1353
1725
  // uname -n
1354
- labels: z8.record(z8.string(), z8.string().optional()).optional()
1726
+ labels: z9.record(z9.string(), z9.string().optional()).optional()
1355
1727
  });
1356
1728
  function parser(tunnel) {
1357
1729
  if (tunnel.status !== "online") return null;
@@ -1409,6 +1781,7 @@ function parseWebTTYServers(tunnels) {
1409
1781
  authTokenScopesSchema,
1410
1782
  authTokenTunnelGrantSchema,
1411
1783
  authTokenTunnelsScopesSchema,
1784
+ clientFilterSchema,
1412
1785
  clientSchema,
1413
1786
  createAPITURNCredentials,
1414
1787
  createAPPTURNCredentials,
@@ -1417,6 +1790,8 @@ function parseWebTTYServers(tunnels) {
1417
1790
  createAuthTokenResponseSchema,
1418
1791
  createPATTURNCredentials,
1419
1792
  createTURNCredentials,
1793
+ engineOpenApiDocument,
1794
+ engineOpenApiJson,
1420
1795
  eventSchema,
1421
1796
  formatTunnelHost,
1422
1797
  listClientsParamsSchema,
@@ -1432,6 +1807,7 @@ function parseWebTTYServers(tunnels) {
1432
1807
  streamSummarySchema,
1433
1808
  streamTLSInfoSchema,
1434
1809
  tokenSchema,
1810
+ tunnelFilterSchema,
1435
1811
  tunnelSchema,
1436
1812
  turnCredentialModeSchema,
1437
1813
  webhookEventsSchema,