@typedb/driver-http 3.12.1 → 3.12.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.
package/dist/index.cjs CHANGED
@@ -9,35 +9,37 @@ function remoteOrigin(params) {
9
9
  if (isBasicParams(params)) return `${params.addresses[0]}`;
10
10
  else return `${params.translatedAddresses[0].external}`;
11
11
  }
12
+ var SCHEME_PREFIX_REGEX = /^[a-z][a-z0-9+.-]*:\/\//i;
12
13
  function hostPortFromOrigin(origin) {
14
+ if (!SCHEME_PREFIX_REGEX.test(origin)) return origin;
13
15
  try {
14
- const url = new URL(origin);
15
- return url.host;
16
+ return new URL(origin).host;
16
17
  } catch (e) {
17
18
  return origin;
18
19
  }
19
20
  }
20
21
  function resolveOrigin(params, primaryAddress) {
22
+ const target = hostPortFromOrigin(primaryAddress);
21
23
  if (isBasicParams(params)) {
22
24
  for (const addr of params.addresses) {
23
- if (hostPortFromOrigin(addr) === primaryAddress) return addr;
25
+ if (hostPortFromOrigin(addr) === target) return addr;
24
26
  }
25
- return deriveOriginWithScheme(params.addresses[0], primaryAddress);
27
+ return originWithScheme(primaryAddress, params.addresses[0]);
26
28
  } else {
27
29
  for (const ta of params.translatedAddresses) {
28
- if (hostPortFromOrigin(ta.internal) === primaryAddress || hostPortFromOrigin(ta.external) === primaryAddress) {
30
+ if (hostPortFromOrigin(ta.internal) === target || hostPortFromOrigin(ta.external) === target) {
29
31
  return ta.external;
30
32
  }
31
33
  }
32
- return deriveOriginWithScheme(params.translatedAddresses[0].external, primaryAddress);
34
+ return originWithScheme(primaryAddress, params.translatedAddresses[0].external);
33
35
  }
34
36
  }
35
- function deriveOriginWithScheme(referenceUrl, hostPort) {
37
+ function originWithScheme(address, referenceOrigin) {
38
+ if (SCHEME_PREFIX_REGEX.test(address)) return address;
36
39
  try {
37
- const url = new URL(referenceUrl);
38
- return `${url.protocol}//${hostPort}`;
40
+ return `${new URL(referenceOrigin).protocol}//${address}`;
39
41
  } catch (e2) {
40
- return `https://${hostPort}`;
42
+ return `https://${address}`;
41
43
  }
42
44
  }
43
45
  function allOrigins(params) {
@@ -73,7 +75,9 @@ function getVariableName(structure, variable) {
73
75
  // ../../../../../../../../../execroot/_main/bazel-out/k8-opt/bin/http-ts/src/index.ts
74
76
  var HTTP_UNAUTHORIZED = 401;
75
77
  var HTTP_MISDIRECTED = 421;
76
- var TRANSIENT_SIGNIN_ERROR_CODES = /* @__PURE__ */ new Set(["HDR2", "SRV14"]);
78
+ var TRANSIENT_SIGNIN_ERROR_CODES = /* @__PURE__ */ new Set(["HDR2", "SRV14", "CSV8", "CSV9"]);
79
+ var PRIMARY_FAILOVER_RETRIES = 3;
80
+ var PRIMARY_SELECTION_WAIT_MS = 2e3;
77
81
  function isApiErrResp(value) {
78
82
  return value !== null && "err" in value;
79
83
  }
@@ -188,6 +192,15 @@ var TypeDBHttpDriver = class {
188
192
  }
189
193
  }
190
194
  async apiReq(method, path, body, options) {
195
+ let result = await this.apiReqOnce(method, path, body, options);
196
+ for (let retry = 0; retry < PRIMARY_FAILOVER_RETRIES && result.status === HTTP_MISDIRECTED; retry++) {
197
+ await new Promise((resolve) => setTimeout(resolve, PRIMARY_SELECTION_WAIT_MS));
198
+ result = await this.apiReqOnce(method, path, body, options);
199
+ }
200
+ return result;
201
+ }
202
+ async apiReqOnce(method, path, body, options) {
203
+ const triedOrigins = /* @__PURE__ */ new Set([this.currentOrigin]);
191
204
  const initial = await this.tryApiReq(method, path, body, options);
192
205
  if (isApiErrResp(initial)) return initial;
193
206
  let result = initial;
@@ -198,7 +211,8 @@ var TypeDBHttpDriver = class {
198
211
  }
199
212
  if (result === null || !result.ok) {
200
213
  const startOrigin = this.currentOrigin;
201
- const fallback = await this.tryFallbackOrigins(method, path, body, options);
214
+ triedOrigins.add(startOrigin);
215
+ const fallback = await this.tryFallbackOrigins(method, path, body, options, triedOrigins);
202
216
  if (isApiErrResp(fallback)) return fallback;
203
217
  if (fallback !== null && (result === null || fallback.ok)) {
204
218
  result = fallback;
@@ -251,12 +265,11 @@ var TypeDBHttpDriver = class {
251
265
  this.switchOrigin(newOrigin);
252
266
  return true;
253
267
  }
254
- async tryFallbackOrigins(method, path, body, options) {
268
+ async tryFallbackOrigins(method, path, body, options, triedOrigins) {
255
269
  const origins = allOrigins(this.params);
256
- const failedOrigin = this.currentOrigin;
257
270
  let lastError = null;
258
271
  for (const origin of origins) {
259
- if (origin === failedOrigin) continue;
272
+ if (triedOrigins.has(origin)) continue;
260
273
  this.switchOrigin(origin);
261
274
  const initial = await this.tryApiReq(method, path, body, options);
262
275
  if (initial === null) continue;
@@ -299,19 +312,19 @@ var TypeDBHttpDriver = class {
299
312
  return driverError("HDR2", `Cannot connect to server at ${this.currentOrigin}`);
300
313
  }
301
314
  const json = await this.jsonOrNull(resp);
302
- if (resp.ok) {
315
+ if (resp.ok && typeof _optionalChain([json, 'optionalAccess', _5 => _5.token]) === "string") {
303
316
  this.token = json.token;
304
317
  return { ok: json };
305
318
  }
306
319
  if (isApiError(json)) return { err: json, status: resp.status };
307
- throw resp;
320
+ return driverError("HDR2", `Unexpected signin response from ${this.currentOrigin} (HTTP ${resp.status})`);
308
321
  }
309
322
  async jsonOrNull(resp) {
310
- const contentLengthRaw = resp.headers.get("Content-Length");
311
- if (!contentLengthRaw) return null;
312
- const contentLength = parseInt(contentLengthRaw || "");
313
- if (isNaN(contentLength)) throw `Received invalid Content-Length header: ${contentLengthRaw}`;
314
- return contentLength > 0 ? await resp.json() : null;
323
+ try {
324
+ return await resp.json();
325
+ } catch (e7) {
326
+ return null;
327
+ }
315
328
  }
316
329
  async stringOrNull(resp) {
317
330
  const contentLengthRaw = resp.headers.get("Content-Length");
package/dist/index.d.ts CHANGED
@@ -16,9 +16,7 @@ type DriverParams = DriverParamsBasic | DriverParamsTranslated;
16
16
  declare function isBasicParams(params: DriverParams): params is DriverParamsBasic;
17
17
  declare function isTranslatedParams(params: DriverParams): params is DriverParamsTranslated;
18
18
  declare function remoteOrigin(params: DriverParams): string;
19
- /** Extract host:port from a URL string. "https://127.0.0.1:18000" → "127.0.0.1:18000" */
20
19
  declare function hostPortFromOrigin(origin: string): string;
21
- /** Resolve a bare primaryAddress (host:port) to a full URL using configured params. */
22
20
  declare function resolveOrigin(params: DriverParams, primaryAddress: string): string;
23
21
  /** Return all configured origins for connection error fallback. */
24
22
  declare function allOrigins(params: DriverParams): string[];
@@ -498,6 +496,7 @@ declare class TypeDBHttpDriver {
498
496
  private jsonApiReq;
499
497
  private stringApiReq;
500
498
  private apiReq;
499
+ private apiReqOnce;
501
500
  private tryApiReq;
502
501
  private followMisdirected;
503
502
  private switchToRedirectTarget;
package/dist/index.mjs CHANGED
@@ -9,35 +9,37 @@ function remoteOrigin(params) {
9
9
  if (isBasicParams(params)) return `${params.addresses[0]}`;
10
10
  else return `${params.translatedAddresses[0].external}`;
11
11
  }
12
+ var SCHEME_PREFIX_REGEX = /^[a-z][a-z0-9+.-]*:\/\//i;
12
13
  function hostPortFromOrigin(origin) {
14
+ if (!SCHEME_PREFIX_REGEX.test(origin)) return origin;
13
15
  try {
14
- const url = new URL(origin);
15
- return url.host;
16
+ return new URL(origin).host;
16
17
  } catch {
17
18
  return origin;
18
19
  }
19
20
  }
20
21
  function resolveOrigin(params, primaryAddress) {
22
+ const target = hostPortFromOrigin(primaryAddress);
21
23
  if (isBasicParams(params)) {
22
24
  for (const addr of params.addresses) {
23
- if (hostPortFromOrigin(addr) === primaryAddress) return addr;
25
+ if (hostPortFromOrigin(addr) === target) return addr;
24
26
  }
25
- return deriveOriginWithScheme(params.addresses[0], primaryAddress);
27
+ return originWithScheme(primaryAddress, params.addresses[0]);
26
28
  } else {
27
29
  for (const ta of params.translatedAddresses) {
28
- if (hostPortFromOrigin(ta.internal) === primaryAddress || hostPortFromOrigin(ta.external) === primaryAddress) {
30
+ if (hostPortFromOrigin(ta.internal) === target || hostPortFromOrigin(ta.external) === target) {
29
31
  return ta.external;
30
32
  }
31
33
  }
32
- return deriveOriginWithScheme(params.translatedAddresses[0].external, primaryAddress);
34
+ return originWithScheme(primaryAddress, params.translatedAddresses[0].external);
33
35
  }
34
36
  }
35
- function deriveOriginWithScheme(referenceUrl, hostPort) {
37
+ function originWithScheme(address, referenceOrigin) {
38
+ if (SCHEME_PREFIX_REGEX.test(address)) return address;
36
39
  try {
37
- const url = new URL(referenceUrl);
38
- return `${url.protocol}//${hostPort}`;
40
+ return `${new URL(referenceOrigin).protocol}//${address}`;
39
41
  } catch {
40
- return `https://${hostPort}`;
42
+ return `https://${address}`;
41
43
  }
42
44
  }
43
45
  function allOrigins(params) {
@@ -73,7 +75,9 @@ function getVariableName(structure, variable) {
73
75
  // ../../../../../../../../../execroot/_main/bazel-out/k8-opt/bin/http-ts/src/index.ts
74
76
  var HTTP_UNAUTHORIZED = 401;
75
77
  var HTTP_MISDIRECTED = 421;
76
- var TRANSIENT_SIGNIN_ERROR_CODES = /* @__PURE__ */ new Set(["HDR2", "SRV14"]);
78
+ var TRANSIENT_SIGNIN_ERROR_CODES = /* @__PURE__ */ new Set(["HDR2", "SRV14", "CSV8", "CSV9"]);
79
+ var PRIMARY_FAILOVER_RETRIES = 3;
80
+ var PRIMARY_SELECTION_WAIT_MS = 2e3;
77
81
  function isApiErrResp(value) {
78
82
  return value !== null && "err" in value;
79
83
  }
@@ -188,6 +192,15 @@ var TypeDBHttpDriver = class {
188
192
  }
189
193
  }
190
194
  async apiReq(method, path, body, options) {
195
+ let result = await this.apiReqOnce(method, path, body, options);
196
+ for (let retry = 0; retry < PRIMARY_FAILOVER_RETRIES && result.status === HTTP_MISDIRECTED; retry++) {
197
+ await new Promise((resolve) => setTimeout(resolve, PRIMARY_SELECTION_WAIT_MS));
198
+ result = await this.apiReqOnce(method, path, body, options);
199
+ }
200
+ return result;
201
+ }
202
+ async apiReqOnce(method, path, body, options) {
203
+ const triedOrigins = /* @__PURE__ */ new Set([this.currentOrigin]);
191
204
  const initial = await this.tryApiReq(method, path, body, options);
192
205
  if (isApiErrResp(initial)) return initial;
193
206
  let result = initial;
@@ -198,7 +211,8 @@ var TypeDBHttpDriver = class {
198
211
  }
199
212
  if (result === null || !result.ok) {
200
213
  const startOrigin = this.currentOrigin;
201
- const fallback = await this.tryFallbackOrigins(method, path, body, options);
214
+ triedOrigins.add(startOrigin);
215
+ const fallback = await this.tryFallbackOrigins(method, path, body, options, triedOrigins);
202
216
  if (isApiErrResp(fallback)) return fallback;
203
217
  if (fallback !== null && (result === null || fallback.ok)) {
204
218
  result = fallback;
@@ -251,12 +265,11 @@ var TypeDBHttpDriver = class {
251
265
  this.switchOrigin(newOrigin);
252
266
  return true;
253
267
  }
254
- async tryFallbackOrigins(method, path, body, options) {
268
+ async tryFallbackOrigins(method, path, body, options, triedOrigins) {
255
269
  const origins = allOrigins(this.params);
256
- const failedOrigin = this.currentOrigin;
257
270
  let lastError = null;
258
271
  for (const origin of origins) {
259
- if (origin === failedOrigin) continue;
272
+ if (triedOrigins.has(origin)) continue;
260
273
  this.switchOrigin(origin);
261
274
  const initial = await this.tryApiReq(method, path, body, options);
262
275
  if (initial === null) continue;
@@ -299,19 +312,19 @@ var TypeDBHttpDriver = class {
299
312
  return driverError("HDR2", `Cannot connect to server at ${this.currentOrigin}`);
300
313
  }
301
314
  const json = await this.jsonOrNull(resp);
302
- if (resp.ok) {
315
+ if (resp.ok && typeof json?.token === "string") {
303
316
  this.token = json.token;
304
317
  return { ok: json };
305
318
  }
306
319
  if (isApiError(json)) return { err: json, status: resp.status };
307
- throw resp;
320
+ return driverError("HDR2", `Unexpected signin response from ${this.currentOrigin} (HTTP ${resp.status})`);
308
321
  }
309
322
  async jsonOrNull(resp) {
310
- const contentLengthRaw = resp.headers.get("Content-Length");
311
- if (!contentLengthRaw) return null;
312
- const contentLength = parseInt(contentLengthRaw || "");
313
- if (isNaN(contentLength)) throw `Received invalid Content-Length header: ${contentLengthRaw}`;
314
- return contentLength > 0 ? await resp.json() : null;
323
+ try {
324
+ return await resp.json();
325
+ } catch {
326
+ return null;
327
+ }
315
328
  }
316
329
  async stringOrNull(resp) {
317
330
  const contentLengthRaw = resp.headers.get("Content-Length");
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name": "@typedb/driver-http", "version": "3.12.1", "description": "TypeDB HTTP Driver", "author": "TypeDB Community <community@typedb.com>", "license": "Apache-2.0", "homepage": "https://typedb.com", "repository": {"type": "git", "url": "https://github.com/typedb/typedb-driver"}, "bugs": {"url": "https://github.com/typedb/typedb-driver/issues"}, "keywords": ["database", "typedb"], "main": "dist/index.cjs", "module": "dist/index.mjs", "types": "dist/index.d.ts", "type": "module", "exports": {".": {"types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs"}}, "scripts": {"build:dev": "tsc", "build": "tsup", "test": "cucumber-js", "docs": "typedoc"}, "packageManager": "pnpm@8.15.9", "packageConfig": {"access": "public"}, "devDependencies": {"@cucumber/cucumber": "9.0.0", "@types/node": "24.0.12", "tsup": "8.5.0", "typedoc": "^0.28.7", "typescript": "5.8.3"}}
1
+ {"name": "@typedb/driver-http", "version": "3.12.3", "description": "TypeDB HTTP Driver", "author": "TypeDB Community <community@typedb.com>", "license": "Apache-2.0", "homepage": "https://typedb.com", "repository": {"type": "git", "url": "https://github.com/typedb/typedb-driver"}, "bugs": {"url": "https://github.com/typedb/typedb-driver/issues"}, "keywords": ["database", "typedb"], "main": "dist/index.cjs", "module": "dist/index.mjs", "types": "dist/index.d.ts", "type": "module", "exports": {".": {"types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs"}}, "scripts": {"build:dev": "tsc", "build": "tsup", "test": "cucumber-js", "docs": "typedoc"}, "packageManager": "pnpm@8.15.9", "packageConfig": {"access": "public"}, "devDependencies": {"@cucumber/cucumber": "9.0.0", "@types/node": "24.0.12", "tsup": "8.5.0", "typedoc": "^0.28.7", "typescript": "5.8.3"}}