@hyperbrowser/sdk 0.89.2 → 0.89.3

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.
@@ -23,6 +23,6 @@ export declare class RuntimeTransport {
23
23
  private fetchForConnection;
24
24
  private assertResponse;
25
25
  private buildHeaders;
26
- private normalizeBaseUrl;
26
+ private buildRequestPath;
27
27
  }
28
28
  export {};
@@ -149,15 +149,7 @@ class RuntimeTransport {
149
149
  return this.assertResponse(response);
150
150
  }
151
151
  async fetchForConnection(connection, path, init, params) {
152
- const url = new URL(path, this.normalizeBaseUrl(connection.baseUrl));
153
- if (params) {
154
- for (const [key, value] of Object.entries(params)) {
155
- if (value !== undefined) {
156
- url.searchParams.append(key, String(value));
157
- }
158
- }
159
- }
160
- const target = (0, ws_1.resolveRuntimeTransportTarget)(connection.baseUrl, `${url.pathname}${url.search}`, this.runtimeProxyOverride);
152
+ const target = (0, ws_1.resolveRuntimeTransportTarget)(connection.baseUrl, this.buildRequestPath(path, params), this.runtimeProxyOverride);
161
153
  const headers = this.buildHeaders(connection, init?.headers, target.hostHeader);
162
154
  const controller = new AbortController();
163
155
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
@@ -235,8 +227,19 @@ class RuntimeTransport {
235
227
  }
236
228
  return headers;
237
229
  }
238
- normalizeBaseUrl(baseUrl) {
239
- return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
230
+ buildRequestPath(path, params) {
231
+ const trimmed = path.trim();
232
+ const [rawPath, rawQuery = ""] = trimmed.split("?", 2);
233
+ const queryParams = new URLSearchParams(rawQuery);
234
+ if (params) {
235
+ for (const [key, value] of Object.entries(params)) {
236
+ if (value !== undefined) {
237
+ queryParams.append(key, String(value));
238
+ }
239
+ }
240
+ }
241
+ const query = queryParams.toString();
242
+ return query ? `${rawPath}?${query}` : rawPath;
240
243
  }
241
244
  }
242
245
  exports.RuntimeTransport = RuntimeTransport;
@@ -0,0 +1,2 @@
1
+ export declare const runtimeSessionIdFromPath: (rawPath: string) => string | null;
2
+ export declare const runtimeBaseUrlSessionId: (runtimeBaseUrl: string) => string | null;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runtimeBaseUrlSessionId = exports.runtimeSessionIdFromPath = void 0;
4
+ const runtimeSessionIdFromPath = (rawPath) => {
5
+ const segments = rawPath
6
+ .trim()
7
+ .replace(/^\/+|\/+$/g, "")
8
+ .split("/")
9
+ .filter(Boolean);
10
+ if (segments.length < 2 || segments[0] !== "sandbox" || !segments[1]?.trim()) {
11
+ return null;
12
+ }
13
+ return segments[1].trim();
14
+ };
15
+ exports.runtimeSessionIdFromPath = runtimeSessionIdFromPath;
16
+ const runtimeBaseUrlSessionId = (runtimeBaseUrl) => {
17
+ return (0, exports.runtimeSessionIdFromPath)(new URL(runtimeBaseUrl).pathname);
18
+ };
19
+ exports.runtimeBaseUrlSessionId = runtimeBaseUrlSessionId;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.openRuntimeWebSocket = exports.toWebSocketUrl = exports.resolveRuntimeTransportTarget = exports.AsyncEventQueue = void 0;
7
7
  const ws_1 = __importDefault(require("ws"));
8
8
  const client_1 = require("../client");
9
+ const runtime_path_1 = require("./runtime-path");
9
10
  class AsyncEventQueue {
10
11
  constructor() {
11
12
  this.values = [];
@@ -75,8 +76,42 @@ const RETRYABLE_NETWORK_CODES = new Set([
75
76
  "ESOCKETTIMEDOUT",
76
77
  ]);
77
78
  const hasScheme = (value) => /^[a-z][a-z0-9+.-]*:\/\//i.test(value);
79
+ const shouldPrependSandboxToRuntimeAPI = (runtimeBaseUrl) => {
80
+ return (0, runtime_path_1.runtimeBaseUrlSessionId)(runtimeBaseUrl) === null;
81
+ };
82
+ const normalizeRuntimeAPIPath = (pathname, prependSandbox) => {
83
+ const trimmed = pathname.trim();
84
+ if (!trimmed) {
85
+ return prependSandbox ? "/sandbox" : "/";
86
+ }
87
+ const absolute = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
88
+ if (prependSandbox) {
89
+ if (absolute === "/sandbox" || absolute.startsWith("/sandbox/")) {
90
+ return absolute;
91
+ }
92
+ return `/sandbox${absolute}`;
93
+ }
94
+ if (absolute === "/sandbox") {
95
+ return "/";
96
+ }
97
+ if (absolute.startsWith("/sandbox/")) {
98
+ return `/${absolute.slice("/sandbox/".length)}`;
99
+ }
100
+ return absolute;
101
+ };
102
+ const normalizeRuntimeRelativePath = (baseUrl, path) => {
103
+ const trimmed = path.trim();
104
+ if (!trimmed) {
105
+ return "";
106
+ }
107
+ const parsedPath = new URL(trimmed, "http://runtime.local");
108
+ const prependSandbox = shouldPrependSandboxToRuntimeAPI(baseUrl);
109
+ const normalizedPath = normalizeRuntimeAPIPath(parsedPath.pathname, prependSandbox);
110
+ const relativePath = normalizedPath.replace(/^\/+/, "");
111
+ return `${relativePath}${parsedPath.search}${parsedPath.hash}`;
112
+ };
78
113
  const resolveRuntimeTransportTarget = (baseUrl, path, runtimeProxyOverride) => {
79
- const url = new URL(path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
114
+ const url = new URL(normalizeRuntimeRelativePath(baseUrl, path), baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
80
115
  if (!runtimeProxyOverride) {
81
116
  return {
82
117
  url: url.toString(),
@@ -4,6 +4,7 @@ exports.SandboxesService = exports.SandboxHandle = void 0;
4
4
  const client_1 = require("../client");
5
5
  const files_1 = require("../sandbox/files");
6
6
  const base_1 = require("../sandbox/base");
7
+ const runtime_path_1 = require("../sandbox/runtime-path");
7
8
  const process_1 = require("../sandbox/process");
8
9
  const terminal_1 = require("../sandbox/terminal");
9
10
  const base_2 = require("./base");
@@ -71,11 +72,35 @@ const serializeCreateSandboxParams = (params) => {
71
72
  timeoutMinutes: snapshotParams.timeoutMinutes,
72
73
  };
73
74
  };
75
+ const resolveSandboxRuntimeSessionHost = (runtime, baseUrl) => {
76
+ const sessionIdFromBasePath = (0, runtime_path_1.runtimeSessionIdFromPath)(baseUrl.pathname);
77
+ if (sessionIdFromBasePath && baseUrl.hostname) {
78
+ return `${sessionIdFromBasePath}.${baseUrl.hostname}`;
79
+ }
80
+ const runtimeHost = runtime.host?.trim() || "";
81
+ if (runtimeHost) {
82
+ try {
83
+ const parsedHost = new URL(runtimeHost);
84
+ const sessionIdFromHostPath = (0, runtime_path_1.runtimeSessionIdFromPath)(parsedHost.pathname);
85
+ if (sessionIdFromHostPath && parsedHost.hostname) {
86
+ return `${sessionIdFromHostPath}.${parsedHost.hostname}`;
87
+ }
88
+ if (parsedHost.hostname) {
89
+ return parsedHost.hostname;
90
+ }
91
+ }
92
+ catch {
93
+ return runtimeHost;
94
+ }
95
+ }
96
+ return baseUrl.hostname;
97
+ };
74
98
  const buildSandboxExposedUrl = (runtime, port) => {
75
99
  const baseUrl = new URL(runtime.baseUrl);
100
+ const sessionHost = resolveSandboxRuntimeSessionHost(runtime, baseUrl);
76
101
  const authority = baseUrl.port
77
- ? `${port}-${runtime.host}:${baseUrl.port}`
78
- : `${port}-${runtime.host}`;
102
+ ? `${port}-${sessionHost}:${baseUrl.port}`
103
+ : `${port}-${sessionHost}`;
79
104
  return new URL("/", `${baseUrl.protocol}//${authority}`).toString();
80
105
  };
81
106
  const upsertExposedPort = (exposedPorts, updated) => [...exposedPorts.filter((entry) => entry.port !== updated.port), updated].sort((left, right) => left.port - right.port);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperbrowser/sdk",
3
- "version": "0.89.2",
3
+ "version": "0.89.3",
4
4
  "description": "Node SDK for Hyperbrowser API",
5
5
  "author": "",
6
6
  "repository": {