@syndroo/sdk 0.4.0-rc.1 → 0.7.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 (42) hide show
  1. package/README.md +83 -136
  2. package/dist/client.d.ts +30 -102
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +120 -325
  5. package/dist/client.js.map +1 -1
  6. package/dist/errors.d.ts +48 -93
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +131 -137
  9. package/dist/errors.js.map +1 -1
  10. package/dist/generated/compiled.d.ts +182 -0
  11. package/dist/generated/compiled.d.ts.map +1 -0
  12. package/dist/generated/compiled.js +25761 -0
  13. package/dist/generated/compiled.js.map +1 -0
  14. package/dist/generated/types.d.ts +387 -0
  15. package/dist/generated/types.d.ts.map +1 -0
  16. package/dist/generated/types.js +2 -0
  17. package/dist/generated/types.js.map +1 -0
  18. package/dist/generated/validation.d.ts +18 -0
  19. package/dist/generated/validation.d.ts.map +1 -0
  20. package/dist/generated/validation.js +184 -0
  21. package/dist/generated/validation.js.map +1 -0
  22. package/dist/generated/validators.d.ts +3 -0
  23. package/dist/generated/validators.d.ts.map +1 -0
  24. package/dist/generated/validators.js +10 -0
  25. package/dist/generated/validators.js.map +1 -0
  26. package/dist/http.d.ts +91 -35
  27. package/dist/http.d.ts.map +1 -1
  28. package/dist/http.js +345 -243
  29. package/dist/http.js.map +1 -1
  30. package/dist/index.d.ts +8 -5
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +7 -5
  33. package/dist/index.js.map +1 -1
  34. package/dist/types.d.ts +90 -83
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js +16 -155
  37. package/dist/types.js.map +1 -1
  38. package/dist/wait.d.ts +65 -0
  39. package/dist/wait.d.ts.map +1 -0
  40. package/dist/wait.js +192 -0
  41. package/dist/wait.js.map +1 -0
  42. package/package.json +6 -3
package/dist/errors.d.ts CHANGED
@@ -1,104 +1,59 @@
1
1
  /**
2
- * Typed error hierarchy for the public Syndroo SDK.
2
+ * Error surface of `@syndroo/sdk`.
3
3
  *
4
- * Every failure the SDK raises is a `SyndrooError`, so callers can narrow on
5
- * one base class and still classify the outcome precisely. The
6
- * `requestMayHaveBeenApplied` flag is the state that decides whether a resend
7
- * is safe: it is true whenever a write may already have reached Syndroo, which
8
- * is exactly the case where retrying with a new idempotency key could create a
9
- * second post.
4
+ * Every error the SDK raises carries a stable `code` and a fixed message. The
5
+ * message never contains a base URL, a path, an idempotency key, a bearer token
6
+ * or any part of a server response, because SDK errors reach logs. The only
7
+ * server-authored data that can appear is `serverError`, and only after the
8
+ * envelope that carried it passed the generated wire validator.
9
+ *
10
+ * A validated envelope is not enough on its own: the wire schema legitimately
11
+ * allows arbitrary `code`/`message` strings and tolerates extra fields, so the
12
+ * server object is never stored by reference. `projectServerError` copies it
13
+ * onto a fixed shape - an allowlisted code, a static message and bounded
14
+ * `details` values - so no server-authored text can reach a log through
15
+ * `JSON.stringify`, `util.inspect` or a stack trace.
10
16
  */
11
- import type { PostDetail } from "./types.js";
12
- export type SyndrooErrorCode = "CONFIG" | "VALIDATION" | "ABORTED" | "TIMEOUT" | "NETWORK" | "INVALID_RESPONSE" | "WAIT_TIMEOUT" | (string & {});
13
- export interface SyndrooErrorInit {
14
- cause?: unknown | undefined;
15
- requestMayHaveBeenApplied?: boolean | undefined;
16
- }
17
- export declare class SyndrooError<Code extends SyndrooErrorCode = SyndrooErrorCode> extends Error {
18
- readonly code: Code;
19
- readonly requestMayHaveBeenApplied: boolean;
20
- constructor(message: string, init: SyndrooErrorInit & {
21
- code: Code;
22
- });
23
- }
24
- /** The client configuration itself is unusable, so no request was sent. */
25
- export declare class SyndrooConfigError extends SyndrooError<"CONFIG"> {
26
- constructor(message: string);
27
- }
28
- /** The caller's argument cannot become a valid Syndroo request. */
29
- export declare class SyndrooValidationError extends SyndrooError<"VALIDATION"> {
30
- constructor(message: string);
31
- }
32
- /** The caller aborted through an AbortSignal. */
33
- export declare class SyndrooAbortError extends SyndrooError<"ABORTED"> {
34
- constructor(message: string, init?: SyndrooErrorInit);
35
- }
36
- /** The configured deadline elapsed before the response was received. */
37
- export declare class SyndrooTimeoutError extends SyndrooError<"TIMEOUT"> {
38
- readonly timeoutMs: number;
39
- constructor(message: string, init: SyndrooErrorInit & {
40
- timeoutMs: number;
41
- });
42
- }
17
+ import type { SafeError } from "./types.js";
43
18
  /**
44
- * The request never produced an HTTP response. `networkCode` carries the
45
- * runtime's error code, such as `ECONNREFUSED`, when one is available.
19
+ * Project a server-authored error onto a fixed, allowlisted shape.
20
+ *
21
+ * Only three fields survive, each of them validated: an allowlisted `code` (an
22
+ * unrecognized code becomes `UNKNOWN_ERROR`), a static `message`, and `details`
23
+ * rebuilt from scratch so unknown keys, wrong types and malformed values are
24
+ * dropped. Nothing is copied by reference, so mutating the original object
25
+ * afterwards cannot change what an error reports.
46
26
  */
47
- export declare class SyndrooNetworkError extends SyndrooError<"NETWORK"> {
48
- readonly networkCode?: string;
49
- constructor(message: string, init: SyndrooErrorInit & {
50
- networkCode?: string | undefined;
51
- });
52
- }
27
+ export declare function projectServerError(raw: unknown): SafeError | undefined;
28
+ /** Stable, branchable error codes. Adding one is an API decision. */
29
+ export type SyndrooErrorCode = "INVALID_ARGUMENT" | "INSECURE_BASE_URL" | "INVALID_REQUEST" | "INVALID_RESPONSE" | "RESPONSE_TOO_LARGE" | "REDIRECT_NOT_ALLOWED" | "TRANSPORT" | "HTTP_ERROR" | "PROTOCOL" | "TIMEOUT" | "ABORTED" | "WAIT_TIMEOUT" | "CONFIRMATION_REQUIRED" | "CONFIRMATION_EXPIRED";
30
+ export type SyndrooErrorInit = {
31
+ /** HTTP status, when the error came from a response. Never a response body. */
32
+ status?: number;
33
+ /**
34
+ * `SafeError` from an `ok:false` envelope, or any object meant to stand in
35
+ * for one. It is projected onto the allowlisted shape, never stored as-is.
36
+ */
37
+ serverError?: SafeError;
38
+ /**
39
+ * Whether the SDK considers a same-key transport retry safe for this failure.
40
+ * Defaults to true for a bare transport failure and false otherwise.
41
+ */
42
+ retryable?: boolean;
43
+ };
53
44
  /**
54
- * Syndroo answered, but the answer is not the documented JSON contract: a
55
- * non-JSON body, a missing required field, or a body above the configured
56
- * size limit. The outcome of a write is never inferred from a bad response.
45
+ * One error type for transport, protocol and local-cancellation failures.
46
+ *
47
+ * `retryable` describes the SDK's own transport-retry decision for this failure
48
+ * and is never advice to retry content: an `unknown` business outcome is a
49
+ * successful protocol call, not an error, and is never auto-retried.
57
50
  */
58
- export declare class SyndrooResponseError extends SyndrooError<"INVALID_RESPONSE"> {
51
+ export declare class SyndrooError extends Error {
52
+ readonly code: SyndrooErrorCode;
59
53
  readonly status?: number;
60
- readonly preview?: string;
61
- constructor(message: string, init?: SyndrooErrorInit & {
62
- status?: number | undefined;
63
- preview?: string | undefined;
64
- });
65
- }
66
- /**
67
- * Syndroo rejected the request with a documented error envelope. `code` is the
68
- * server's code such as `UNAUTHORIZED`, `POST_NOT_FOUND`,
69
- * `IDEMPOTENCY_CONFLICT`, or `PLATFORM_NOT_CONFIGURED`, and `HTTP_<status>`
70
- * when the body did not carry one.
71
- */
72
- export declare class SyndrooApiError extends SyndrooError {
73
- readonly status: number;
74
- readonly retryAfterMs?: number;
75
- constructor(message: string, init: SyndrooErrorInit & {
76
- code: SyndrooErrorCode;
77
- status: number;
78
- retryAfterMs?: number | undefined;
79
- });
80
- /** Syndroo or an intermediary asked the client to slow down. */
81
- get retryable(): boolean;
82
- }
83
- /** `posts.wait` reached its deadline before the post became terminal. */
84
- export declare class SyndrooWaitTimeoutError extends SyndrooError<"WAIT_TIMEOUT"> {
85
- readonly postId: string;
86
- readonly timeoutMs: number;
87
- readonly lastStatus?: string;
88
- readonly lastPost?: PostDetail;
89
- readonly lastError?: SyndrooError;
90
- constructor(message: string, init: {
91
- postId: string;
92
- timeoutMs: number;
93
- lastStatus?: string | undefined;
94
- lastPost?: PostDetail | undefined;
95
- lastError?: SyndrooError | undefined;
96
- });
54
+ readonly serverError?: SafeError;
55
+ readonly retryable: boolean;
56
+ constructor(code: SyndrooErrorCode, init?: SyndrooErrorInit);
97
57
  }
98
58
  export declare function isSyndrooError(value: unknown): value is SyndrooError;
99
- /**
100
- * Internal helper for bounded diagnostics. Error messages and response
101
- * previews must never grow with the size of an untrusted body.
102
- */
103
- export declare function truncate(value: string, limit: number): string;
104
59
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAyE5C;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAgBtE;AAED,qEAAqE;AACrE,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GACpB,sBAAsB,GACtB,WAAW,GACX,YAAY,GACZ,UAAU,GACV,SAAS,GACT,SAAS,GACT,cAAc,GACd,uBAAuB,GACvB,sBAAsB,CAAC;AAoB3B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B,YAAY,IAAI,EAAE,gBAAgB,EAAE,IAAI,GAAE,gBAAqB,EAc9D;CACF;AAGD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE"}
package/dist/errors.js CHANGED
@@ -1,162 +1,156 @@
1
1
  /**
2
- * Typed error hierarchy for the public Syndroo SDK.
2
+ * Error surface of `@syndroo/sdk`.
3
3
  *
4
- * Every failure the SDK raises is a `SyndrooError`, so callers can narrow on
5
- * one base class and still classify the outcome precisely. The
6
- * `requestMayHaveBeenApplied` flag is the state that decides whether a resend
7
- * is safe: it is true whenever a write may already have reached Syndroo, which
8
- * is exactly the case where retrying with a new idempotency key could create a
9
- * second post.
4
+ * Every error the SDK raises carries a stable `code` and a fixed message. The
5
+ * message never contains a base URL, a path, an idempotency key, a bearer token
6
+ * or any part of a server response, because SDK errors reach logs. The only
7
+ * server-authored data that can appear is `serverError`, and only after the
8
+ * envelope that carried it passed the generated wire validator.
9
+ *
10
+ * A validated envelope is not enough on its own: the wire schema legitimately
11
+ * allows arbitrary `code`/`message` strings and tolerates extra fields, so the
12
+ * server object is never stored by reference. `projectServerError` copies it
13
+ * onto a fixed shape - an allowlisted code, a static message and bounded
14
+ * `details` values - so no server-authored text can reach a log through
15
+ * `JSON.stringify`, `util.inspect` or a stack trace.
10
16
  */
11
- export class SyndrooError extends Error {
12
- code;
13
- requestMayHaveBeenApplied;
14
- constructor(message, init) {
15
- super(message, { cause: init.cause });
16
- this.name = "SyndrooError";
17
- this.code = init.code;
18
- this.requestMayHaveBeenApplied = init.requestMayHaveBeenApplied ?? false;
19
- }
20
- }
21
- /** The client configuration itself is unusable, so no request was sent. */
22
- export class SyndrooConfigError extends SyndrooError {
23
- constructor(message) {
24
- super(message, { code: "CONFIG" });
25
- this.name = "SyndrooConfigError";
17
+ /**
18
+ * Protocol error codes the server may report verbatim (the stable set from the
19
+ * shared blueprint). A code outside this set is never retained.
20
+ */
21
+ const SERVER_ERROR_CODES = new Set([
22
+ "INVALID_INPUT",
23
+ "BODY_TOO_LARGE",
24
+ "UNSUPPORTED_MEDIA_TYPE",
25
+ "UNAUTHORIZED",
26
+ "FORBIDDEN",
27
+ "NOT_FOUND",
28
+ "TARGET_AMBIGUOUS",
29
+ "DUPLICATE_TARGET",
30
+ "CONNECTION_IDENTITY_CHANGED",
31
+ "CONNECTION_CAPACITY",
32
+ "PROVIDER_TRUST_REQUIRED",
33
+ "PROVIDER_INVALID",
34
+ "PROVIDER_UNAVAILABLE",
35
+ "STALE_INTENT",
36
+ "STALE_BINDING",
37
+ "APPROVAL_INVALID",
38
+ "APPROVAL_EXPIRED",
39
+ "IDEMPOTENCY_CONFLICT",
40
+ "REQUEST_IN_PROGRESS",
41
+ "RETRY_INELIGIBLE",
42
+ "CONNECT_SESSION_EXPIRED",
43
+ "CONNECT_STEP_CONFLICT",
44
+ "CONNECT_STEP_UNKNOWN",
45
+ "STATE_RECOVERY_REQUIRED",
46
+ "DURABILITY_ERROR",
47
+ ]);
48
+ /** Static text kept in place of every server-authored message. */
49
+ const SERVER_ERROR_MESSAGE = "the server rejected the request";
50
+ /** Placeholder for a server code the SDK does not recognize. */
51
+ const UNKNOWN_SERVER_ERROR_CODE = "UNKNOWN_ERROR";
52
+ /** A dotted path with optional array indices, e.g. `targets[0].options.visibility`. */
53
+ const FIELD_PATH_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*|\[[0-9]{1,6}\])*$/;
54
+ /**
55
+ * A Syndroo operation id. Core mints every id as `<prefix>_<base64url>` (for
56
+ * example `op_2f8c...`), so the shape - a short lowercase prefix, then a
57
+ * base64url token - is checkable without importing Core. A string that does not
58
+ * have it is not an id the SDK will echo back.
59
+ */
60
+ const OPERATION_ID_PATTERN = /^[a-z][a-z0-9]{0,7}_[A-Za-z0-9_-]{1,118}$/;
61
+ /** RFC 3339 date-time, the `IsoTime` shape the wire schema uses. */
62
+ const ISO_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/;
63
+ function projectDetails(raw) {
64
+ if (raw === null || typeof raw !== "object") {
65
+ return undefined;
26
66
  }
27
- }
28
- /** The caller's argument cannot become a valid Syndroo request. */
29
- export class SyndrooValidationError extends SyndrooError {
30
- constructor(message) {
31
- super(message, { code: "VALIDATION" });
32
- this.name = "SyndrooValidationError";
67
+ const source = raw;
68
+ const details = {};
69
+ const field = source["field"];
70
+ if (typeof field === "string" && field.length <= 256 && FIELD_PATH_PATTERN.test(field)) {
71
+ details.field = field;
33
72
  }
34
- }
35
- /** The caller aborted through an AbortSignal. */
36
- export class SyndrooAbortError extends SyndrooError {
37
- constructor(message, init = {}) {
38
- super(message, {
39
- code: "ABORTED",
40
- cause: init.cause,
41
- requestMayHaveBeenApplied: init.requestMayHaveBeenApplied,
42
- });
43
- this.name = "SyndrooAbortError";
73
+ const operationId = source["operationId"];
74
+ if (typeof operationId === "string" && OPERATION_ID_PATTERN.test(operationId)) {
75
+ details.operationId = operationId;
44
76
  }
45
- }
46
- /** The configured deadline elapsed before the response was received. */
47
- export class SyndrooTimeoutError extends SyndrooError {
48
- timeoutMs;
49
- constructor(message, init) {
50
- super(message, {
51
- code: "TIMEOUT",
52
- cause: init.cause,
53
- requestMayHaveBeenApplied: init.requestMayHaveBeenApplied,
54
- });
55
- this.name = "SyndrooTimeoutError";
56
- this.timeoutMs = init.timeoutMs;
77
+ const retryAt = source["retryAt"];
78
+ if (typeof retryAt === "string" && ISO_TIME_PATTERN.test(retryAt)) {
79
+ details.retryAt = retryAt;
57
80
  }
81
+ return Object.keys(details).length === 0 ? undefined : details;
58
82
  }
59
83
  /**
60
- * The request never produced an HTTP response. `networkCode` carries the
61
- * runtime's error code, such as `ECONNREFUSED`, when one is available.
84
+ * Project a server-authored error onto a fixed, allowlisted shape.
85
+ *
86
+ * Only three fields survive, each of them validated: an allowlisted `code` (an
87
+ * unrecognized code becomes `UNKNOWN_ERROR`), a static `message`, and `details`
88
+ * rebuilt from scratch so unknown keys, wrong types and malformed values are
89
+ * dropped. Nothing is copied by reference, so mutating the original object
90
+ * afterwards cannot change what an error reports.
62
91
  */
63
- export class SyndrooNetworkError extends SyndrooError {
64
- networkCode;
65
- constructor(message, init) {
66
- super(message, {
67
- code: "NETWORK",
68
- cause: init.cause,
69
- requestMayHaveBeenApplied: init.requestMayHaveBeenApplied,
70
- });
71
- this.name = "SyndrooNetworkError";
72
- if (init.networkCode !== undefined) {
73
- this.networkCode = init.networkCode;
74
- }
92
+ export function projectServerError(raw) {
93
+ if (raw === null || typeof raw !== "object") {
94
+ return undefined;
95
+ }
96
+ const source = raw;
97
+ const rawCode = source["code"];
98
+ const code = typeof rawCode === "string" && SERVER_ERROR_CODES.has(rawCode)
99
+ ? rawCode
100
+ : UNKNOWN_SERVER_ERROR_CODE;
101
+ const error = { code, message: SERVER_ERROR_MESSAGE };
102
+ const details = projectDetails(source["details"]);
103
+ if (details !== undefined) {
104
+ error.details = details;
75
105
  }
106
+ return error;
76
107
  }
108
+ /** Fixed messages. Nothing here is interpolated from input or from a response. */
109
+ const MESSAGES = Object.freeze({
110
+ INVALID_ARGUMENT: "the SDK call was given an argument outside its documented bounds",
111
+ INSECURE_BASE_URL: "the base URL is not an acceptable Syndroo endpoint",
112
+ INVALID_REQUEST: "the request does not match the Syndroo wire protocol",
113
+ INVALID_RESPONSE: "the server response does not match the Syndroo wire protocol",
114
+ RESPONSE_TOO_LARGE: "the server response exceeded the protocol size bound",
115
+ REDIRECT_NOT_ALLOWED: "the server answered with a redirect, which the SDK never follows",
116
+ TRANSPORT: "the request could not be completed at the transport layer",
117
+ HTTP_ERROR: "the server answered with an unexpected HTTP status",
118
+ PROTOCOL: "the server rejected the request",
119
+ TIMEOUT: "the request deadline elapsed before a response arrived",
120
+ ABORTED: "the call was cancelled locally",
121
+ WAIT_TIMEOUT: "the wait deadline elapsed before the execution round completed",
122
+ CONFIRMATION_REQUIRED: "the operation is waiting for explicit confirmation",
123
+ CONFIRMATION_EXPIRED: "the prepared operation's confirmation window has expired",
124
+ });
77
125
  /**
78
- * Syndroo answered, but the answer is not the documented JSON contract: a
79
- * non-JSON body, a missing required field, or a body above the configured
80
- * size limit. The outcome of a write is never inferred from a bad response.
126
+ * One error type for transport, protocol and local-cancellation failures.
127
+ *
128
+ * `retryable` describes the SDK's own transport-retry decision for this failure
129
+ * and is never advice to retry content: an `unknown` business outcome is a
130
+ * successful protocol call, not an error, and is never auto-retried.
81
131
  */
82
- export class SyndrooResponseError extends SyndrooError {
132
+ export class SyndrooError extends Error {
133
+ code;
83
134
  status;
84
- preview;
85
- constructor(message, init = {}) {
86
- super(message, {
87
- code: "INVALID_RESPONSE",
88
- cause: init.cause,
89
- requestMayHaveBeenApplied: init.requestMayHaveBeenApplied,
90
- });
91
- this.name = "SyndrooResponseError";
135
+ serverError;
136
+ retryable;
137
+ constructor(code, init = {}) {
138
+ super(MESSAGES[code]);
139
+ this.name = "SyndrooError";
140
+ this.code = code;
92
141
  if (init.status !== undefined) {
93
142
  this.status = init.status;
94
143
  }
95
- if (init.preview !== undefined) {
96
- this.preview = init.preview;
97
- }
98
- }
99
- }
100
- /**
101
- * Syndroo rejected the request with a documented error envelope. `code` is the
102
- * server's code such as `UNAUTHORIZED`, `POST_NOT_FOUND`,
103
- * `IDEMPOTENCY_CONFLICT`, or `PLATFORM_NOT_CONFIGURED`, and `HTTP_<status>`
104
- * when the body did not carry one.
105
- */
106
- export class SyndrooApiError extends SyndrooError {
107
- status;
108
- retryAfterMs;
109
- constructor(message, init) {
110
- super(message, {
111
- code: init.code,
112
- cause: init.cause,
113
- requestMayHaveBeenApplied: init.requestMayHaveBeenApplied,
114
- });
115
- this.name = "SyndrooApiError";
116
- this.status = init.status;
117
- if (init.retryAfterMs !== undefined) {
118
- this.retryAfterMs = init.retryAfterMs;
119
- }
120
- }
121
- /** Syndroo or an intermediary asked the client to slow down. */
122
- get retryable() {
123
- return this.status === 429 || this.status >= 500;
124
- }
125
- }
126
- /** `posts.wait` reached its deadline before the post became terminal. */
127
- export class SyndrooWaitTimeoutError extends SyndrooError {
128
- postId;
129
- timeoutMs;
130
- lastStatus;
131
- lastPost;
132
- lastError;
133
- constructor(message, init) {
134
- super(message, { code: "WAIT_TIMEOUT", requestMayHaveBeenApplied: false });
135
- this.name = "SyndrooWaitTimeoutError";
136
- this.postId = init.postId;
137
- this.timeoutMs = init.timeoutMs;
138
- if (init.lastStatus !== undefined) {
139
- this.lastStatus = init.lastStatus;
140
- }
141
- if (init.lastPost !== undefined) {
142
- this.lastPost = init.lastPost;
143
- }
144
- if (init.lastError !== undefined) {
145
- this.lastError = init.lastError;
144
+ if (init.serverError !== undefined) {
145
+ const projected = projectServerError(init.serverError);
146
+ if (projected !== undefined) {
147
+ this.serverError = projected;
148
+ }
146
149
  }
150
+ this.retryable = init.retryable ?? code === "TRANSPORT";
147
151
  }
148
152
  }
149
153
  export function isSyndrooError(value) {
150
154
  return value instanceof SyndrooError;
151
155
  }
152
- /**
153
- * Internal helper for bounded diagnostics. Error messages and response
154
- * previews must never grow with the size of an untrusted body.
155
- */
156
- export function truncate(value, limit) {
157
- if (value.length <= limit) {
158
- return value;
159
- }
160
- return `${value.slice(0, limit)}...[${value.length - limit} more characters]`;
161
- }
162
156
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}