@roarkanalytics/sdk 2.21.1 → 2.22.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/CHANGELOG.md +16 -0
- package/README.md +78 -46
- package/api-promise.d.mts +1 -46
- package/api-promise.d.mts.map +1 -1
- package/api-promise.d.ts +1 -46
- package/api-promise.d.ts.map +1 -1
- package/api-promise.js +3 -81
- package/api-promise.js.map +1 -1
- package/api-promise.mjs +1 -79
- package/api-promise.mjs.map +1 -1
- package/client.d.mts +25 -30
- package/client.d.mts.map +1 -1
- package/client.d.ts +25 -30
- package/client.d.ts.map +1 -1
- package/client.js +150 -132
- package/client.js.map +1 -1
- package/client.mjs +145 -104
- package/client.mjs.map +1 -1
- package/core/api-promise.d.mts +46 -0
- package/core/api-promise.d.mts.map +1 -0
- package/core/api-promise.d.ts +46 -0
- package/core/api-promise.d.ts.map +1 -0
- package/core/api-promise.js +74 -0
- package/core/api-promise.js.map +1 -0
- package/core/api-promise.mjs +70 -0
- package/core/api-promise.mjs.map +1 -0
- package/core/error.d.mts +46 -0
- package/core/error.d.mts.map +1 -0
- package/core/error.d.ts +46 -0
- package/core/error.d.ts.map +1 -0
- package/core/error.js +113 -0
- package/core/error.js.map +1 -0
- package/core/error.mjs +97 -0
- package/core/error.mjs.map +1 -0
- package/core/resource.d.mts +6 -0
- package/core/resource.d.mts.map +1 -0
- package/core/resource.d.ts +6 -0
- package/core/resource.d.ts.map +1 -0
- package/core/resource.js +11 -0
- package/core/resource.js.map +1 -0
- package/core/resource.mjs +7 -0
- package/core/resource.mjs.map +1 -0
- package/core/uploads.d.mts +3 -0
- package/core/uploads.d.mts.map +1 -0
- package/core/uploads.d.ts +3 -0
- package/core/uploads.d.ts.map +1 -0
- package/core/uploads.js +6 -0
- package/core/uploads.js.map +1 -0
- package/core/uploads.mjs +2 -0
- package/core/uploads.mjs.map +1 -0
- package/error.d.mts +1 -46
- package/error.d.mts.map +1 -1
- package/error.d.ts +1 -46
- package/error.d.ts.map +1 -1
- package/error.js +3 -110
- package/error.js.map +1 -1
- package/error.mjs +1 -96
- package/error.mjs.map +1 -1
- package/index.d.mts +6 -6
- package/index.d.ts +3 -3
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/index.mjs +3 -3
- package/internal/builtin-types.d.mts +11 -3
- package/internal/builtin-types.d.mts.map +1 -1
- package/internal/builtin-types.d.ts +11 -3
- package/internal/builtin-types.d.ts.map +1 -1
- package/internal/detect-platform.js +3 -3
- package/internal/detect-platform.js.map +1 -1
- package/internal/detect-platform.mjs +3 -3
- package/internal/detect-platform.mjs.map +1 -1
- package/internal/errors.d.mts.map +1 -1
- package/internal/errors.d.ts.map +1 -1
- package/internal/errors.js +17 -2
- package/internal/errors.js.map +1 -1
- package/internal/errors.mjs +15 -0
- package/internal/errors.mjs.map +1 -1
- package/internal/headers.d.mts +1 -2
- package/internal/headers.d.mts.map +1 -1
- package/internal/headers.d.ts +1 -2
- package/internal/headers.d.ts.map +1 -1
- package/internal/headers.js +7 -5
- package/internal/headers.js.map +1 -1
- package/internal/headers.mjs +7 -5
- package/internal/headers.mjs.map +1 -1
- package/internal/parse.d.mts +3 -1
- package/internal/parse.d.mts.map +1 -1
- package/internal/parse.d.ts +3 -1
- package/internal/parse.d.ts.map +1 -1
- package/internal/parse.js +33 -21
- package/internal/parse.js.map +1 -1
- package/internal/parse.mjs +33 -20
- package/internal/parse.mjs.map +1 -1
- package/internal/qs/formats.d.mts +1 -0
- package/internal/qs/formats.d.mts.map +1 -1
- package/internal/qs/formats.d.ts +1 -0
- package/internal/qs/formats.d.ts.map +1 -1
- package/internal/qs/formats.js +4 -2
- package/internal/qs/formats.js.map +1 -1
- package/internal/qs/formats.mjs +2 -1
- package/internal/qs/formats.mjs.map +1 -1
- package/internal/qs/stringify.d.mts.map +1 -1
- package/internal/qs/stringify.d.ts.map +1 -1
- package/internal/qs/stringify.js +16 -19
- package/internal/qs/stringify.js.map +1 -1
- package/internal/qs/stringify.mjs +17 -19
- package/internal/qs/stringify.mjs.map +1 -1
- package/internal/qs/utils.d.mts +1 -0
- package/internal/qs/utils.d.mts.map +1 -1
- package/internal/qs/utils.d.ts +1 -0
- package/internal/qs/utils.d.ts.map +1 -1
- package/internal/qs/utils.js +22 -21
- package/internal/qs/utils.js.map +1 -1
- package/internal/qs/utils.mjs +12 -12
- package/internal/qs/utils.mjs.map +1 -1
- package/internal/request-options.d.mts +43 -2
- package/internal/request-options.d.mts.map +1 -1
- package/internal/request-options.d.ts +43 -2
- package/internal/request-options.d.ts.map +1 -1
- package/internal/request-options.js +1 -26
- package/internal/request-options.js.map +1 -1
- package/internal/request-options.mjs +0 -24
- package/internal/request-options.mjs.map +1 -1
- package/internal/shim-types.d.mts +11 -22
- package/internal/shim-types.d.mts.map +1 -0
- package/internal/shim-types.d.ts +11 -22
- package/internal/shim-types.d.ts.map +1 -0
- package/internal/shim-types.js +4 -0
- package/internal/shim-types.js.map +1 -0
- package/internal/shim-types.mjs +3 -0
- package/internal/shim-types.mjs.map +1 -0
- package/internal/shims.d.mts +7 -48
- package/internal/shims.d.mts.map +1 -1
- package/internal/shims.d.ts +7 -48
- package/internal/shims.d.ts.map +1 -1
- package/internal/shims.js +21 -30
- package/internal/shims.js.map +1 -1
- package/internal/shims.mjs +16 -23
- package/internal/shims.mjs.map +1 -1
- package/internal/to-file.d.mts +45 -0
- package/internal/to-file.d.mts.map +1 -0
- package/internal/to-file.d.ts +45 -0
- package/internal/to-file.d.ts.map +1 -0
- package/internal/to-file.js +91 -0
- package/internal/to-file.js.map +1 -0
- package/internal/to-file.mjs +88 -0
- package/internal/to-file.mjs.map +1 -0
- package/internal/tslib.js +81 -0
- package/internal/tslib.mjs +17 -0
- package/internal/types.d.mts +14 -13
- package/internal/types.d.mts.map +1 -1
- package/internal/types.d.ts +14 -13
- package/internal/types.d.ts.map +1 -1
- package/internal/uploads.d.mts +16 -47
- package/internal/uploads.d.mts.map +1 -1
- package/internal/uploads.d.ts +16 -47
- package/internal/uploads.d.ts.map +1 -1
- package/internal/uploads.js +41 -108
- package/internal/uploads.js.map +1 -1
- package/internal/uploads.mjs +39 -108
- package/internal/uploads.mjs.map +1 -1
- package/internal/utils/base64.d.mts.map +1 -1
- package/internal/utils/base64.d.ts.map +1 -1
- package/internal/utils/base64.js +13 -8
- package/internal/utils/base64.js.map +1 -1
- package/internal/utils/base64.mjs +13 -8
- package/internal/utils/base64.mjs.map +1 -1
- package/internal/utils/bytes.d.mts +4 -0
- package/internal/utils/bytes.d.mts.map +1 -0
- package/internal/utils/bytes.d.ts +4 -0
- package/internal/utils/bytes.d.ts.map +1 -0
- package/internal/utils/bytes.js +31 -0
- package/internal/utils/bytes.js.map +1 -0
- package/internal/utils/bytes.mjs +26 -0
- package/internal/utils/bytes.mjs.map +1 -0
- package/internal/utils/env.d.mts.map +1 -1
- package/internal/utils/env.d.ts.map +1 -1
- package/internal/utils/env.js.map +1 -1
- package/internal/utils/env.mjs.map +1 -1
- package/internal/utils/log.d.mts +35 -2
- package/internal/utils/log.d.mts.map +1 -1
- package/internal/utils/log.d.ts +35 -2
- package/internal/utils/log.d.ts.map +1 -1
- package/internal/utils/log.js +62 -24
- package/internal/utils/log.js.map +1 -1
- package/internal/utils/log.mjs +58 -22
- package/internal/utils/log.mjs.map +1 -1
- package/internal/utils/path.d.mts +15 -0
- package/internal/utils/path.d.mts.map +1 -0
- package/internal/utils/path.d.ts +15 -0
- package/internal/utils/path.d.ts.map +1 -0
- package/internal/utils/path.js +79 -0
- package/internal/utils/path.js.map +1 -0
- package/internal/utils/path.mjs +74 -0
- package/internal/utils/path.mjs.map +1 -0
- package/internal/utils/sleep.d.mts.map +1 -1
- package/internal/utils/sleep.d.ts.map +1 -1
- package/internal/utils/uuid.d.mts +1 -1
- package/internal/utils/uuid.d.mts.map +1 -1
- package/internal/utils/uuid.d.ts +1 -1
- package/internal/utils/uuid.d.ts.map +1 -1
- package/internal/utils/uuid.js +10 -6
- package/internal/utils/uuid.js.map +1 -1
- package/internal/utils/uuid.mjs +9 -5
- package/internal/utils/uuid.mjs.map +1 -1
- package/internal/utils/values.d.mts +4 -1
- package/internal/utils/values.d.mts.map +1 -1
- package/internal/utils/values.d.ts +4 -1
- package/internal/utils/values.d.ts.map +1 -1
- package/internal/utils/values.js +21 -9
- package/internal/utils/values.js.map +1 -1
- package/internal/utils/values.mjs +14 -4
- package/internal/utils/values.mjs.map +1 -1
- package/internal/utils.js +7 -20
- package/internal/utils.js.map +1 -1
- package/package.json +31 -13
- package/resource.d.mts +1 -5
- package/resource.d.mts.map +1 -1
- package/resource.d.ts +1 -5
- package/resource.d.ts.map +1 -1
- package/resource.js +3 -8
- package/resource.js.map +1 -1
- package/resource.mjs +1 -6
- package/resource.mjs.map +1 -1
- package/resources/call.d.mts +17 -7
- package/resources/call.d.mts.map +1 -1
- package/resources/call.d.ts +17 -7
- package/resources/call.d.ts.map +1 -1
- package/resources/call.js +6 -5
- package/resources/call.js.map +1 -1
- package/resources/call.mjs +6 -5
- package/resources/call.mjs.map +1 -1
- package/resources/evaluation.d.mts +20 -8
- package/resources/evaluation.d.mts.map +1 -1
- package/resources/evaluation.d.ts +20 -8
- package/resources/evaluation.d.ts.map +1 -1
- package/resources/evaluation.js +5 -4
- package/resources/evaluation.js.map +1 -1
- package/resources/evaluation.mjs +5 -4
- package/resources/evaluation.mjs.map +1 -1
- package/resources/health.d.mts +2 -2
- package/resources/health.d.ts +2 -2
- package/resources/health.js +1 -1
- package/resources/health.js.map +1 -1
- package/resources/health.mjs +1 -1
- package/resources/integrations.d.mts +39 -6
- package/resources/integrations.d.mts.map +1 -1
- package/resources/integrations.d.ts +39 -6
- package/resources/integrations.d.ts.map +1 -1
- package/resources/integrations.js +26 -1
- package/resources/integrations.js.map +1 -1
- package/resources/integrations.mjs +26 -1
- package/resources/integrations.mjs.map +1 -1
- package/resources/metric.d.mts +2 -2
- package/resources/metric.d.ts +2 -2
- package/resources/metric.js +1 -1
- package/resources/metric.js.map +1 -1
- package/resources/metric.mjs +1 -1
- package/resources/persona.d.mts +45 -8
- package/resources/persona.d.mts.map +1 -1
- package/resources/persona.d.ts +45 -8
- package/resources/persona.d.ts.map +1 -1
- package/resources/persona.js +29 -3
- package/resources/persona.js.map +1 -1
- package/resources/persona.mjs +29 -3
- package/resources/persona.mjs.map +1 -1
- package/resources/simulation.d.mts +51 -5
- package/resources/simulation.d.mts.map +1 -1
- package/resources/simulation.d.ts +51 -5
- package/resources/simulation.d.ts.map +1 -1
- package/resources/simulation.js +45 -4
- package/resources/simulation.js.map +1 -1
- package/resources/simulation.mjs +45 -4
- package/resources/simulation.mjs.map +1 -1
- package/resources.d.mts +2 -0
- package/resources.d.mts.map +1 -0
- package/resources.d.ts +2 -0
- package/resources.d.ts.map +1 -0
- package/resources.js +5 -0
- package/resources.js.map +1 -0
- package/resources.mjs +2 -0
- package/resources.mjs.map +1 -0
- package/src/api-promise.ts +2 -92
- package/src/client.ts +207 -116
- package/src/core/README.md +3 -0
- package/src/core/api-promise.ts +92 -0
- package/src/core/error.ts +130 -0
- package/src/core/resource.ts +11 -0
- package/src/core/uploads.ts +2 -0
- package/src/error.ts +2 -130
- package/src/index.ts +3 -3
- package/src/internal/README.md +3 -0
- package/src/internal/builtin-types.ts +14 -0
- package/src/internal/detect-platform.ts +3 -3
- package/src/internal/errors.ts +11 -0
- package/src/internal/headers.ts +9 -8
- package/src/internal/parse.ts +43 -28
- package/src/internal/qs/formats.ts +2 -1
- package/src/internal/qs/stringify.ts +17 -20
- package/src/internal/qs/utils.ts +14 -14
- package/src/internal/request-options.ts +55 -31
- package/src/internal/shim-types.ts +26 -0
- package/src/internal/shims.ts +20 -58
- package/src/internal/to-file.ts +154 -0
- package/src/internal/types.ts +14 -17
- package/src/internal/uploads.ts +60 -180
- package/src/internal/utils/base64.ts +14 -11
- package/src/internal/utils/bytes.ts +32 -0
- package/src/internal/utils/log.ts +100 -23
- package/src/internal/utils/path.ts +88 -0
- package/src/internal/utils/uuid.ts +10 -6
- package/src/internal/utils/values.ts +16 -5
- package/src/resource.ts +2 -11
- package/src/resources/call.ts +12 -11
- package/src/resources/evaluation.ts +12 -11
- package/src/resources/health.ts +2 -2
- package/src/resources/integrations.ts +31 -6
- package/src/resources/metric.ts +2 -2
- package/src/resources/persona.ts +36 -10
- package/src/resources/simulation.ts +49 -8
- package/src/resources.ts +1 -0
- package/src/uploads.ts +2 -1
- package/src/version.ts +1 -1
- package/uploads.d.mts +1 -1
- package/uploads.d.mts.map +1 -1
- package/uploads.d.ts +1 -1
- package/uploads.d.ts.map +1 -1
- package/uploads.js +3 -3
- package/uploads.js.map +1 -1
- package/uploads.mjs +1 -1
- package/uploads.mjs.map +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
- package/internal/polyfill/crypto.node.d.ts +0 -10
- package/internal/polyfill/crypto.node.js +0 -11
- package/internal/polyfill/crypto.node.mjs +0 -2
- package/internal/polyfill/file.node.d.ts +0 -9
- package/internal/polyfill/file.node.js +0 -17
- package/internal/polyfill/file.node.mjs +0 -9
- package/src/internal/polyfill/crypto.node.d.ts +0 -10
- package/src/internal/polyfill/crypto.node.js +0 -11
- package/src/internal/polyfill/crypto.node.mjs +0 -2
- package/src/internal/polyfill/file.node.d.ts +0 -9
- package/src/internal/polyfill/file.node.js +0 -17
- package/src/internal/polyfill/file.node.mjs +0 -9
- package/src/internal/shim-types.d.ts +0 -28
package/src/client.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
3
|
import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types';
|
|
4
|
-
import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types';
|
|
4
|
+
import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types';
|
|
5
5
|
import { uuid4 } from './internal/utils/uuid';
|
|
6
|
-
import { validatePositiveInteger, isAbsoluteURL } from './internal/utils/values';
|
|
6
|
+
import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
|
|
7
7
|
import { sleep } from './internal/utils/sleep';
|
|
8
|
+
export type { Logger, LogLevel } from './internal/utils/log';
|
|
8
9
|
import { castToError, isAbortError } from './internal/errors';
|
|
9
10
|
import type { APIResponseProps } from './internal/parse';
|
|
10
11
|
import { getPlatformHeaders } from './internal/detect-platform';
|
|
@@ -12,13 +13,10 @@ import * as Shims from './internal/shims';
|
|
|
12
13
|
import * as Opts from './internal/request-options';
|
|
13
14
|
import * as qs from './internal/qs';
|
|
14
15
|
import { VERSION } from './version';
|
|
15
|
-
import * as Errors from './error';
|
|
16
|
-
import * as Uploads from './uploads';
|
|
16
|
+
import * as Errors from './core/error';
|
|
17
|
+
import * as Uploads from './core/uploads';
|
|
17
18
|
import * as API from './resources/index';
|
|
18
|
-
import { APIPromise } from './api-promise';
|
|
19
|
-
import { type Fetch } from './internal/builtin-types';
|
|
20
|
-
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
|
|
21
|
-
import { FinalRequestOptions, RequestOptions } from './internal/request-options';
|
|
19
|
+
import { APIPromise } from './core/api-promise';
|
|
22
20
|
import {
|
|
23
21
|
Call,
|
|
24
22
|
CallCreateParams,
|
|
@@ -73,37 +71,19 @@ import {
|
|
|
73
71
|
SimulationLookupSimulationJobResponse,
|
|
74
72
|
SimulationStartRunPlanJobResponse,
|
|
75
73
|
} from './resources/simulation';
|
|
74
|
+
import { type Fetch } from './internal/builtin-types';
|
|
75
|
+
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
|
|
76
|
+
import { FinalRequestOptions, RequestOptions } from './internal/request-options';
|
|
76
77
|
import { readEnv } from './internal/utils/env';
|
|
77
|
-
import {
|
|
78
|
+
import {
|
|
79
|
+
type LogLevel,
|
|
80
|
+
type Logger,
|
|
81
|
+
formatRequestDetails,
|
|
82
|
+
loggerFor,
|
|
83
|
+
parseLogLevel,
|
|
84
|
+
} from './internal/utils/log';
|
|
78
85
|
import { isEmptyObj } from './internal/utils/values';
|
|
79
86
|
|
|
80
|
-
const safeJSON = (text: string) => {
|
|
81
|
-
try {
|
|
82
|
-
return JSON.parse(text);
|
|
83
|
-
} catch (err) {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
type LogFn = (message: string, ...rest: unknown[]) => void;
|
|
89
|
-
export type Logger = {
|
|
90
|
-
error: LogFn;
|
|
91
|
-
warn: LogFn;
|
|
92
|
-
info: LogFn;
|
|
93
|
-
debug: LogFn;
|
|
94
|
-
};
|
|
95
|
-
export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug';
|
|
96
|
-
const isLogLevel = (key: string | undefined): key is LogLevel => {
|
|
97
|
-
const levels: Record<LogLevel, true> = {
|
|
98
|
-
off: true,
|
|
99
|
-
error: true,
|
|
100
|
-
warn: true,
|
|
101
|
-
info: true,
|
|
102
|
-
debug: true,
|
|
103
|
-
};
|
|
104
|
-
return key! in levels;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
87
|
export interface ClientOptions {
|
|
108
88
|
/**
|
|
109
89
|
* JWT token for authentication
|
|
@@ -123,6 +103,8 @@ export interface ClientOptions {
|
|
|
123
103
|
*
|
|
124
104
|
* Note that request timeouts are retried by default, so in a worst-case scenario you may wait
|
|
125
105
|
* much longer than this timeout before the promise succeeds or fails.
|
|
106
|
+
*
|
|
107
|
+
* @unit milliseconds
|
|
126
108
|
*/
|
|
127
109
|
timeout?: number | undefined;
|
|
128
110
|
/**
|
|
@@ -165,20 +147,18 @@ export interface ClientOptions {
|
|
|
165
147
|
/**
|
|
166
148
|
* Set the log level.
|
|
167
149
|
*
|
|
168
|
-
* Defaults to process.env['ROARK_LOG'].
|
|
150
|
+
* Defaults to process.env['ROARK_LOG'] or 'warn' if it isn't set.
|
|
169
151
|
*/
|
|
170
|
-
logLevel?: LogLevel | undefined
|
|
152
|
+
logLevel?: LogLevel | undefined;
|
|
171
153
|
|
|
172
154
|
/**
|
|
173
155
|
* Set the logger.
|
|
174
156
|
*
|
|
175
157
|
* Defaults to globalThis.console.
|
|
176
158
|
*/
|
|
177
|
-
logger?: Logger | undefined
|
|
159
|
+
logger?: Logger | undefined;
|
|
178
160
|
}
|
|
179
161
|
|
|
180
|
-
type FinalizedRequestInit = RequestInit & { headers: Headers };
|
|
181
|
-
|
|
182
162
|
/**
|
|
183
163
|
* API Client for interfacing with the Roark API.
|
|
184
164
|
*/
|
|
@@ -188,7 +168,7 @@ export class Roark {
|
|
|
188
168
|
baseURL: string;
|
|
189
169
|
maxRetries: number;
|
|
190
170
|
timeout: number;
|
|
191
|
-
logger: Logger
|
|
171
|
+
logger: Logger;
|
|
192
172
|
logLevel: LogLevel | undefined;
|
|
193
173
|
fetchOptions: MergedRequestInit | undefined;
|
|
194
174
|
|
|
@@ -229,14 +209,13 @@ export class Roark {
|
|
|
229
209
|
this.baseURL = options.baseURL!;
|
|
230
210
|
this.timeout = options.timeout ?? Roark.DEFAULT_TIMEOUT /* 1 minute */;
|
|
231
211
|
this.logger = options.logger ?? console;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
212
|
+
const defaultLogLevel = 'warn';
|
|
213
|
+
// Set default logLevel early so that we can log a warning in parseLogLevel.
|
|
214
|
+
this.logLevel = defaultLogLevel;
|
|
215
|
+
this.logLevel =
|
|
216
|
+
parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
|
|
217
|
+
parseLogLevel(readEnv('ROARK_LOG'), "process.env['ROARK_LOG']", this) ??
|
|
218
|
+
defaultLogLevel;
|
|
240
219
|
this.fetchOptions = options.fetchOptions;
|
|
241
220
|
this.maxRetries = options.maxRetries ?? 2;
|
|
242
221
|
this.fetch = options.fetch ?? Shims.getDefaultFetch();
|
|
@@ -247,6 +226,32 @@ export class Roark {
|
|
|
247
226
|
this.bearerToken = bearerToken;
|
|
248
227
|
}
|
|
249
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
231
|
+
*/
|
|
232
|
+
withOptions(options: Partial<ClientOptions>): this {
|
|
233
|
+
const client = new (this.constructor as any as new (props: ClientOptions) => typeof this)({
|
|
234
|
+
...this._options,
|
|
235
|
+
baseURL: this.baseURL,
|
|
236
|
+
maxRetries: this.maxRetries,
|
|
237
|
+
timeout: this.timeout,
|
|
238
|
+
logger: this.logger,
|
|
239
|
+
logLevel: this.logLevel,
|
|
240
|
+
fetch: this.fetch,
|
|
241
|
+
fetchOptions: this.fetchOptions,
|
|
242
|
+
bearerToken: this.bearerToken,
|
|
243
|
+
...options,
|
|
244
|
+
});
|
|
245
|
+
return client;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Check whether the base URL is set to its default.
|
|
250
|
+
*/
|
|
251
|
+
#baseURLOverridden(): boolean {
|
|
252
|
+
return this.baseURL !== 'https://api.roark.ai';
|
|
253
|
+
}
|
|
254
|
+
|
|
250
255
|
protected defaultQuery(): Record<string, string | undefined> | undefined {
|
|
251
256
|
return this._options.defaultQuery;
|
|
252
257
|
}
|
|
@@ -255,8 +260,8 @@ export class Roark {
|
|
|
255
260
|
return;
|
|
256
261
|
}
|
|
257
262
|
|
|
258
|
-
protected authHeaders(opts: FinalRequestOptions):
|
|
259
|
-
return
|
|
263
|
+
protected async authHeaders(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
|
|
264
|
+
return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
|
|
260
265
|
}
|
|
261
266
|
|
|
262
267
|
protected stringifyQuery(query: Record<string, unknown>): string {
|
|
@@ -280,11 +285,16 @@ export class Roark {
|
|
|
280
285
|
return Errors.APIError.generate(status, error, message, headers);
|
|
281
286
|
}
|
|
282
287
|
|
|
283
|
-
buildURL(
|
|
288
|
+
buildURL(
|
|
289
|
+
path: string,
|
|
290
|
+
query: Record<string, unknown> | null | undefined,
|
|
291
|
+
defaultBaseURL?: string | undefined,
|
|
292
|
+
): string {
|
|
293
|
+
const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
|
|
284
294
|
const url =
|
|
285
295
|
isAbsoluteURL(path) ?
|
|
286
296
|
new URL(path)
|
|
287
|
-
: new URL(
|
|
297
|
+
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
|
|
288
298
|
|
|
289
299
|
const defaultQuery = this.defaultQuery();
|
|
290
300
|
if (!isEmptyObj(defaultQuery)) {
|
|
@@ -298,24 +308,6 @@ export class Roark {
|
|
|
298
308
|
return url.toString();
|
|
299
309
|
}
|
|
300
310
|
|
|
301
|
-
private calculateContentLength(body: unknown): string | null {
|
|
302
|
-
if (typeof body === 'string') {
|
|
303
|
-
if (typeof (globalThis as any).Buffer !== 'undefined') {
|
|
304
|
-
return (globalThis as any).Buffer.byteLength(body, 'utf8').toString();
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (typeof (globalThis as any).TextEncoder !== 'undefined') {
|
|
308
|
-
const encoder = new (globalThis as any).TextEncoder();
|
|
309
|
-
const encoded = encoder.encode(body);
|
|
310
|
-
return encoded.length.toString();
|
|
311
|
-
}
|
|
312
|
-
} else if (ArrayBuffer.isView(body)) {
|
|
313
|
-
return body.byteLength.toString();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return null;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
311
|
/**
|
|
320
312
|
* Used as a callback for mutating the given `FinalRequestOptions` object.
|
|
321
313
|
*/
|
|
@@ -368,12 +360,13 @@ export class Roark {
|
|
|
368
360
|
options: PromiseOrValue<FinalRequestOptions>,
|
|
369
361
|
remainingRetries: number | null = null,
|
|
370
362
|
): APIPromise<Rsp> {
|
|
371
|
-
return new APIPromise(this, this.makeRequest(options, remainingRetries));
|
|
363
|
+
return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
|
|
372
364
|
}
|
|
373
365
|
|
|
374
366
|
private async makeRequest(
|
|
375
367
|
optionsInput: PromiseOrValue<FinalRequestOptions>,
|
|
376
368
|
retriesRemaining: number | null,
|
|
369
|
+
retryOfRequestLogID: string | undefined,
|
|
377
370
|
): Promise<APIResponseProps> {
|
|
378
371
|
const options = await optionsInput;
|
|
379
372
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
@@ -383,11 +376,27 @@ export class Roark {
|
|
|
383
376
|
|
|
384
377
|
await this.prepareOptions(options);
|
|
385
378
|
|
|
386
|
-
const { req, url, timeout } = this.buildRequest(options, {
|
|
379
|
+
const { req, url, timeout } = await this.buildRequest(options, {
|
|
380
|
+
retryCount: maxRetries - retriesRemaining,
|
|
381
|
+
});
|
|
387
382
|
|
|
388
383
|
await this.prepareRequest(req, { url, options });
|
|
389
384
|
|
|
390
|
-
|
|
385
|
+
/** Not an API request ID, just for correlating local log entries. */
|
|
386
|
+
const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
|
|
387
|
+
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
|
|
388
|
+
const startTime = Date.now();
|
|
389
|
+
|
|
390
|
+
loggerFor(this).debug(
|
|
391
|
+
`[${requestLogID}] sending request`,
|
|
392
|
+
formatRequestDetails({
|
|
393
|
+
retryOfRequestLogID,
|
|
394
|
+
method: options.method,
|
|
395
|
+
url,
|
|
396
|
+
options,
|
|
397
|
+
headers: req.headers,
|
|
398
|
+
}),
|
|
399
|
+
);
|
|
391
400
|
|
|
392
401
|
if (options.signal?.aborted) {
|
|
393
402
|
throw new Errors.APIUserAbortError();
|
|
@@ -395,52 +404,120 @@ export class Roark {
|
|
|
395
404
|
|
|
396
405
|
const controller = new AbortController();
|
|
397
406
|
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
|
|
407
|
+
const headersTime = Date.now();
|
|
398
408
|
|
|
399
|
-
if (response instanceof Error) {
|
|
409
|
+
if (response instanceof globalThis.Error) {
|
|
410
|
+
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
400
411
|
if (options.signal?.aborted) {
|
|
401
412
|
throw new Errors.APIUserAbortError();
|
|
402
413
|
}
|
|
403
|
-
if (retriesRemaining) {
|
|
404
|
-
return this.retryRequest(options, retriesRemaining);
|
|
405
|
-
}
|
|
406
|
-
if (isAbortError(response)) {
|
|
407
|
-
throw new Errors.APIConnectionTimeoutError();
|
|
408
|
-
}
|
|
409
414
|
// detect native connection timeout errors
|
|
410
415
|
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
|
|
411
416
|
// undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
|
|
412
417
|
// others do not provide enough information to distinguish timeouts from other connection errors
|
|
413
|
-
|
|
418
|
+
const isTimeout =
|
|
419
|
+
isAbortError(response) ||
|
|
420
|
+
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
|
|
421
|
+
if (retriesRemaining) {
|
|
422
|
+
loggerFor(this).info(
|
|
423
|
+
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`,
|
|
424
|
+
);
|
|
425
|
+
loggerFor(this).debug(
|
|
426
|
+
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`,
|
|
427
|
+
formatRequestDetails({
|
|
428
|
+
retryOfRequestLogID,
|
|
429
|
+
url,
|
|
430
|
+
durationMs: headersTime - startTime,
|
|
431
|
+
message: response.message,
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
434
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
435
|
+
}
|
|
436
|
+
loggerFor(this).info(
|
|
437
|
+
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`,
|
|
438
|
+
);
|
|
439
|
+
loggerFor(this).debug(
|
|
440
|
+
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`,
|
|
441
|
+
formatRequestDetails({
|
|
442
|
+
retryOfRequestLogID,
|
|
443
|
+
url,
|
|
444
|
+
durationMs: headersTime - startTime,
|
|
445
|
+
message: response.message,
|
|
446
|
+
}),
|
|
447
|
+
);
|
|
448
|
+
if (isTimeout) {
|
|
414
449
|
throw new Errors.APIConnectionTimeoutError();
|
|
415
450
|
}
|
|
416
451
|
throw new Errors.APIConnectionError({ cause: response });
|
|
417
452
|
}
|
|
418
453
|
|
|
454
|
+
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${
|
|
455
|
+
response.ok ? 'succeeded' : 'failed'
|
|
456
|
+
} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
457
|
+
|
|
419
458
|
if (!response.ok) {
|
|
420
|
-
|
|
459
|
+
const shouldRetry = await this.shouldRetry(response);
|
|
460
|
+
if (retriesRemaining && shouldRetry) {
|
|
421
461
|
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
422
|
-
|
|
423
|
-
|
|
462
|
+
|
|
463
|
+
// We don't need the body of this response.
|
|
464
|
+
await Shims.CancelReadableStream(response.body);
|
|
465
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
466
|
+
loggerFor(this).debug(
|
|
467
|
+
`[${requestLogID}] response error (${retryMessage})`,
|
|
468
|
+
formatRequestDetails({
|
|
469
|
+
retryOfRequestLogID,
|
|
470
|
+
url: response.url,
|
|
471
|
+
status: response.status,
|
|
472
|
+
headers: response.headers,
|
|
473
|
+
durationMs: headersTime - startTime,
|
|
474
|
+
}),
|
|
475
|
+
);
|
|
476
|
+
return this.retryRequest(
|
|
477
|
+
options,
|
|
478
|
+
retriesRemaining,
|
|
479
|
+
retryOfRequestLogID ?? requestLogID,
|
|
480
|
+
response.headers,
|
|
481
|
+
);
|
|
424
482
|
}
|
|
425
483
|
|
|
484
|
+
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
485
|
+
|
|
486
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
487
|
+
|
|
426
488
|
const errText = await response.text().catch((err: any) => castToError(err).message);
|
|
427
489
|
const errJSON = safeJSON(errText);
|
|
428
490
|
const errMessage = errJSON ? undefined : errText;
|
|
429
|
-
const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`;
|
|
430
491
|
|
|
431
|
-
|
|
432
|
-
`response
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
492
|
+
loggerFor(this).debug(
|
|
493
|
+
`[${requestLogID}] response error (${retryMessage})`,
|
|
494
|
+
formatRequestDetails({
|
|
495
|
+
retryOfRequestLogID,
|
|
496
|
+
url: response.url,
|
|
497
|
+
status: response.status,
|
|
498
|
+
headers: response.headers,
|
|
499
|
+
message: errMessage,
|
|
500
|
+
durationMs: Date.now() - startTime,
|
|
501
|
+
}),
|
|
437
502
|
);
|
|
438
503
|
|
|
439
504
|
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
440
505
|
throw err;
|
|
441
506
|
}
|
|
442
507
|
|
|
443
|
-
|
|
508
|
+
loggerFor(this).info(responseInfo);
|
|
509
|
+
loggerFor(this).debug(
|
|
510
|
+
`[${requestLogID}] response start`,
|
|
511
|
+
formatRequestDetails({
|
|
512
|
+
retryOfRequestLogID,
|
|
513
|
+
url: response.url,
|
|
514
|
+
status: response.status,
|
|
515
|
+
headers: response.headers,
|
|
516
|
+
durationMs: headersTime - startTime,
|
|
517
|
+
}),
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
444
521
|
}
|
|
445
522
|
|
|
446
523
|
async fetchWithTimeout(
|
|
@@ -450,11 +527,14 @@ export class Roark {
|
|
|
450
527
|
controller: AbortController,
|
|
451
528
|
): Promise<Response> {
|
|
452
529
|
const { signal, method, ...options } = init || {};
|
|
453
|
-
|
|
530
|
+
const abort = this._makeAbort(controller);
|
|
531
|
+
if (signal) signal.addEventListener('abort', abort, { once: true });
|
|
454
532
|
|
|
455
|
-
const timeout = setTimeout(
|
|
533
|
+
const timeout = setTimeout(abort, ms);
|
|
456
534
|
|
|
457
|
-
const isReadableBody =
|
|
535
|
+
const isReadableBody =
|
|
536
|
+
((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
|
|
537
|
+
(typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
|
|
458
538
|
|
|
459
539
|
const fetchOptions: RequestInit = {
|
|
460
540
|
signal: controller.signal as any,
|
|
@@ -468,15 +548,15 @@ export class Roark {
|
|
|
468
548
|
fetchOptions.method = method.toUpperCase();
|
|
469
549
|
}
|
|
470
550
|
|
|
471
|
-
|
|
551
|
+
try {
|
|
472
552
|
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
|
|
473
|
-
this.fetch.call(undefined, url, fetchOptions)
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
553
|
+
return await this.fetch.call(undefined, url, fetchOptions);
|
|
554
|
+
} finally {
|
|
555
|
+
clearTimeout(timeout);
|
|
556
|
+
}
|
|
477
557
|
}
|
|
478
558
|
|
|
479
|
-
private shouldRetry(response: Response): boolean {
|
|
559
|
+
private async shouldRetry(response: Response): Promise<boolean> {
|
|
480
560
|
// Note this is not a standard header.
|
|
481
561
|
const shouldRetryHeader = response.headers.get('x-should-retry');
|
|
482
562
|
|
|
@@ -502,6 +582,7 @@ export class Roark {
|
|
|
502
582
|
private async retryRequest(
|
|
503
583
|
options: FinalRequestOptions,
|
|
504
584
|
retriesRemaining: number,
|
|
585
|
+
requestLogID: string,
|
|
505
586
|
responseHeaders?: Headers | undefined,
|
|
506
587
|
): Promise<APIResponseProps> {
|
|
507
588
|
let timeoutMillis: number | undefined;
|
|
@@ -534,7 +615,7 @@ export class Roark {
|
|
|
534
615
|
}
|
|
535
616
|
await sleep(timeoutMillis);
|
|
536
617
|
|
|
537
|
-
return this.makeRequest(options, retriesRemaining - 1);
|
|
618
|
+
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
538
619
|
}
|
|
539
620
|
|
|
540
621
|
private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
|
|
@@ -552,17 +633,18 @@ export class Roark {
|
|
|
552
633
|
return sleepSeconds * jitter * 1000;
|
|
553
634
|
}
|
|
554
635
|
|
|
555
|
-
buildRequest(
|
|
556
|
-
|
|
636
|
+
async buildRequest(
|
|
637
|
+
inputOptions: FinalRequestOptions,
|
|
557
638
|
{ retryCount = 0 }: { retryCount?: number } = {},
|
|
558
|
-
): { req: FinalizedRequestInit; url: string; timeout: number } {
|
|
559
|
-
const
|
|
639
|
+
): Promise<{ req: FinalizedRequestInit; url: string; timeout: number }> {
|
|
640
|
+
const options = { ...inputOptions };
|
|
641
|
+
const { method, path, query, defaultBaseURL } = options;
|
|
560
642
|
|
|
561
|
-
const url = this.buildURL(path!, query as Record<string, unknown
|
|
643
|
+
const url = this.buildURL(path!, query as Record<string, unknown>, defaultBaseURL);
|
|
562
644
|
if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
|
|
563
|
-
|
|
645
|
+
options.timeout = options.timeout ?? this.timeout;
|
|
564
646
|
const { bodyHeaders, body } = this.buildBody({ options });
|
|
565
|
-
const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount });
|
|
647
|
+
const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
|
|
566
648
|
|
|
567
649
|
const req: FinalizedRequestInit = {
|
|
568
650
|
method,
|
|
@@ -575,10 +657,10 @@ export class Roark {
|
|
|
575
657
|
...((options.fetchOptions as any) ?? {}),
|
|
576
658
|
};
|
|
577
659
|
|
|
578
|
-
return { req, url, timeout };
|
|
660
|
+
return { req, url, timeout: options.timeout };
|
|
579
661
|
}
|
|
580
662
|
|
|
581
|
-
private buildHeaders({
|
|
663
|
+
private async buildHeaders({
|
|
582
664
|
options,
|
|
583
665
|
method,
|
|
584
666
|
bodyHeaders,
|
|
@@ -588,7 +670,7 @@ export class Roark {
|
|
|
588
670
|
method: HTTPMethod;
|
|
589
671
|
bodyHeaders: HeadersLike;
|
|
590
672
|
retryCount: number;
|
|
591
|
-
}): Headers {
|
|
673
|
+
}): Promise<Headers> {
|
|
592
674
|
let idempotencyHeaders: HeadersLike = {};
|
|
593
675
|
if (this.idempotencyHeader && method !== 'get') {
|
|
594
676
|
if (!options.idempotencyKey) options.idempotencyKey = this.defaultIdempotencyKey();
|
|
@@ -601,9 +683,10 @@ export class Roark {
|
|
|
601
683
|
Accept: 'application/json',
|
|
602
684
|
'User-Agent': this.getUserAgent(),
|
|
603
685
|
'X-Stainless-Retry-Count': String(retryCount),
|
|
686
|
+
...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
|
|
604
687
|
...getPlatformHeaders(),
|
|
605
688
|
},
|
|
606
|
-
this.authHeaders(options),
|
|
689
|
+
await this.authHeaders(options),
|
|
607
690
|
this._options.defaultHeaders,
|
|
608
691
|
bodyHeaders,
|
|
609
692
|
options.headers,
|
|
@@ -614,6 +697,12 @@ export class Roark {
|
|
|
614
697
|
return headers.values;
|
|
615
698
|
}
|
|
616
699
|
|
|
700
|
+
private _makeAbort(controller: AbortController) {
|
|
701
|
+
// note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
|
|
702
|
+
// would capture all request options, and cause a memory leak.
|
|
703
|
+
return () => controller.abort();
|
|
704
|
+
}
|
|
705
|
+
|
|
617
706
|
private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
|
|
618
707
|
bodyHeaders: HeadersLike;
|
|
619
708
|
body: BodyInit | undefined;
|
|
@@ -631,7 +720,7 @@ export class Roark {
|
|
|
631
720
|
// Preserve legacy string encoding behavior for now
|
|
632
721
|
headers.values.has('content-type')) ||
|
|
633
722
|
// `Blob` is superset of `File`
|
|
634
|
-
body instanceof Blob ||
|
|
723
|
+
((globalThis as any).Blob && body instanceof (globalThis as any).Blob) ||
|
|
635
724
|
// `FormData` -> `multipart/form-data`
|
|
636
725
|
body instanceof FormData ||
|
|
637
726
|
// `URLSearchParams` -> `application/x-www-form-urlencoded`
|
|
@@ -678,6 +767,7 @@ export class Roark {
|
|
|
678
767
|
simulation: API.Simulation = new API.Simulation(this);
|
|
679
768
|
persona: API.Persona = new API.Persona(this);
|
|
680
769
|
}
|
|
770
|
+
|
|
681
771
|
Roark.Health = Health;
|
|
682
772
|
Roark.Evaluation = Evaluation;
|
|
683
773
|
Roark.Call = Call;
|
|
@@ -685,6 +775,7 @@ Roark.Metric = Metric;
|
|
|
685
775
|
Roark.Integrations = Integrations;
|
|
686
776
|
Roark.Simulation = Simulation;
|
|
687
777
|
Roark.Persona = Persona;
|
|
778
|
+
|
|
688
779
|
export declare namespace Roark {
|
|
689
780
|
export type RequestOptions = Opts.RequestOptions;
|
|
690
781
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { type Roark } from '../client';
|
|
4
|
+
|
|
5
|
+
import { type PromiseOrValue } from '../internal/types';
|
|
6
|
+
import { APIResponseProps, defaultParseResponse } from '../internal/parse';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A subclass of `Promise` providing additional helper methods
|
|
10
|
+
* for interacting with the SDK.
|
|
11
|
+
*/
|
|
12
|
+
export class APIPromise<T> extends Promise<T> {
|
|
13
|
+
private parsedPromise: Promise<T> | undefined;
|
|
14
|
+
#client: Roark;
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
client: Roark,
|
|
18
|
+
private responsePromise: Promise<APIResponseProps>,
|
|
19
|
+
private parseResponse: (
|
|
20
|
+
client: Roark,
|
|
21
|
+
props: APIResponseProps,
|
|
22
|
+
) => PromiseOrValue<T> = defaultParseResponse,
|
|
23
|
+
) {
|
|
24
|
+
super((resolve) => {
|
|
25
|
+
// this is maybe a bit weird but this has to be a no-op to not implicitly
|
|
26
|
+
// parse the response body; instead .then, .catch, .finally are overridden
|
|
27
|
+
// to parse the response
|
|
28
|
+
resolve(null as any);
|
|
29
|
+
});
|
|
30
|
+
this.#client = client;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
|
|
34
|
+
return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
|
|
35
|
+
transform(await this.parseResponse(client, props), props),
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets the raw `Response` instance instead of parsing the response
|
|
41
|
+
* data.
|
|
42
|
+
*
|
|
43
|
+
* If you want to parse the response body but still get the `Response`
|
|
44
|
+
* instance, you can use {@link withResponse()}.
|
|
45
|
+
*
|
|
46
|
+
* 👋 Getting the wrong TypeScript type for `Response`?
|
|
47
|
+
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
|
|
48
|
+
* to your `tsconfig.json`.
|
|
49
|
+
*/
|
|
50
|
+
asResponse(): Promise<Response> {
|
|
51
|
+
return this.responsePromise.then((p) => p.response);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets the parsed response data and the raw `Response` instance.
|
|
56
|
+
*
|
|
57
|
+
* If you just want to get the raw `Response` instance without parsing it,
|
|
58
|
+
* you can use {@link asResponse()}.
|
|
59
|
+
*
|
|
60
|
+
* 👋 Getting the wrong TypeScript type for `Response`?
|
|
61
|
+
* Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
|
|
62
|
+
* to your `tsconfig.json`.
|
|
63
|
+
*/
|
|
64
|
+
async withResponse(): Promise<{ data: T; response: Response }> {
|
|
65
|
+
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
|
|
66
|
+
return { data, response };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private parse(): Promise<T> {
|
|
70
|
+
if (!this.parsedPromise) {
|
|
71
|
+
this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
|
|
72
|
+
}
|
|
73
|
+
return this.parsedPromise;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override then<TResult1 = T, TResult2 = never>(
|
|
77
|
+
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
|
|
78
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
|
|
79
|
+
): Promise<TResult1 | TResult2> {
|
|
80
|
+
return this.parse().then(onfulfilled, onrejected);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override catch<TResult = never>(
|
|
84
|
+
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
|
|
85
|
+
): Promise<T | TResult> {
|
|
86
|
+
return this.parse().catch(onrejected);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
|
|
90
|
+
return this.parse().finally(onfinally);
|
|
91
|
+
}
|
|
92
|
+
}
|