phenoml 6.2.0 → 6.3.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.
@@ -52,7 +52,7 @@ class phenomlClient {
52
52
  this._options = Object.assign(Object.assign({}, _options), { logging: core.logging.createLogger(_options === null || _options === void 0 ? void 0 : _options.logging), headers: (0, headers_js_1.mergeHeaders)({
53
53
  "X-Fern-Language": "JavaScript",
54
54
  "X-Fern-SDK-Name": "phenoml",
55
- "X-Fern-SDK-Version": "6.2.0",
55
+ "X-Fern-SDK-Version": "6.3.0",
56
56
  "User-Agent": "phenoml/auto",
57
57
  "X-Fern-Runtime": core.RUNTIME.type,
58
58
  "X-Fern-Runtime-Version": core.RUNTIME.version,
@@ -24,14 +24,21 @@ const RawResponse_js_1 = require("./RawResponse.js");
24
24
  const requestWithRetries_js_1 = require("./requestWithRetries.js");
25
25
  const SENSITIVE_HEADERS = new Set([
26
26
  "authorization",
27
+ "www-authenticate",
27
28
  "x-api-key",
28
29
  "api-key",
30
+ "apikey",
31
+ "x-api-token",
29
32
  "x-auth-token",
33
+ "auth-token",
30
34
  "cookie",
31
35
  "set-cookie",
32
36
  "proxy-authorization",
37
+ "proxy-authenticate",
33
38
  "x-csrf-token",
34
39
  "x-xsrf-token",
40
+ "x-session-token",
41
+ "x-access-token",
35
42
  ]);
36
43
  function redactHeaders(headers) {
37
44
  const filtered = {};
@@ -85,20 +92,26 @@ function redactUrl(url) {
85
92
  if (protocolIndex === -1)
86
93
  return url;
87
94
  const afterProtocol = protocolIndex + 3;
88
- const atIndex = url.indexOf("@", afterProtocol);
89
- if (atIndex !== -1) {
90
- const pathStart = url.indexOf("/", afterProtocol);
91
- const queryStart = url.indexOf("?", afterProtocol);
92
- const fragmentStart = url.indexOf("#", afterProtocol);
93
- const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
94
- if (atIndex < firstDelimiter) {
95
- url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
95
+ // Find the first delimiter that marks the end of the authority section
96
+ const pathStart = url.indexOf("/", afterProtocol);
97
+ let queryStart = url.indexOf("?", afterProtocol);
98
+ let fragmentStart = url.indexOf("#", afterProtocol);
99
+ const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
100
+ // Find the LAST @ before the delimiter (handles multiple @ in credentials)
101
+ let atIndex = -1;
102
+ for (let i = afterProtocol; i < firstDelimiter; i++) {
103
+ if (url[i] === "@") {
104
+ atIndex = i;
96
105
  }
97
106
  }
98
- const queryStart = url.indexOf("?");
107
+ if (atIndex !== -1) {
108
+ url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
109
+ }
110
+ // Recalculate queryStart since url might have changed
111
+ queryStart = url.indexOf("?");
99
112
  if (queryStart === -1)
100
113
  return url;
101
- const fragmentStart = url.indexOf("#", queryStart);
114
+ fragmentStart = url.indexOf("#", queryStart);
102
115
  const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length;
103
116
  const queryString = url.slice(queryStart + 1, queryEnd);
104
117
  if (queryString.length === 0)
@@ -106,15 +119,15 @@ function redactUrl(url) {
106
119
  // FAST PATH: Quick check if any sensitive keywords present
107
120
  // Using indexOf is faster than regex for simple substring matching
108
121
  const lower = queryString.toLowerCase();
109
- const hasSensitive = lower.includes("token") || // catches token, access_token, auth_token, etc.
110
- lower.includes("key") || // catches key, api_key, apikey, api-key, etc.
111
- lower.includes("password") || // catches password
112
- lower.includes("passwd") || // catches passwd
113
- lower.includes("secret") || // catches secret, api_secret, etc.
114
- lower.includes("session") || // catches session, session_id, session-id
115
- lower.includes("auth"); // catches auth_token, auth-token, etc.
122
+ const hasSensitive = lower.includes("token") ||
123
+ lower.includes("key") ||
124
+ lower.includes("password") ||
125
+ lower.includes("passwd") ||
126
+ lower.includes("secret") ||
127
+ lower.includes("session") ||
128
+ lower.includes("auth");
116
129
  if (!hasSensitive) {
117
- return url; // Early exit - no sensitive params
130
+ return url;
118
131
  }
119
132
  // SLOW PATH: Parse and redact
120
133
  const redactedParams = [];
@@ -193,6 +206,7 @@ function fetcherImpl(args) {
193
206
  method: args.method,
194
207
  url: redactUrl(url),
195
208
  statusCode: response.status,
209
+ responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())),
196
210
  };
197
211
  logger.debug("HTTP request succeeded", metadata);
198
212
  }
@@ -209,6 +223,7 @@ function fetcherImpl(args) {
209
223
  method: args.method,
210
224
  url: redactUrl(url),
211
225
  statusCode: response.status,
226
+ responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())),
212
227
  };
213
228
  logger.error("HTTP request failed with error status", metadata);
214
229
  }
@@ -13,14 +13,12 @@ exports.makeRequest = void 0;
13
13
  const signals_js_1 = require("./signals.js");
14
14
  const makeRequest = (fetchFn, url, method, headers, requestBody, timeoutMs, abortSignal, withCredentials, duplex) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  const signals = [];
16
- // Add timeout signal
17
16
  let timeoutAbortId;
18
17
  if (timeoutMs != null) {
19
18
  const { signal, abortId } = (0, signals_js_1.getTimeoutSignal)(timeoutMs);
20
19
  timeoutAbortId = abortId;
21
20
  signals.push(signal);
22
21
  }
23
- // Add arbitrary signal
24
22
  if (abortSignal != null) {
25
23
  signals.push(abortSignal);
26
24
  }
@@ -15,25 +15,20 @@ const MAX_RETRY_DELAY = 60000; // in milliseconds
15
15
  const DEFAULT_MAX_RETRIES = 2;
16
16
  const JITTER_FACTOR = 0.2; // 20% random jitter
17
17
  function addPositiveJitter(delay) {
18
- // Generate a random value between 0 and +JITTER_FACTOR
19
18
  const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR;
20
19
  return delay * jitterMultiplier;
21
20
  }
22
21
  function addSymmetricJitter(delay) {
23
- // Generate a random value in a JITTER_FACTOR-sized percentage range around delay
24
22
  const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR;
25
23
  return delay * jitterMultiplier;
26
24
  }
27
25
  function getRetryDelayFromHeaders(response, retryAttempt) {
28
- // Check for Retry-After header first (RFC 7231), with no jitter
29
26
  const retryAfter = response.headers.get("Retry-After");
30
27
  if (retryAfter) {
31
- // Parse as number of seconds...
32
28
  const retryAfterSeconds = parseInt(retryAfter, 10);
33
29
  if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) {
34
30
  return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY);
35
31
  }
36
- // ...or as an HTTP date; both are valid
37
32
  const retryAfterDate = new Date(retryAfter);
38
33
  if (!Number.isNaN(retryAfterDate.getTime())) {
39
34
  const delay = retryAfterDate.getTime() - Date.now();
@@ -42,19 +37,16 @@ function getRetryDelayFromHeaders(response, retryAttempt) {
42
37
  }
43
38
  }
44
39
  }
45
- // Then check for industry-standard X-RateLimit-Reset header, with positive jitter
46
40
  const rateLimitReset = response.headers.get("X-RateLimit-Reset");
47
41
  if (rateLimitReset) {
48
42
  const resetTime = parseInt(rateLimitReset, 10);
49
43
  if (!Number.isNaN(resetTime)) {
50
- // Assume Unix timestamp in epoch seconds
51
44
  const delay = resetTime * 1000 - Date.now();
52
45
  if (delay > 0) {
53
46
  return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY));
54
47
  }
55
48
  }
56
49
  }
57
- // Fall back to exponential backoff, with symmetric jitter
58
50
  return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * Math.pow(2, retryAttempt), MAX_RETRY_DELAY));
59
51
  }
60
52
  function requestWithRetries(requestFn_1) {
@@ -62,7 +54,6 @@ function requestWithRetries(requestFn_1) {
62
54
  let response = yield requestFn();
63
55
  for (let i = 0; i < maxRetries; ++i) {
64
56
  if ([408, 429].includes(response.status) || response.status >= 500) {
65
- // Get delay with appropriate jitter applied
66
57
  const delay = getRetryDelayFromHeaders(response, i);
67
58
  yield new Promise((resolve) => setTimeout(resolve, delay));
68
59
  response = yield requestFn();
@@ -2,10 +2,4 @@ export declare function getTimeoutSignal(timeoutMs: number): {
2
2
  signal: AbortSignal;
3
3
  abortId: NodeJS.Timeout;
4
4
  };
5
- /**
6
- * Returns an abort signal that is getting aborted when
7
- * at least one of the specified abort signals is aborted.
8
- *
9
- * Requires at least node.js 18.
10
- */
11
5
  export declare function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal;
@@ -8,26 +8,14 @@ function getTimeoutSignal(timeoutMs) {
8
8
  const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs);
9
9
  return { signal: controller.signal, abortId };
10
10
  }
11
- /**
12
- * Returns an abort signal that is getting aborted when
13
- * at least one of the specified abort signals is aborted.
14
- *
15
- * Requires at least node.js 18.
16
- */
17
11
  function anySignal(...args) {
18
- // Allowing signals to be passed either as array
19
- // of signals or as multiple arguments.
20
12
  const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args);
21
13
  const controller = new AbortController();
22
14
  for (const signal of signals) {
23
15
  if (signal.aborted) {
24
- // Exiting early if one of the signals
25
- // is already aborted.
26
16
  controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
27
17
  break;
28
18
  }
29
- // Listening for signals and removing the listeners
30
- // when at least one symbol is aborted.
31
19
  signal.addEventListener("abort", () => controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason), {
32
20
  signal: controller.signal,
33
21
  });
@@ -51,7 +51,7 @@ class Logger {
51
51
  * @returns True if the level should be logged
52
52
  */
53
53
  shouldLog(level) {
54
- return !this.silent && this.level >= logLevelMap[level];
54
+ return !this.silent && this.level <= logLevelMap[level];
55
55
  }
56
56
  /**
57
57
  * Checks if debug logging is enabled.
@@ -14,7 +14,6 @@ function join(base, ...segments) {
14
14
  url = new URL(base);
15
15
  }
16
16
  catch (_a) {
17
- // Fallback to path joining if URL is malformed
18
17
  return joinPath(base, ...segments);
19
18
  }
20
19
  const lastSegment = segments[segments.length - 1];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "6.2.0";
1
+ export declare const SDK_VERSION = "6.3.0";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
- exports.SDK_VERSION = "6.2.0";
4
+ exports.SDK_VERSION = "6.3.0";
@@ -16,7 +16,7 @@ export class phenomlClient {
16
16
  this._options = Object.assign(Object.assign({}, _options), { logging: core.logging.createLogger(_options === null || _options === void 0 ? void 0 : _options.logging), headers: mergeHeaders({
17
17
  "X-Fern-Language": "JavaScript",
18
18
  "X-Fern-SDK-Name": "phenoml",
19
- "X-Fern-SDK-Version": "6.2.0",
19
+ "X-Fern-SDK-Version": "6.3.0",
20
20
  "User-Agent": "phenoml/auto",
21
21
  "X-Fern-Runtime": core.RUNTIME.type,
22
22
  "X-Fern-Runtime-Version": core.RUNTIME.version,
@@ -20,14 +20,21 @@ import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawRespon
20
20
  import { requestWithRetries } from "./requestWithRetries.mjs";
21
21
  const SENSITIVE_HEADERS = new Set([
22
22
  "authorization",
23
+ "www-authenticate",
23
24
  "x-api-key",
24
25
  "api-key",
26
+ "apikey",
27
+ "x-api-token",
25
28
  "x-auth-token",
29
+ "auth-token",
26
30
  "cookie",
27
31
  "set-cookie",
28
32
  "proxy-authorization",
33
+ "proxy-authenticate",
29
34
  "x-csrf-token",
30
35
  "x-xsrf-token",
36
+ "x-session-token",
37
+ "x-access-token",
31
38
  ]);
32
39
  function redactHeaders(headers) {
33
40
  const filtered = {};
@@ -81,20 +88,26 @@ function redactUrl(url) {
81
88
  if (protocolIndex === -1)
82
89
  return url;
83
90
  const afterProtocol = protocolIndex + 3;
84
- const atIndex = url.indexOf("@", afterProtocol);
85
- if (atIndex !== -1) {
86
- const pathStart = url.indexOf("/", afterProtocol);
87
- const queryStart = url.indexOf("?", afterProtocol);
88
- const fragmentStart = url.indexOf("#", afterProtocol);
89
- const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
90
- if (atIndex < firstDelimiter) {
91
- url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
91
+ // Find the first delimiter that marks the end of the authority section
92
+ const pathStart = url.indexOf("/", afterProtocol);
93
+ let queryStart = url.indexOf("?", afterProtocol);
94
+ let fragmentStart = url.indexOf("#", afterProtocol);
95
+ const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
96
+ // Find the LAST @ before the delimiter (handles multiple @ in credentials)
97
+ let atIndex = -1;
98
+ for (let i = afterProtocol; i < firstDelimiter; i++) {
99
+ if (url[i] === "@") {
100
+ atIndex = i;
92
101
  }
93
102
  }
94
- const queryStart = url.indexOf("?");
103
+ if (atIndex !== -1) {
104
+ url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
105
+ }
106
+ // Recalculate queryStart since url might have changed
107
+ queryStart = url.indexOf("?");
95
108
  if (queryStart === -1)
96
109
  return url;
97
- const fragmentStart = url.indexOf("#", queryStart);
110
+ fragmentStart = url.indexOf("#", queryStart);
98
111
  const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length;
99
112
  const queryString = url.slice(queryStart + 1, queryEnd);
100
113
  if (queryString.length === 0)
@@ -102,15 +115,15 @@ function redactUrl(url) {
102
115
  // FAST PATH: Quick check if any sensitive keywords present
103
116
  // Using indexOf is faster than regex for simple substring matching
104
117
  const lower = queryString.toLowerCase();
105
- const hasSensitive = lower.includes("token") || // catches token, access_token, auth_token, etc.
106
- lower.includes("key") || // catches key, api_key, apikey, api-key, etc.
107
- lower.includes("password") || // catches password
108
- lower.includes("passwd") || // catches passwd
109
- lower.includes("secret") || // catches secret, api_secret, etc.
110
- lower.includes("session") || // catches session, session_id, session-id
111
- lower.includes("auth"); // catches auth_token, auth-token, etc.
118
+ const hasSensitive = lower.includes("token") ||
119
+ lower.includes("key") ||
120
+ lower.includes("password") ||
121
+ lower.includes("passwd") ||
122
+ lower.includes("secret") ||
123
+ lower.includes("session") ||
124
+ lower.includes("auth");
112
125
  if (!hasSensitive) {
113
- return url; // Early exit - no sensitive params
126
+ return url;
114
127
  }
115
128
  // SLOW PATH: Parse and redact
116
129
  const redactedParams = [];
@@ -189,6 +202,7 @@ export function fetcherImpl(args) {
189
202
  method: args.method,
190
203
  url: redactUrl(url),
191
204
  statusCode: response.status,
205
+ responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())),
192
206
  };
193
207
  logger.debug("HTTP request succeeded", metadata);
194
208
  }
@@ -205,6 +219,7 @@ export function fetcherImpl(args) {
205
219
  method: args.method,
206
220
  url: redactUrl(url),
207
221
  statusCode: response.status,
222
+ responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())),
208
223
  };
209
224
  logger.error("HTTP request failed with error status", metadata);
210
225
  }
@@ -10,14 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { anySignal, getTimeoutSignal } from "./signals.mjs";
11
11
  export const makeRequest = (fetchFn, url, method, headers, requestBody, timeoutMs, abortSignal, withCredentials, duplex) => __awaiter(void 0, void 0, void 0, function* () {
12
12
  const signals = [];
13
- // Add timeout signal
14
13
  let timeoutAbortId;
15
14
  if (timeoutMs != null) {
16
15
  const { signal, abortId } = getTimeoutSignal(timeoutMs);
17
16
  timeoutAbortId = abortId;
18
17
  signals.push(signal);
19
18
  }
20
- // Add arbitrary signal
21
19
  if (abortSignal != null) {
22
20
  signals.push(abortSignal);
23
21
  }
@@ -12,25 +12,20 @@ const MAX_RETRY_DELAY = 60000; // in milliseconds
12
12
  const DEFAULT_MAX_RETRIES = 2;
13
13
  const JITTER_FACTOR = 0.2; // 20% random jitter
14
14
  function addPositiveJitter(delay) {
15
- // Generate a random value between 0 and +JITTER_FACTOR
16
15
  const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR;
17
16
  return delay * jitterMultiplier;
18
17
  }
19
18
  function addSymmetricJitter(delay) {
20
- // Generate a random value in a JITTER_FACTOR-sized percentage range around delay
21
19
  const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR;
22
20
  return delay * jitterMultiplier;
23
21
  }
24
22
  function getRetryDelayFromHeaders(response, retryAttempt) {
25
- // Check for Retry-After header first (RFC 7231), with no jitter
26
23
  const retryAfter = response.headers.get("Retry-After");
27
24
  if (retryAfter) {
28
- // Parse as number of seconds...
29
25
  const retryAfterSeconds = parseInt(retryAfter, 10);
30
26
  if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) {
31
27
  return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY);
32
28
  }
33
- // ...or as an HTTP date; both are valid
34
29
  const retryAfterDate = new Date(retryAfter);
35
30
  if (!Number.isNaN(retryAfterDate.getTime())) {
36
31
  const delay = retryAfterDate.getTime() - Date.now();
@@ -39,19 +34,16 @@ function getRetryDelayFromHeaders(response, retryAttempt) {
39
34
  }
40
35
  }
41
36
  }
42
- // Then check for industry-standard X-RateLimit-Reset header, with positive jitter
43
37
  const rateLimitReset = response.headers.get("X-RateLimit-Reset");
44
38
  if (rateLimitReset) {
45
39
  const resetTime = parseInt(rateLimitReset, 10);
46
40
  if (!Number.isNaN(resetTime)) {
47
- // Assume Unix timestamp in epoch seconds
48
41
  const delay = resetTime * 1000 - Date.now();
49
42
  if (delay > 0) {
50
43
  return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY));
51
44
  }
52
45
  }
53
46
  }
54
- // Fall back to exponential backoff, with symmetric jitter
55
47
  return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * Math.pow(2, retryAttempt), MAX_RETRY_DELAY));
56
48
  }
57
49
  export function requestWithRetries(requestFn_1) {
@@ -59,7 +51,6 @@ export function requestWithRetries(requestFn_1) {
59
51
  let response = yield requestFn();
60
52
  for (let i = 0; i < maxRetries; ++i) {
61
53
  if ([408, 429].includes(response.status) || response.status >= 500) {
62
- // Get delay with appropriate jitter applied
63
54
  const delay = getRetryDelayFromHeaders(response, i);
64
55
  yield new Promise((resolve) => setTimeout(resolve, delay));
65
56
  response = yield requestFn();
@@ -2,10 +2,4 @@ export declare function getTimeoutSignal(timeoutMs: number): {
2
2
  signal: AbortSignal;
3
3
  abortId: NodeJS.Timeout;
4
4
  };
5
- /**
6
- * Returns an abort signal that is getting aborted when
7
- * at least one of the specified abort signals is aborted.
8
- *
9
- * Requires at least node.js 18.
10
- */
11
5
  export declare function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal;
@@ -4,26 +4,14 @@ export function getTimeoutSignal(timeoutMs) {
4
4
  const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs);
5
5
  return { signal: controller.signal, abortId };
6
6
  }
7
- /**
8
- * Returns an abort signal that is getting aborted when
9
- * at least one of the specified abort signals is aborted.
10
- *
11
- * Requires at least node.js 18.
12
- */
13
7
  export function anySignal(...args) {
14
- // Allowing signals to be passed either as array
15
- // of signals or as multiple arguments.
16
8
  const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args);
17
9
  const controller = new AbortController();
18
10
  for (const signal of signals) {
19
11
  if (signal.aborted) {
20
- // Exiting early if one of the signals
21
- // is already aborted.
22
12
  controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
23
13
  break;
24
14
  }
25
- // Listening for signals and removing the listeners
26
- // when at least one symbol is aborted.
27
15
  signal.addEventListener("abort", () => controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason), {
28
16
  signal: controller.signal,
29
17
  });
@@ -46,7 +46,7 @@ export class Logger {
46
46
  * @returns True if the level should be logged
47
47
  */
48
48
  shouldLog(level) {
49
- return !this.silent && this.level >= logLevelMap[level];
49
+ return !this.silent && this.level <= logLevelMap[level];
50
50
  }
51
51
  /**
52
52
  * Checks if debug logging is enabled.
@@ -11,7 +11,6 @@ export function join(base, ...segments) {
11
11
  url = new URL(base);
12
12
  }
13
13
  catch (_a) {
14
- // Fallback to path joining if URL is malformed
15
14
  return joinPath(base, ...segments);
16
15
  }
17
16
  const lastSegment = segments[segments.length - 1];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "6.2.0";
1
+ export declare const SDK_VERSION = "6.3.0";
@@ -1 +1 @@
1
- export const SDK_VERSION = "6.2.0";
1
+ export const SDK_VERSION = "6.3.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phenoml",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "private": false,
5
5
  "repository": "github:PhenoML/phenoml-ts-sdk",
6
6
  "type": "commonjs",