@predictorsdk/client 0.11.0 → 0.13.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.
Files changed (40) hide show
  1. package/README.md +6 -4
  2. package/dist/BaseClient.d.ts +12 -0
  3. package/dist/Client.d.ts +23 -1
  4. package/dist/Client.js +55 -1
  5. package/dist/api/client/requests/GetMarketsRequest.d.ts +1 -1
  6. package/dist/api/errors/BadGatewayError.js +1 -1
  7. package/dist/api/errors/BadRequestError.js +1 -1
  8. package/dist/api/errors/ForbiddenError.js +1 -1
  9. package/dist/api/errors/NotFoundError.js +1 -1
  10. package/dist/api/errors/PaymentRequiredError.js +1 -1
  11. package/dist/api/errors/ServiceUnavailableError.js +1 -1
  12. package/dist/api/errors/TooManyRequestsError.js +1 -1
  13. package/dist/api/errors/UnauthorizedError.js +1 -1
  14. package/dist/api/types/PaymentRequiredErrorAction.d.ts +1 -1
  15. package/dist/api/types/PaymentRequiredErrorAction.js +1 -1
  16. package/dist/api/types/PaymentRequiredErrorBody.d.ts +0 -1
  17. package/dist/api/types/PlatformMarket.d.ts +2 -0
  18. package/dist/core/fetcher/Fetcher.js +1 -84
  19. package/dist/core/fetcher/getResponseBody.js +11 -0
  20. package/dist/core/fetcher/makePassthroughRequest.js +26 -4
  21. package/dist/core/fetcher/redactUrl.d.ts +2 -0
  22. package/dist/core/fetcher/redactUrl.js +84 -0
  23. package/dist/core/fetcher/requestWithRetries.js +2 -2
  24. package/dist/core/fetcher/signals.js +9 -1
  25. package/dist/core/requestBody.d.ts +12 -0
  26. package/dist/core/requestBody.js +23 -0
  27. package/dist/core/runtime/index.d.ts +1 -1
  28. package/dist/core/runtime/index.js +1 -1
  29. package/dist/core/runtime/runtime.d.ts +19 -0
  30. package/dist/core/runtime/runtime.js +71 -0
  31. package/dist/core/schemas/builders/schema-utils/JsonError.js +2 -2
  32. package/dist/core/schemas/builders/schema-utils/ParseError.js +2 -2
  33. package/dist/core/url/qs.js +2 -2
  34. package/dist/errors/PredictorSDKError.d.ts +1 -0
  35. package/dist/errors/PredictorSDKError.js +4 -1
  36. package/dist/errors/PredictorSDKTimeoutError.d.ts +2 -2
  37. package/dist/errors/PredictorSDKTimeoutError.js +7 -7
  38. package/dist/serialization/types/PlatformMarket.d.ts +1 -0
  39. package/dist/serialization/types/PlatformMarket.js +1 -0
  40. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @predictorsdk/client
2
2
 
3
- The official TypeScript/JavaScript client for the [PredictorSDK](https://predictorsdk.com) matching markets API.
3
+ The official TypeScript/JavaScript client for the [PredictorSDK](https://predictorsdk.com) prediction-market data API.
4
4
 
5
5
  ## Installation
6
6
 
@@ -15,9 +15,11 @@ import { PredictorSDKClient } from "@predictorsdk/client";
15
15
 
16
16
  const client = new PredictorSDKClient({ token: "your-api-key" });
17
17
 
18
- const { markets } = await client.getSportsMatchingMarkets({
19
- kalshiEventTicker: "KXMLB-25-NYM-COL-2025-04-03",
20
- });
18
+ const plans = await client.getPlans();
19
+ const categories = await client.getCategories();
20
+ const markets = await client.getMarkets({ limit: 10, category: "sports" });
21
+
22
+ console.log(plans.data, categories.data, markets.data);
21
23
  ```
22
24
 
23
25
  ## Documentation
@@ -16,6 +16,11 @@ export type BaseClientOptions = {
16
16
  fetch?: typeof fetch;
17
17
  /** Configure logging for the client. */
18
18
  logging?: core.logging.LogConfig | core.logging.Logger;
19
+ /** Default options for SSE stream reconnection behavior. Has no effect on non-resumable endpoints. */
20
+ stream?: {
21
+ reconnectionEnabled?: boolean;
22
+ maxReconnectionAttempts?: number;
23
+ };
19
24
  /** Override auth. Pass false to disable, a function returning auth headers, an AuthProvider, or auth options. */
20
25
  auth?: AuthOption;
21
26
  } & BearerAuthProvider.AuthOptions;
@@ -28,8 +33,15 @@ export interface BaseRequestOptions {
28
33
  abortSignal?: AbortSignal;
29
34
  /** Additional query string parameters to include in the request. */
30
35
  queryParams?: Record<string, unknown>;
36
+ /** A dictionary containing additional parameters to spread into the request's body. */
37
+ additionalBodyParameters?: Record<string, unknown>;
31
38
  /** Additional headers to include in the request. */
32
39
  headers?: Record<string, string | core.Supplier<string | null | undefined> | null | undefined>;
40
+ /** Options for SSE stream reconnection behavior. Has no effect on non-resumable endpoints. */
41
+ stream?: {
42
+ reconnectionEnabled?: boolean;
43
+ maxReconnectionAttempts?: number;
44
+ };
33
45
  }
34
46
  export type NormalizedClientOptions<T extends BaseClientOptions = BaseClientOptions> = T & {
35
47
  logging: core.logging.Logger;
package/dist/Client.d.ts CHANGED
@@ -16,6 +16,8 @@ export declare class PredictorSDKClient {
16
16
  * @param {PredictorSDKClient.RequestOptions} requestOptions - Request-specific configuration.
17
17
  *
18
18
  * @throws {@link PredictorSDK.ServiceUnavailableError}
19
+ * @throws {@link errors.PredictorSDKError}
20
+ * @throws {@link errors.PredictorSDKTimeoutError}
19
21
  *
20
22
  * @example
21
23
  * await client.getPlans()
@@ -23,7 +25,7 @@ export declare class PredictorSDKClient {
23
25
  getPlans(requestOptions?: PredictorSDKClient.RequestOptions): core.HttpResponsePromise<PredictorSDK.PlansResponse>;
24
26
  private __getPlans;
25
27
  /**
26
- * Find cross-platform market matches for sports events. When called without parameters, returns all currently matched sports markets with cursor-based pagination (default `limit=25`, max `100`). Provide a canonical event key, Kalshi event ticker, Polymarket slug, Predict market ID, or SX Bet market ID to look up a specific event — lookups return the full match immediately and skip pagination.
28
+ * Find cross-platform market matches for sports events. When called without parameters, returns all currently matched sports markets with cursor-based pagination (default `limit=25`, max `100`). Provide a canonical event key, Kalshi event ticker, Polymarket slug, Predict market ID, or SX Bet market ID to look up a specific event — lookups return the full match immediately and skip pagination. Every platform row includes its provider-native `event_id` for use with `GET /v1/events/{event_id}`; pass that row's `platform` value as the events endpoint's `platform` query parameter, which is required to disambiguate Predict and AlphaArcade identifiers.
27
29
  *
28
30
  * @param {PredictorSDK.GetSportsMatchingMarketsRequest} request
29
31
  * @param {PredictorSDKClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -33,7 +35,10 @@ export declare class PredictorSDKClient {
33
35
  * @throws {@link PredictorSDK.PaymentRequiredError}
34
36
  * @throws {@link PredictorSDK.ForbiddenError}
35
37
  * @throws {@link PredictorSDK.TooManyRequestsError}
38
+ * @throws {@link PredictorSDK.BadGatewayError}
36
39
  * @throws {@link PredictorSDK.ServiceUnavailableError}
40
+ * @throws {@link errors.PredictorSDKError}
41
+ * @throws {@link errors.PredictorSDKTimeoutError}
37
42
  *
38
43
  * @example
39
44
  * await client.getSportsMatchingMarkets()
@@ -51,7 +56,10 @@ export declare class PredictorSDKClient {
51
56
  * @throws {@link PredictorSDK.PaymentRequiredError}
52
57
  * @throws {@link PredictorSDK.ForbiddenError}
53
58
  * @throws {@link PredictorSDK.TooManyRequestsError}
59
+ * @throws {@link PredictorSDK.BadGatewayError}
54
60
  * @throws {@link PredictorSDK.ServiceUnavailableError}
61
+ * @throws {@link errors.PredictorSDKError}
62
+ * @throws {@link errors.PredictorSDKTimeoutError}
55
63
  *
56
64
  * @example
57
65
  * await client.getMarkets()
@@ -67,6 +75,10 @@ export declare class PredictorSDKClient {
67
75
  * @throws {@link PredictorSDK.PaymentRequiredError}
68
76
  * @throws {@link PredictorSDK.ForbiddenError}
69
77
  * @throws {@link PredictorSDK.TooManyRequestsError}
78
+ * @throws {@link PredictorSDK.BadGatewayError}
79
+ * @throws {@link PredictorSDK.ServiceUnavailableError}
80
+ * @throws {@link errors.PredictorSDKError}
81
+ * @throws {@link errors.PredictorSDKTimeoutError}
70
82
  *
71
83
  * @example
72
84
  * await client.getCategories()
@@ -91,6 +103,8 @@ export declare class PredictorSDKClient {
91
103
  * @throws {@link PredictorSDK.TooManyRequestsError}
92
104
  * @throws {@link PredictorSDK.BadGatewayError}
93
105
  * @throws {@link PredictorSDK.ServiceUnavailableError}
106
+ * @throws {@link errors.PredictorSDKError}
107
+ * @throws {@link errors.PredictorSDKTimeoutError}
94
108
  *
95
109
  * @example
96
110
  * await client.getMarket({
@@ -112,6 +126,8 @@ export declare class PredictorSDKClient {
112
126
  * @throws {@link PredictorSDK.TooManyRequestsError}
113
127
  * @throws {@link PredictorSDK.BadGatewayError}
114
128
  * @throws {@link PredictorSDK.ServiceUnavailableError}
129
+ * @throws {@link errors.PredictorSDKError}
130
+ * @throws {@link errors.PredictorSDKTimeoutError}
115
131
  *
116
132
  * @example
117
133
  * await client.getBinanceCryptoPrices({
@@ -138,6 +154,8 @@ export declare class PredictorSDKClient {
138
154
  * @throws {@link PredictorSDK.TooManyRequestsError}
139
155
  * @throws {@link PredictorSDK.BadGatewayError}
140
156
  * @throws {@link PredictorSDK.ServiceUnavailableError}
157
+ * @throws {@link errors.PredictorSDKError}
158
+ * @throws {@link errors.PredictorSDKTimeoutError}
141
159
  *
142
160
  * @example
143
161
  * await client.getPolymarketWallet({
@@ -166,6 +184,8 @@ export declare class PredictorSDKClient {
166
184
  * @throws {@link PredictorSDK.TooManyRequestsError}
167
185
  * @throws {@link PredictorSDK.BadGatewayError}
168
186
  * @throws {@link PredictorSDK.ServiceUnavailableError}
187
+ * @throws {@link errors.PredictorSDKError}
188
+ * @throws {@link errors.PredictorSDKTimeoutError}
169
189
  *
170
190
  * @example
171
191
  * await client.listPolymarketWalletPositions({
@@ -194,6 +214,8 @@ export declare class PredictorSDKClient {
194
214
  * @throws {@link PredictorSDK.TooManyRequestsError}
195
215
  * @throws {@link PredictorSDK.BadGatewayError}
196
216
  * @throws {@link PredictorSDK.ServiceUnavailableError}
217
+ * @throws {@link errors.PredictorSDKError}
218
+ * @throws {@link errors.PredictorSDKTimeoutError}
197
219
  *
198
220
  * @example
199
221
  * await client.getEvent({
package/dist/Client.js CHANGED
@@ -18,6 +18,8 @@ export class PredictorSDKClient {
18
18
  * @param {PredictorSDKClient.RequestOptions} requestOptions - Request-specific configuration.
19
19
  *
20
20
  * @throws {@link PredictorSDK.ServiceUnavailableError}
21
+ * @throws {@link errors.PredictorSDKError}
22
+ * @throws {@link errors.PredictorSDKTimeoutError}
21
23
  *
22
24
  * @example
23
25
  * await client.getPlans()
@@ -73,7 +75,7 @@ export class PredictorSDKClient {
73
75
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/plans");
74
76
  }
75
77
  /**
76
- * Find cross-platform market matches for sports events. When called without parameters, returns all currently matched sports markets with cursor-based pagination (default `limit=25`, max `100`). Provide a canonical event key, Kalshi event ticker, Polymarket slug, Predict market ID, or SX Bet market ID to look up a specific event — lookups return the full match immediately and skip pagination.
78
+ * Find cross-platform market matches for sports events. When called without parameters, returns all currently matched sports markets with cursor-based pagination (default `limit=25`, max `100`). Provide a canonical event key, Kalshi event ticker, Polymarket slug, Predict market ID, or SX Bet market ID to look up a specific event — lookups return the full match immediately and skip pagination. Every platform row includes its provider-native `event_id` for use with `GET /v1/events/{event_id}`; pass that row's `platform` value as the events endpoint's `platform` query parameter, which is required to disambiguate Predict and AlphaArcade identifiers.
77
79
  *
78
80
  * @param {PredictorSDK.GetSportsMatchingMarketsRequest} request
79
81
  * @param {PredictorSDKClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -83,7 +85,10 @@ export class PredictorSDKClient {
83
85
  * @throws {@link PredictorSDK.PaymentRequiredError}
84
86
  * @throws {@link PredictorSDK.ForbiddenError}
85
87
  * @throws {@link PredictorSDK.TooManyRequestsError}
88
+ * @throws {@link PredictorSDK.BadGatewayError}
86
89
  * @throws {@link PredictorSDK.ServiceUnavailableError}
90
+ * @throws {@link errors.PredictorSDKError}
91
+ * @throws {@link errors.PredictorSDKTimeoutError}
87
92
  *
88
93
  * @example
89
94
  * await client.getSportsMatchingMarkets()
@@ -177,6 +182,14 @@ export class PredictorSDKClient {
177
182
  skipValidation: true,
178
183
  breadcrumbsPrefix: ["response"],
179
184
  }), _response.rawResponse);
185
+ case 502:
186
+ throw new PredictorSDK.BadGatewayError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
187
+ unrecognizedObjectKeys: "passthrough",
188
+ allowUnrecognizedUnionMembers: true,
189
+ allowUnrecognizedEnumValues: true,
190
+ skipValidation: true,
191
+ breadcrumbsPrefix: ["response"],
192
+ }), _response.rawResponse);
180
193
  case 503:
181
194
  throw new PredictorSDK.ServiceUnavailableError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
182
195
  unrecognizedObjectKeys: "passthrough",
@@ -206,7 +219,10 @@ export class PredictorSDKClient {
206
219
  * @throws {@link PredictorSDK.PaymentRequiredError}
207
220
  * @throws {@link PredictorSDK.ForbiddenError}
208
221
  * @throws {@link PredictorSDK.TooManyRequestsError}
222
+ * @throws {@link PredictorSDK.BadGatewayError}
209
223
  * @throws {@link PredictorSDK.ServiceUnavailableError}
224
+ * @throws {@link errors.PredictorSDKError}
225
+ * @throws {@link errors.PredictorSDKTimeoutError}
210
226
  *
211
227
  * @example
212
228
  * await client.getMarkets()
@@ -299,6 +315,14 @@ export class PredictorSDKClient {
299
315
  skipValidation: true,
300
316
  breadcrumbsPrefix: ["response"],
301
317
  }), _response.rawResponse);
318
+ case 502:
319
+ throw new PredictorSDK.BadGatewayError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
320
+ unrecognizedObjectKeys: "passthrough",
321
+ allowUnrecognizedUnionMembers: true,
322
+ allowUnrecognizedEnumValues: true,
323
+ skipValidation: true,
324
+ breadcrumbsPrefix: ["response"],
325
+ }), _response.rawResponse);
302
326
  case 503:
303
327
  throw new PredictorSDK.ServiceUnavailableError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
304
328
  unrecognizedObjectKeys: "passthrough",
@@ -326,6 +350,10 @@ export class PredictorSDKClient {
326
350
  * @throws {@link PredictorSDK.PaymentRequiredError}
327
351
  * @throws {@link PredictorSDK.ForbiddenError}
328
352
  * @throws {@link PredictorSDK.TooManyRequestsError}
353
+ * @throws {@link PredictorSDK.BadGatewayError}
354
+ * @throws {@link PredictorSDK.ServiceUnavailableError}
355
+ * @throws {@link errors.PredictorSDKError}
356
+ * @throws {@link errors.PredictorSDKTimeoutError}
329
357
  *
330
358
  * @example
331
359
  * await client.getCategories()
@@ -395,6 +423,22 @@ export class PredictorSDKClient {
395
423
  skipValidation: true,
396
424
  breadcrumbsPrefix: ["response"],
397
425
  }), _response.rawResponse);
426
+ case 502:
427
+ throw new PredictorSDK.BadGatewayError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
428
+ unrecognizedObjectKeys: "passthrough",
429
+ allowUnrecognizedUnionMembers: true,
430
+ allowUnrecognizedEnumValues: true,
431
+ skipValidation: true,
432
+ breadcrumbsPrefix: ["response"],
433
+ }), _response.rawResponse);
434
+ case 503:
435
+ throw new PredictorSDK.ServiceUnavailableError(serializers.ErrorResponse.parseOrThrow(_response.error.body, {
436
+ unrecognizedObjectKeys: "passthrough",
437
+ allowUnrecognizedUnionMembers: true,
438
+ allowUnrecognizedEnumValues: true,
439
+ skipValidation: true,
440
+ breadcrumbsPrefix: ["response"],
441
+ }), _response.rawResponse);
398
442
  default:
399
443
  throw new errors.PredictorSDKError({
400
444
  statusCode: _response.error.statusCode,
@@ -423,6 +467,8 @@ export class PredictorSDKClient {
423
467
  * @throws {@link PredictorSDK.TooManyRequestsError}
424
468
  * @throws {@link PredictorSDK.BadGatewayError}
425
469
  * @throws {@link PredictorSDK.ServiceUnavailableError}
470
+ * @throws {@link errors.PredictorSDKError}
471
+ * @throws {@link errors.PredictorSDKTimeoutError}
426
472
  *
427
473
  * @example
428
474
  * await client.getMarket({
@@ -562,6 +608,8 @@ export class PredictorSDKClient {
562
608
  * @throws {@link PredictorSDK.TooManyRequestsError}
563
609
  * @throws {@link PredictorSDK.BadGatewayError}
564
610
  * @throws {@link PredictorSDK.ServiceUnavailableError}
611
+ * @throws {@link errors.PredictorSDKError}
612
+ * @throws {@link errors.PredictorSDKTimeoutError}
565
613
  *
566
614
  * @example
567
615
  * await client.getBinanceCryptoPrices({
@@ -697,6 +745,8 @@ export class PredictorSDKClient {
697
745
  * @throws {@link PredictorSDK.TooManyRequestsError}
698
746
  * @throws {@link PredictorSDK.BadGatewayError}
699
747
  * @throws {@link PredictorSDK.ServiceUnavailableError}
748
+ * @throws {@link errors.PredictorSDKError}
749
+ * @throws {@link errors.PredictorSDKTimeoutError}
700
750
  *
701
751
  * @example
702
752
  * await client.getPolymarketWallet({
@@ -839,6 +889,8 @@ export class PredictorSDKClient {
839
889
  * @throws {@link PredictorSDK.TooManyRequestsError}
840
890
  * @throws {@link PredictorSDK.BadGatewayError}
841
891
  * @throws {@link PredictorSDK.ServiceUnavailableError}
892
+ * @throws {@link errors.PredictorSDKError}
893
+ * @throws {@link errors.PredictorSDKTimeoutError}
842
894
  *
843
895
  * @example
844
896
  * await client.listPolymarketWalletPositions({
@@ -983,6 +1035,8 @@ export class PredictorSDKClient {
983
1035
  * @throws {@link PredictorSDK.TooManyRequestsError}
984
1036
  * @throws {@link PredictorSDK.BadGatewayError}
985
1037
  * @throws {@link PredictorSDK.ServiceUnavailableError}
1038
+ * @throws {@link errors.PredictorSDKError}
1039
+ * @throws {@link errors.PredictorSDKTimeoutError}
986
1040
  *
987
1041
  * @example
988
1042
  * await client.getEvent({
@@ -6,7 +6,7 @@ import type * as PredictorSDK from "../../index.js";
6
6
  export interface GetMarketsRequest {
7
7
  /** Maximum number of markets to return per page. Range 1–100, default 25. */
8
8
  limit?: number;
9
- /** Opaque cursor from a previous response's `pagination.nextCursor` in the SDKs (raw JSON: `pagination.next_cursor`). */
9
+ /** Opaque cursor from a previous response's `pagination.nextCursor` in the SDKs (raw JSON: `pagination.next_cursor`). Market cursors stay bound to the immutable catalog snapshot that issued them. Replaced snapshots normally remain available for up to 24 hours, but storage pressure can evict a retained snapshot sooner; retry from the first page after a stale-cursor `400`. */
10
10
  cursor?: string;
11
11
  /** Canonical top-level category filter. This is PredictorSDK's normalized category, not a provider-native tag. Cursors are bound to the category filter used to create them. */
12
12
  category?: PredictorSDK.MarketCategory;
@@ -12,6 +12,6 @@ export class BadGatewayError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "BadGatewayError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class BadRequestError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "BadRequestError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class ForbiddenError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "ForbiddenError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class NotFoundError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "NotFoundError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class PaymentRequiredError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "PaymentRequiredError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class ServiceUnavailableError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "ServiceUnavailableError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class TooManyRequestsError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "TooManyRequestsError";
16
16
  }
17
17
  }
@@ -12,6 +12,6 @@ export class UnauthorizedError extends errors.PredictorSDKError {
12
12
  if (Error.captureStackTrace) {
13
13
  Error.captureStackTrace(this, this.constructor);
14
14
  }
15
- this.name = this.constructor.name;
15
+ this.name = "UnauthorizedError";
16
16
  }
17
17
  }
@@ -1,4 +1,4 @@
1
- /** Recommended client action for this 402. */
1
+ /** Recommended client action for an HTTP 402 response. */
2
2
  export declare const PaymentRequiredErrorAction: {
3
3
  readonly UpgradePlan: "upgrade_plan";
4
4
  readonly ResolvePayment: "resolve_payment";
@@ -1,5 +1,5 @@
1
1
  // This file was auto-generated by Fern from our API Definition.
2
- /** Recommended client action for this 402. */
2
+ /** Recommended client action for an HTTP 402 response. */
3
3
  export const PaymentRequiredErrorAction = {
4
4
  UpgradePlan: "upgrade_plan",
5
5
  ResolvePayment: "resolve_payment",
@@ -7,7 +7,6 @@ export interface PaymentRequiredErrorBody {
7
7
  /** Additional detail about the error. */
8
8
  message?: string;
9
9
  statusCode: number;
10
- /** Recommended client action for this 402. */
11
10
  action: PredictorSDK.PaymentRequiredErrorAction;
12
11
  /** Billing tier that would satisfy the gate (e.g. `starter`, `pro`, `business`, `enterprise`). */
13
12
  requiredTier: string;
@@ -1,6 +1,8 @@
1
1
  import type * as PredictorSDK from "../index.js";
2
2
  export interface PlatformMarket {
3
3
  platform: PredictorSDK.PlatformMarketPlatform;
4
+ /** Provider-native parent event or fixture identifier for the path in `GET /v1/events/{event_id}`. Kalshi uses its event ticker, Polymarket its event slug (or numeric event ID fallback), Predict its market ID, SX Bet its `L...` fixture ID, and AlphaArcade its parent market ULID. Always pair it with the events endpoint's `platform` query parameter, passing this row's `platform` value (matched case-insensitively). Predict market IDs and AlphaArcade ULIDs are not shape-distinguishable from Polymarket identifiers, so without that override the events endpoint probes Polymarket first and can answer `200` with an unrelated Polymarket event instead of `404`. Retained snapshots created before this field was introduced may omit it. */
5
+ eventId?: string;
4
6
  /** Kalshi event ticker. Present when platform is KALSHI. */
5
7
  eventTicker?: string;
6
8
  /** Kalshi market tickers. Present when platform is KALSHI. */
@@ -9,6 +9,7 @@ import { getResponseBody } from "./getResponseBody.js";
9
9
  import { Headers } from "./Headers.js";
10
10
  import { makeRequest } from "./makeRequest.js";
11
11
  import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js";
12
+ import { redactUrl, SENSITIVE_QUERY_PARAMS } from "./redactUrl.js";
12
13
  import { requestWithRetries } from "./requestWithRetries.js";
13
14
  const SENSITIVE_HEADERS = new Set([
14
15
  "authorization",
@@ -40,26 +41,6 @@ function redactHeaders(headers) {
40
41
  }
41
42
  return filtered;
42
43
  }
43
- const SENSITIVE_QUERY_PARAMS = new Set([
44
- "api_key",
45
- "api-key",
46
- "apikey",
47
- "token",
48
- "access_token",
49
- "access-token",
50
- "auth_token",
51
- "auth-token",
52
- "password",
53
- "passwd",
54
- "secret",
55
- "api_secret",
56
- "api-secret",
57
- "apisecret",
58
- "key",
59
- "session",
60
- "session_id",
61
- "session-id",
62
- ]);
63
44
  function redactQueryParameters(queryParameters) {
64
45
  if (queryParameters == null) {
65
46
  return undefined;
@@ -70,70 +51,6 @@ function redactQueryParameters(queryParameters) {
70
51
  }
71
52
  return redacted;
72
53
  }
73
- function redactUrl(url) {
74
- const protocolIndex = url.indexOf("://");
75
- if (protocolIndex === -1)
76
- return url;
77
- const afterProtocol = protocolIndex + 3;
78
- // Find the first delimiter that marks the end of the authority section
79
- const pathStart = url.indexOf("/", afterProtocol);
80
- let queryStart = url.indexOf("?", afterProtocol);
81
- let fragmentStart = url.indexOf("#", afterProtocol);
82
- const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
83
- // Find the LAST @ before the delimiter (handles multiple @ in credentials)
84
- let atIndex = -1;
85
- for (let i = afterProtocol; i < firstDelimiter; i++) {
86
- if (url[i] === "@") {
87
- atIndex = i;
88
- }
89
- }
90
- if (atIndex !== -1) {
91
- url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
92
- }
93
- // Recalculate queryStart since url might have changed
94
- queryStart = url.indexOf("?");
95
- if (queryStart === -1)
96
- return url;
97
- fragmentStart = url.indexOf("#", queryStart);
98
- const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length;
99
- const queryString = url.slice(queryStart + 1, queryEnd);
100
- if (queryString.length === 0)
101
- return url;
102
- // FAST PATH: Quick check if any sensitive keywords present
103
- // Using indexOf is faster than regex for simple substring matching
104
- const lower = queryString.toLowerCase();
105
- const hasSensitive = lower.includes("token") ||
106
- lower.includes("key") ||
107
- lower.includes("password") ||
108
- lower.includes("passwd") ||
109
- lower.includes("secret") ||
110
- lower.includes("session") ||
111
- lower.includes("auth");
112
- if (!hasSensitive) {
113
- return url;
114
- }
115
- // SLOW PATH: Parse and redact
116
- const redactedParams = [];
117
- const params = queryString.split("&");
118
- for (const param of params) {
119
- const equalIndex = param.indexOf("=");
120
- if (equalIndex === -1) {
121
- redactedParams.push(param);
122
- continue;
123
- }
124
- const key = param.slice(0, equalIndex);
125
- let shouldRedact = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase());
126
- if (!shouldRedact && key.includes("%")) {
127
- try {
128
- const decodedKey = decodeURIComponent(key);
129
- shouldRedact = SENSITIVE_QUERY_PARAMS.has(decodedKey.toLowerCase());
130
- }
131
- catch { }
132
- }
133
- redactedParams.push(shouldRedact ? `${key}=[REDACTED]` : param);
134
- }
135
- return url.slice(0, queryStart + 1) + redactedParams.join("&") + url.slice(queryEnd);
136
- }
137
54
  async function getHeaders(args) {
138
55
  const newHeaders = new Headers();
139
56
  newHeaders.set("Accept", args.responseType === "json"
@@ -1,5 +1,14 @@
1
1
  import { fromJson } from "../json.js";
2
2
  import { getBinaryResponse } from "./BinaryResponse.js";
3
+ // Pins the upstream Response so undici's FinalizationRegistry can't GC it and cancel the body stream.
4
+ function retainResponse(target, response) {
5
+ Object.defineProperty(target, "__fern_response_ref", {
6
+ value: response,
7
+ enumerable: false,
8
+ configurable: true,
9
+ writable: false,
10
+ });
11
+ }
3
12
  export async function getResponseBody(response, responseType) {
4
13
  switch (responseType) {
5
14
  case "binary-response":
@@ -18,6 +27,7 @@ export async function getResponseBody(response, responseType) {
18
27
  },
19
28
  };
20
29
  }
30
+ retainResponse(response.body, response);
21
31
  return response.body;
22
32
  case "streaming":
23
33
  if (response.body == null) {
@@ -29,6 +39,7 @@ export async function getResponseBody(response, responseType) {
29
39
  },
30
40
  };
31
41
  }
42
+ retainResponse(response.body, response);
32
43
  return response.body;
33
44
  case "text":
34
45
  return await response.text();
@@ -3,6 +3,7 @@ import { join } from "../url/join.js";
3
3
  import { EndpointSupplier } from "./EndpointSupplier.js";
4
4
  import { getFetchFn } from "./getFetchFn.js";
5
5
  import { makeRequest } from "./makeRequest.js";
6
+ import { redactUrl } from "./redactUrl.js";
6
7
  import { requestWithRetries } from "./requestWithRetries.js";
7
8
  import { Supplier } from "./Supplier.js";
8
9
  /**
@@ -66,8 +67,10 @@ export async function makePassthroughRequest(input, init, clientOptions, request
66
67
  }
67
68
  }
68
69
  }
69
- // Apply auth headers
70
- if (clientOptions.getAuthHeaders != null) {
70
+ // Apply auth headers, but only when the resolved URL targets the configured base URL.
71
+ // This prevents the SDK's credentials from leaking to an unrelated host when a caller
72
+ // passes an absolute cross-origin URL into the passthrough fetch escape hatch.
73
+ if (clientOptions.getAuthHeaders != null && targetsBaseUrl(fullUrl, baseUrl)) {
71
74
  const authHeaders = await clientOptions.getAuthHeaders();
72
75
  for (const [key, value] of Object.entries(authHeaders)) {
73
76
  mergedHeaders[key.toLowerCase()] = value;
@@ -102,7 +105,7 @@ export async function makePassthroughRequest(input, init, clientOptions, request
102
105
  if (logger.isDebug()) {
103
106
  logger.debug("Making passthrough HTTP request", {
104
107
  method,
105
- url: fullUrl,
108
+ url: redactUrl(fullUrl),
106
109
  hasBody: body != null,
107
110
  });
108
111
  }
@@ -111,9 +114,28 @@ export async function makePassthroughRequest(input, init, clientOptions, request
111
114
  if (logger.isDebug()) {
112
115
  logger.debug("Passthrough HTTP request completed", {
113
116
  method,
114
- url: fullUrl,
117
+ url: redactUrl(fullUrl),
115
118
  statusCode: response.status,
116
119
  });
117
120
  }
118
121
  return response;
119
122
  }
123
+ /**
124
+ * Returns true when the resolved request URL points at the same origin as the
125
+ * configured base URL. Relative paths are always joined onto the base URL, so
126
+ * they resolve to the base origin and return true. Absolute URLs only match when
127
+ * their origin equals the base origin. When there is no base URL to compare
128
+ * against, or either value is not a parseable absolute URL, this returns false so
129
+ * auth headers are not attached.
130
+ */
131
+ function targetsBaseUrl(fullUrl, baseUrl) {
132
+ if (baseUrl == null) {
133
+ return false;
134
+ }
135
+ try {
136
+ return new URL(fullUrl).origin === new URL(baseUrl).origin;
137
+ }
138
+ catch {
139
+ return false;
140
+ }
141
+ }
@@ -0,0 +1,2 @@
1
+ export declare const SENSITIVE_QUERY_PARAMS: Set<string>;
2
+ export declare function redactUrl(url: string): string;
@@ -0,0 +1,84 @@
1
+ export const SENSITIVE_QUERY_PARAMS = new Set([
2
+ "api_key",
3
+ "api-key",
4
+ "apikey",
5
+ "token",
6
+ "access_token",
7
+ "access-token",
8
+ "auth_token",
9
+ "auth-token",
10
+ "password",
11
+ "passwd",
12
+ "secret",
13
+ "api_secret",
14
+ "api-secret",
15
+ "apisecret",
16
+ "key",
17
+ "session",
18
+ "session_id",
19
+ "session-id",
20
+ ]);
21
+ export function redactUrl(url) {
22
+ const protocolIndex = url.indexOf("://");
23
+ if (protocolIndex === -1)
24
+ return url;
25
+ const afterProtocol = protocolIndex + 3;
26
+ // Find the first delimiter that marks the end of the authority section
27
+ const pathStart = url.indexOf("/", afterProtocol);
28
+ let queryStart = url.indexOf("?", afterProtocol);
29
+ let fragmentStart = url.indexOf("#", afterProtocol);
30
+ const firstDelimiter = Math.min(pathStart === -1 ? url.length : pathStart, queryStart === -1 ? url.length : queryStart, fragmentStart === -1 ? url.length : fragmentStart);
31
+ // Find the LAST @ before the delimiter (handles multiple @ in credentials)
32
+ let atIndex = -1;
33
+ for (let i = afterProtocol; i < firstDelimiter; i++) {
34
+ if (url[i] === "@") {
35
+ atIndex = i;
36
+ }
37
+ }
38
+ if (atIndex !== -1) {
39
+ url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`;
40
+ }
41
+ // Recalculate queryStart since url might have changed
42
+ queryStart = url.indexOf("?");
43
+ if (queryStart === -1)
44
+ return url;
45
+ fragmentStart = url.indexOf("#", queryStart);
46
+ const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length;
47
+ const queryString = url.slice(queryStart + 1, queryEnd);
48
+ if (queryString.length === 0)
49
+ return url;
50
+ // FAST PATH: Quick check if any sensitive keywords present
51
+ // Using indexOf is faster than regex for simple substring matching
52
+ const lower = queryString.toLowerCase();
53
+ const hasSensitive = lower.includes("token") ||
54
+ lower.includes("key") ||
55
+ lower.includes("password") ||
56
+ lower.includes("passwd") ||
57
+ lower.includes("secret") ||
58
+ lower.includes("session") ||
59
+ lower.includes("auth");
60
+ if (!hasSensitive) {
61
+ return url;
62
+ }
63
+ // SLOW PATH: Parse and redact
64
+ const redactedParams = [];
65
+ const params = queryString.split("&");
66
+ for (const param of params) {
67
+ const equalIndex = param.indexOf("=");
68
+ if (equalIndex === -1) {
69
+ redactedParams.push(param);
70
+ continue;
71
+ }
72
+ const key = param.slice(0, equalIndex);
73
+ let shouldRedact = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase());
74
+ if (!shouldRedact && key.includes("%")) {
75
+ try {
76
+ const decodedKey = decodeURIComponent(key);
77
+ shouldRedact = SENSITIVE_QUERY_PARAMS.has(decodedKey.toLowerCase());
78
+ }
79
+ catch { }
80
+ }
81
+ redactedParams.push(shouldRedact ? `${key}=[REDACTED]` : param);
82
+ }
83
+ return url.slice(0, queryStart + 1) + redactedParams.join("&") + url.slice(queryEnd);
84
+ }
@@ -35,11 +35,11 @@ export function getRetryDelayFromHeaders(response, retryAttempt) {
35
35
  const resetTimeMilliseconds = resetTime >= 1_000_000_000_000 ? resetTime : resetTime * 1000;
36
36
  const delay = resetTimeMilliseconds - Date.now();
37
37
  if (delay > 0) {
38
- return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY));
38
+ return Math.min(addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY)), MAX_RETRY_DELAY);
39
39
  }
40
40
  }
41
41
  }
42
- return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * 2 ** retryAttempt, MAX_RETRY_DELAY));
42
+ return Math.min(addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * 2 ** retryAttempt, MAX_RETRY_DELAY)), MAX_RETRY_DELAY);
43
43
  }
44
44
  export async function requestWithRetries(requestFn, maxRetries = DEFAULT_MAX_RETRIES) {
45
45
  let response = await requestFn();
@@ -10,11 +10,19 @@ export function anySignal(...args) {
10
10
  for (const signal of signals) {
11
11
  if (signal.aborted) {
12
12
  controller.abort(signal?.reason);
13
- break;
13
+ return controller.signal;
14
14
  }
15
15
  signal.addEventListener("abort", () => controller.abort(signal?.reason), {
16
16
  signal: controller.signal,
17
17
  });
18
+ // Re-check after adding listener: the signal may have aborted
19
+ // between the initial `signal.aborted` check and the `addEventListener`
20
+ // call above. If it did, the abort event was already dispatched and
21
+ // the listener will never fire — we must manually abort.
22
+ if (signal.aborted) {
23
+ controller.abort(signal?.reason);
24
+ return controller.signal;
25
+ }
18
26
  }
19
27
  return controller.signal;
20
28
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Spreads caller-supplied `additionalBodyParameters` (from `requestOptions.additionalBodyParameters`)
3
+ * on top of the request body. Caller-supplied properties win over the endpoint body. When no
4
+ * additional body parameters are provided, the original body is returned unchanged so serialization
5
+ * is unaffected.
6
+ *
7
+ * The merge only applies to plain-object (JSON object) bodies. When the body is `null`/`undefined`
8
+ * the additional parameters become the body; when the body is an array or a primitive JSON value it
9
+ * is returned unchanged, since object properties cannot be spread into it. This mirrors the Python
10
+ * SDK, which only merges additional body parameters into mapping bodies.
11
+ */
12
+ export declare function mergeAdditionalBodyParameters(body: unknown, additionalBodyParameters: Record<string, unknown> | undefined): unknown;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Spreads caller-supplied `additionalBodyParameters` (from `requestOptions.additionalBodyParameters`)
3
+ * on top of the request body. Caller-supplied properties win over the endpoint body. When no
4
+ * additional body parameters are provided, the original body is returned unchanged so serialization
5
+ * is unaffected.
6
+ *
7
+ * The merge only applies to plain-object (JSON object) bodies. When the body is `null`/`undefined`
8
+ * the additional parameters become the body; when the body is an array or a primitive JSON value it
9
+ * is returned unchanged, since object properties cannot be spread into it. This mirrors the Python
10
+ * SDK, which only merges additional body parameters into mapping bodies.
11
+ */
12
+ export function mergeAdditionalBodyParameters(body, additionalBodyParameters) {
13
+ if (additionalBodyParameters == null) {
14
+ return body;
15
+ }
16
+ if (body == null) {
17
+ return { ...additionalBodyParameters };
18
+ }
19
+ if (typeof body === "object" && !Array.isArray(body)) {
20
+ return { ...body, ...additionalBodyParameters };
21
+ }
22
+ return body;
23
+ }
@@ -1 +1 @@
1
- export { RUNTIME } from "./runtime.js";
1
+ export { getUserAgent, RUNTIME } from "./runtime.js";
@@ -1 +1 @@
1
- export { RUNTIME } from "./runtime.js";
1
+ export { getUserAgent, RUNTIME } from "./runtime.js";
@@ -6,4 +6,23 @@ export interface Runtime {
6
6
  type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime";
7
7
  version?: string;
8
8
  parsedVersion?: number;
9
+ /**
10
+ * The operating system the SDK is running on, when it can be determined
11
+ * (e.g. "linux", "darwin", "win32" on server runtimes). Undefined in
12
+ * environments where the OS is not observable (e.g. browsers).
13
+ */
14
+ os?: string;
15
+ /**
16
+ * The CPU architecture the SDK is running on, when it can be determined
17
+ * (e.g. "x64", "arm64" on server runtimes). Undefined in environments where
18
+ * the architecture is not observable (e.g. browsers).
19
+ */
20
+ arch?: string;
9
21
  }
22
+ /**
23
+ * Builds a structured User-Agent string of the form
24
+ * `{sdkName}/{sdkVersion} ({os}; {arch}) {runtime}/{runtimeVersion}`
25
+ * where the platform group and runtime segment are omitted gracefully when the
26
+ * underlying values cannot be determined (e.g. in a browser).
27
+ */
28
+ export declare function getUserAgent(sdkName: string, sdkVersion: string): string;
@@ -55,6 +55,8 @@ function evaluateRuntime() {
55
55
  return {
56
56
  type: "deno",
57
57
  version: Deno.version.deno,
58
+ os: Deno.build?.os,
59
+ arch: Deno.build?.arch,
58
60
  };
59
61
  }
60
62
  /**
@@ -65,6 +67,8 @@ function evaluateRuntime() {
65
67
  return {
66
68
  type: "bun",
67
69
  version: Bun.version,
70
+ os: typeof process !== "undefined" ? process.platform : undefined,
71
+ arch: typeof process !== "undefined" ? process.arch : undefined,
68
72
  };
69
73
  }
70
74
  /**
@@ -92,9 +96,76 @@ function evaluateRuntime() {
92
96
  type: "node",
93
97
  version: _process.versions.node,
94
98
  parsedVersion: Number(_process.versions.node.split(".")[0]),
99
+ os: _process.platform,
100
+ arch: _process.arch,
95
101
  };
96
102
  }
97
103
  return {
98
104
  type: "unknown",
99
105
  };
100
106
  }
107
+ /**
108
+ * Display names for the language runtimes whose version is meaningful to encode
109
+ * in a User-Agent. Environments where a version string is not useful (e.g.
110
+ * browsers, where `version` is the full navigator UA) are intentionally mapped
111
+ * to `undefined` so they are omitted from the User-Agent.
112
+ */
113
+ const RUNTIME_DISPLAY_NAMES = {
114
+ node: "Node",
115
+ deno: "Deno",
116
+ bun: "Bun",
117
+ browser: undefined,
118
+ "web-worker": undefined,
119
+ "react-native": undefined,
120
+ workerd: undefined,
121
+ "edge-runtime": undefined,
122
+ unknown: undefined,
123
+ };
124
+ /**
125
+ * CPU architecture aliases that all refer to 64-bit x86. They are normalized to
126
+ * the single canonical token `x86_64` so the User-Agent architecture label is
127
+ * consistent regardless of which runtime reports it (Node reports `x64`, others
128
+ * report `amd64` or `x86_64`).
129
+ */
130
+ const X86_64_ARCH_ALIASES = new Set(["x64", "amd64", "x86_64"]);
131
+ /**
132
+ * Normalizes a CPU architecture token, collapsing the 64-bit x86 aliases
133
+ * (`x64`, `amd64`, `x86_64`) to `x86_64`. Other architectures are returned
134
+ * unchanged.
135
+ */
136
+ function normalizeArch(arch) {
137
+ if (arch == null) {
138
+ return arch;
139
+ }
140
+ return X86_64_ARCH_ALIASES.has(arch.toLowerCase()) ? "x86_64" : arch;
141
+ }
142
+ /**
143
+ * Percent-encodes the `@` and `/` characters in an npm package name so the
144
+ * User-Agent product token stays within the RFC 7230 token grammar. The
145
+ * original scoped package name can be recovered by URL-decoding (e.g.
146
+ * `@dummy/sdk` becomes `%40dummy%2Fsdk`).
147
+ */
148
+ function encodeProductName(sdkName) {
149
+ return sdkName.replace(/@/g, "%40").replace(/\//g, "%2F");
150
+ }
151
+ /**
152
+ * Builds a structured User-Agent string of the form
153
+ * `{sdkName}/{sdkVersion} ({os}; {arch}) {runtime}/{runtimeVersion}`
154
+ * where the platform group and runtime segment are omitted gracefully when the
155
+ * underlying values cannot be determined (e.g. in a browser).
156
+ */
157
+ export function getUserAgent(sdkName, sdkVersion) {
158
+ let userAgent = `${encodeProductName(sdkName)}/${sdkVersion}`;
159
+ const platform = [RUNTIME.os, normalizeArch(RUNTIME.arch)].filter((part) => part != null && part.length > 0);
160
+ if (platform.length > 0) {
161
+ userAgent += ` (${platform.join("; ")})`;
162
+ }
163
+ const runtimeName = RUNTIME_DISPLAY_NAMES[RUNTIME.type];
164
+ if (runtimeName != null) {
165
+ userAgent += ` ${runtimeName}`;
166
+ if (RUNTIME.version != null && RUNTIME.version.length > 0) {
167
+ userAgent += `/${RUNTIME.version}`;
168
+ }
169
+ }
170
+ return userAgent;
171
+ }
@@ -4,7 +4,7 @@ export class JsonError extends Error {
4
4
  constructor(errors) {
5
5
  super(errors.map(stringifyValidationError).join("; "));
6
6
  this.errors = errors;
7
- Object.setPrototypeOf(this, new.target.prototype);
8
- this.name = this.constructor.name;
7
+ Object.setPrototypeOf(this, JsonError.prototype);
8
+ this.name = "JsonError";
9
9
  }
10
10
  }
@@ -4,7 +4,7 @@ export class ParseError extends Error {
4
4
  constructor(errors) {
5
5
  super(errors.map(stringifyValidationError).join("; "));
6
6
  this.errors = errors;
7
- Object.setPrototypeOf(this, new.target.prototype);
8
- this.name = this.constructor.name;
7
+ Object.setPrototypeOf(this, ParseError.prototype);
8
+ this.name = "ParseError";
9
9
  }
10
10
  }
@@ -16,7 +16,7 @@ function stringifyObject(obj, prefix = "", options) {
16
16
  const parts = [];
17
17
  for (const [key, value] of Object.entries(obj)) {
18
18
  const fullKey = prefix ? `${prefix}[${key}]` : key;
19
- if (value === undefined) {
19
+ if (value == null) {
20
20
  continue;
21
21
  }
22
22
  if (Array.isArray(value)) {
@@ -36,7 +36,7 @@ function stringifyObject(obj, prefix = "", options) {
36
36
  else {
37
37
  for (let i = 0; i < value.length; i++) {
38
38
  const item = value[i];
39
- if (item === undefined) {
39
+ if (item == null) {
40
40
  continue;
41
41
  }
42
42
  if (typeof item === "object" && !Array.isArray(item) && item !== null) {
@@ -11,4 +11,5 @@ export declare class PredictorSDKError extends Error {
11
11
  rawResponse?: core.RawResponse;
12
12
  cause?: unknown;
13
13
  });
14
+ get requestId(): string | undefined;
14
15
  }
@@ -11,7 +11,7 @@ export class PredictorSDKError extends Error {
11
11
  if (Error.captureStackTrace) {
12
12
  Error.captureStackTrace(this, this.constructor);
13
13
  }
14
- this.name = this.constructor.name;
14
+ this.name = "PredictorSDKError";
15
15
  this.statusCode = statusCode;
16
16
  this.body = body;
17
17
  this.rawResponse = rawResponse;
@@ -19,6 +19,9 @@ export class PredictorSDKError extends Error {
19
19
  this.cause = cause;
20
20
  }
21
21
  }
22
+ get requestId() {
23
+ return this.rawResponse?.headers?.get("x-request-id") ?? undefined;
24
+ }
22
25
  }
23
26
  function buildMessage({ message, statusCode, body, }) {
24
27
  const lines = [];
@@ -1,5 +1,5 @@
1
- export declare class PredictorSDKTimeoutError extends Error {
2
- readonly cause?: unknown;
1
+ import * as errors from "./index.js";
2
+ export declare class PredictorSDKTimeoutError extends errors.PredictorSDKError {
3
3
  constructor(message: string, opts?: {
4
4
  cause?: unknown;
5
5
  });
@@ -1,15 +1,15 @@
1
1
  // This file was auto-generated by Fern from our API Definition.
2
- export class PredictorSDKTimeoutError extends Error {
3
- cause;
2
+ import * as errors from "./index.js";
3
+ export class PredictorSDKTimeoutError extends errors.PredictorSDKError {
4
4
  constructor(message, opts) {
5
- super(message);
5
+ super({
6
+ message: message,
7
+ cause: opts?.cause,
8
+ });
6
9
  Object.setPrototypeOf(this, new.target.prototype);
7
10
  if (Error.captureStackTrace) {
8
11
  Error.captureStackTrace(this, this.constructor);
9
12
  }
10
- this.name = this.constructor.name;
11
- if (opts?.cause != null) {
12
- this.cause = opts.cause;
13
- }
13
+ this.name = "PredictorSDKTimeoutError";
14
14
  }
15
15
  }
@@ -6,6 +6,7 @@ export declare const PlatformMarket: core.serialization.ObjectSchema<serializers
6
6
  export declare namespace PlatformMarket {
7
7
  interface Raw {
8
8
  platform: PlatformMarketPlatform.Raw;
9
+ event_id?: string | null;
9
10
  event_ticker?: string | null;
10
11
  market_tickers?: string[] | null;
11
12
  market_slug?: string | null;
@@ -3,6 +3,7 @@ import * as core from "../../core/index.js";
3
3
  import { PlatformMarketPlatform } from "./PlatformMarketPlatform.js";
4
4
  export const PlatformMarket = core.serialization.object({
5
5
  platform: PlatformMarketPlatform,
6
+ eventId: core.serialization.property("event_id", core.serialization.string().optional()),
6
7
  eventTicker: core.serialization.property("event_ticker", core.serialization.string().optional()),
7
8
  marketTickers: core.serialization.property("market_tickers", core.serialization.list(core.serialization.string()).optional()),
8
9
  marketSlug: core.serialization.property("market_slug", core.serialization.string().optional()),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@predictorsdk/client",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "The official TypeScript/JavaScript client for the PredictorSDK matching markets API",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -47,7 +47,7 @@
47
47
  "node": ">=18"
48
48
  },
49
49
  "devDependencies": {
50
- "@types/node": "^25.5.2",
50
+ "@types/node": "^26.2.0",
51
51
  "typescript": "^5.7.0"
52
52
  }
53
53
  }