@relyio/sdk 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/{chunk-7W4MJXQ4.cjs → chunk-54WP2PWG.cjs} +215 -96
  4. package/dist/chunk-BBUB7C2Z.js +81 -0
  5. package/dist/{chunk-FJK7ZWKK.cjs → chunk-HMVGXUGR.cjs} +156 -221
  6. package/dist/chunk-LSRPMNPT.cjs +89 -0
  7. package/dist/{chunk-2QUK2ZGD.js → chunk-LYRYCIX5.js} +157 -219
  8. package/dist/{chunk-RJBIJ2ZK.js → chunk-QIZOBT5F.js} +215 -96
  9. package/dist/client/index.cjs +4 -3
  10. package/dist/client/index.d.cts +4 -3
  11. package/dist/client/index.d.ts +4 -3
  12. package/dist/client/index.js +2 -1
  13. package/dist/define-content-type-CBfnTWSS.d.cts +716 -0
  14. package/dist/define-content-type-CBfnTWSS.d.ts +716 -0
  15. package/dist/{define-schema-DHvUCKwj.d.cts → define-schema-BD6HSPnG.d.ts} +55 -722
  16. package/dist/{define-schema-DHvUCKwj.d.ts → define-schema-BfXeR6K8.d.cts} +55 -722
  17. package/dist/dev-handshake/index.cjs +37 -0
  18. package/dist/dev-handshake/index.d.cts +144 -0
  19. package/dist/dev-handshake/index.d.ts +144 -0
  20. package/dist/dev-handshake/index.js +4 -0
  21. package/dist/{index-DGWaawHt.d.cts → index-BDpar3FO.d.cts} +22 -6
  22. package/dist/{index-BsUqCAu8.d.cts → index-DuEhsGdE.d.ts} +516 -2155
  23. package/dist/{index-B-KiFHbx.d.ts → index-Dx01iwaf.d.ts} +22 -6
  24. package/dist/{index-BsUqCAu8.d.ts → index-ulOrcfPa.d.cts} +516 -2155
  25. package/dist/index.cjs +67 -70
  26. package/dist/index.d.cts +28 -13
  27. package/dist/index.d.ts +28 -13
  28. package/dist/index.js +3 -2
  29. package/dist/schema/index.cjs +35 -47
  30. package/dist/schema/index.d.cts +3 -2
  31. package/dist/schema/index.d.ts +3 -2
  32. package/dist/schema/index.js +1 -1
  33. package/dist/types/index.d.cts +2 -1
  34. package/dist/types/index.d.ts +2 -1
  35. package/package.json +11 -5
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ var chunkLSRPMNPT_cjs = require('../chunk-LSRPMNPT.cjs');
4
+ require('../chunk-MWMSFIWN.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "DEV_CONTEXT_DIR", {
9
+ enumerable: true,
10
+ get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_DIR; }
11
+ });
12
+ Object.defineProperty(exports, "DEV_CONTEXT_FILE", {
13
+ enumerable: true,
14
+ get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_FILE; }
15
+ });
16
+ Object.defineProperty(exports, "DEV_CONTEXT_FILENAME", {
17
+ enumerable: true,
18
+ get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_FILENAME; }
19
+ });
20
+ Object.defineProperty(exports, "DEV_ENV", {
21
+ enumerable: true,
22
+ get: function () { return chunkLSRPMNPT_cjs.DEV_ENV; }
23
+ });
24
+ Object.defineProperty(exports, "buildDevEnv", {
25
+ enumerable: true,
26
+ get: function () { return chunkLSRPMNPT_cjs.buildDevEnv; }
27
+ });
28
+ Object.defineProperty(exports, "parseDevContextFile", {
29
+ enumerable: true,
30
+ get: function () { return chunkLSRPMNPT_cjs.parseDevContextFile; }
31
+ });
32
+ Object.defineProperty(exports, "parseDevEnv", {
33
+ enumerable: true,
34
+ get: function () { return chunkLSRPMNPT_cjs.parseDevEnv; }
35
+ });
36
+ //# sourceMappingURL=index.cjs.map
37
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The `relyio dev` handshake: the one declaration of how a sandbox reaches a running app.
3
+ *
4
+ * `relyio dev` provisions an ephemeral sandbox and hands its connection details to the developer's
5
+ * app by two carriers, which `sandboxes-spec.md` presents as interchangeable:
6
+ *
7
+ * 1. **Env** — `relyio dev -- pnpm dev` injects `RELYIO_DEV_*` into the wrapped child process.
8
+ * 2. **File** — `.relyio/dev.json`, for an app started standalone beside the cockpit.
9
+ *
10
+ * Three consumers read this: the SDK (both carriers), and `relyio promote` (the file, to work out
11
+ * which sandbox this repo is developing against). Before REL-647 each had its own copy of the
12
+ * answer and the three disagreed — the file required `branchId` in the CLI and not in the SDK, an
13
+ * unparseable deadline read as *unbounded*, and **the env carrier had no expiry at all**, so
14
+ * `relyio dev` and `relyio dev -- pnpm dev` were not in fact interchangeable: the same lapsed
15
+ * sandbox stopped working under one and kept working for the life of the process under the other.
16
+ *
17
+ * So this module is the declaration, and it is deliberately **pure** — no `node:*`, no I/O, no
18
+ * clock of its own. Each consumer keeps the I/O shell it needs (the SDK cannot statically import
19
+ * `node:fs`; the CLI is async and knows the project root) and none of them keeps a rule.
20
+ *
21
+ * **On the direction of the dependency.** The CLI *writes* this file and the SDK *reads* it, so
22
+ * publishing the declaration from the reader inverts writer→reader, which is worth knowing when
23
+ * you change it. It is the right trade anyway: the SDK is already dependency-free and browser-safe
24
+ * by construction, so the declaration costs it nothing, while the CLI bundles every `@relyio/*`
25
+ * into its published artifact and can absorb the import. The alternative — a third package — buys
26
+ * a version stream for four constants and a parser.
27
+ */
28
+ /** Directory, relative to the project root, that holds the dev artifact. Hidden, git-ignored. */
29
+ declare const DEV_CONTEXT_DIR = ".relyio";
30
+ /** Filename of the dev artifact inside {@link DEV_CONTEXT_DIR}. */
31
+ declare const DEV_CONTEXT_FILENAME = "dev.json";
32
+ /**
33
+ * Path of the dev artifact relative to the project root, POSIX-separated.
34
+ *
35
+ * The one place this path is spelled. It is also exactly the `.gitignore` entry, which must use a
36
+ * forward slash on every platform — so the constant is a literal rather than a `path.join`, and
37
+ * callers that need a filesystem path join it onto their own root.
38
+ */
39
+ declare const DEV_CONTEXT_FILE = ".relyio/dev.json";
40
+ /**
41
+ * The environment variables `relyio dev` injects into a wrapped child process.
42
+ *
43
+ * `expiresAt` is the REL-647 addition. Without it the env carrier could not express a deadline, so
44
+ * it was exempt from the expiry the file carrier enforced — which is the whole of Gap 3.
45
+ */
46
+ declare const DEV_ENV: {
47
+ readonly dataset: "RELYIO_DEV_DATASET";
48
+ readonly apiKey: "RELYIO_DEV_API_KEY";
49
+ readonly expiresAt: "RELYIO_DEV_EXPIRES_AT";
50
+ };
51
+ /** The `.relyio/dev.json` shape, as `relyio dev` writes it. All four keys; `expiresAt` nullable. */
52
+ interface DevContext {
53
+ /** Ephemeral sandbox dataset the app should read (`X-RelyIO-Dataset`). */
54
+ datasetId: string;
55
+ /** Scoped read-only preview key for the sandbox dataset (`X-API-Key`). */
56
+ previewApiKey: string;
57
+ /** Sandbox branch id — informational to the SDK; `relyio promote` identifies the sandbox by it. */
58
+ branchId: string;
59
+ /**
60
+ * ISO deadline of the sandbox's current lifecycle state, or null when unbounded.
61
+ *
62
+ * This is `sandbox.expiresAt` from the provisioning bundle — when the sandbox is due to be
63
+ * suspended or archived — not the preview key's own `expiresAt`. Past it, the dataset may be
64
+ * archived and the key deactivated, so the handshake names a sandbox that no longer answers.
65
+ */
66
+ expiresAt: string | null;
67
+ }
68
+ /** The credentials a carrier yields once it has been accepted. */
69
+ interface DevCredentials {
70
+ dataset: string;
71
+ apiKey: string;
72
+ }
73
+ /** Why a carrier's payload could not be understood. */
74
+ type DevUnreadableReason = 'not-json' | 'missing-fields' | 'bad-expiry';
75
+ /**
76
+ * What a carrier says, as a closed set of named states.
77
+ *
78
+ * There is deliberately no `null` or falsy arm, on any path. "Expired", "absent" and "corrupt" lead
79
+ * to different advice — refresh the key, start a sandbox, delete the file — and collapsing them to
80
+ * one falsy value is what let an app with a lapsed sandbox read **production** in silence and let
81
+ * `relyio promote` act on a stale identity. An absent input is a declared state, not a default.
82
+ */
83
+ type DevContextVerdict = {
84
+ state: 'active';
85
+ context: DevContext;
86
+ } | {
87
+ state: 'expired';
88
+ context: DevContext;
89
+ expiredAt: string;
90
+ } | {
91
+ state: 'unreadable';
92
+ reason: DevUnreadableReason;
93
+ } | {
94
+ state: 'absent';
95
+ };
96
+ /** What the env carrier says. It carries no `branchId`; only the file identifies a branch. */
97
+ type DevEnvVerdict = {
98
+ state: 'active';
99
+ credentials: DevCredentials;
100
+ expiresAt: string | null;
101
+ } | {
102
+ state: 'expired';
103
+ expiredAt: string;
104
+ } | {
105
+ state: 'unreadable';
106
+ reason: DevUnreadableReason;
107
+ } | {
108
+ state: 'absent';
109
+ };
110
+ /**
111
+ * Decide what the text of `.relyio/dev.json` says, against a caller-supplied clock.
112
+ *
113
+ * All three of `datasetId`, `previewApiKey` and `branchId` are **required**. `relyio dev` has
114
+ * always written all four keys and the spec documents all four, so a file missing one is corrupt
115
+ * rather than a narrower dialect — before REL-647 the CLI required `branchId` and the SDK did not,
116
+ * so one file read as absent to one binary and usable to the other.
117
+ *
118
+ * The clock is a parameter rather than a `Date.now()` inside, so the boundary is testable without
119
+ * faking time, and so this module stays pure.
120
+ */
121
+ declare function parseDevContextFile(raw: string, now: number): DevContextVerdict;
122
+ /**
123
+ * Build the `RELYIO_DEV_*` environment `relyio dev` injects into a wrapped child.
124
+ *
125
+ * The counterpart of {@link parseDevEnv}, and the reason the env names are single-sourced: the
126
+ * binary that writes them and the library that reads them now use one object. `expiresAt` is
127
+ * omitted rather than emitted empty when the sandbox is unbounded, so the variable's presence
128
+ * means "there is a deadline".
129
+ */
130
+ declare function buildDevEnv(context: Pick<DevContext, 'datasetId' | 'previewApiKey' | 'expiresAt'>): Record<string, string>;
131
+ /**
132
+ * Decide what the `RELYIO_DEV_*` environment says, against a caller-supplied clock.
133
+ *
134
+ * The env carrier names no branch, so it yields credentials rather than a {@link DevContext}. It
135
+ * applies the same deadline rule the file does — that equivalence is Gap 3, and the reason
136
+ * {@link DEV_ENV}`.expiresAt` exists at all.
137
+ *
138
+ * A deadline present but unreadable refuses the credentials. That is deliberate and is the same
139
+ * choice the file path makes: a wrapped process whose deadline we cannot read is not a process we
140
+ * can say is inside its window.
141
+ */
142
+ declare function parseDevEnv(env: Record<string, string | undefined> | undefined, now: number): DevEnvVerdict;
143
+
144
+ export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, type DevContext, type DevContextVerdict, type DevCredentials, type DevEnvVerdict, type DevUnreadableReason, buildDevEnv, parseDevContextFile, parseDevEnv };
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The `relyio dev` handshake: the one declaration of how a sandbox reaches a running app.
3
+ *
4
+ * `relyio dev` provisions an ephemeral sandbox and hands its connection details to the developer's
5
+ * app by two carriers, which `sandboxes-spec.md` presents as interchangeable:
6
+ *
7
+ * 1. **Env** — `relyio dev -- pnpm dev` injects `RELYIO_DEV_*` into the wrapped child process.
8
+ * 2. **File** — `.relyio/dev.json`, for an app started standalone beside the cockpit.
9
+ *
10
+ * Three consumers read this: the SDK (both carriers), and `relyio promote` (the file, to work out
11
+ * which sandbox this repo is developing against). Before REL-647 each had its own copy of the
12
+ * answer and the three disagreed — the file required `branchId` in the CLI and not in the SDK, an
13
+ * unparseable deadline read as *unbounded*, and **the env carrier had no expiry at all**, so
14
+ * `relyio dev` and `relyio dev -- pnpm dev` were not in fact interchangeable: the same lapsed
15
+ * sandbox stopped working under one and kept working for the life of the process under the other.
16
+ *
17
+ * So this module is the declaration, and it is deliberately **pure** — no `node:*`, no I/O, no
18
+ * clock of its own. Each consumer keeps the I/O shell it needs (the SDK cannot statically import
19
+ * `node:fs`; the CLI is async and knows the project root) and none of them keeps a rule.
20
+ *
21
+ * **On the direction of the dependency.** The CLI *writes* this file and the SDK *reads* it, so
22
+ * publishing the declaration from the reader inverts writer→reader, which is worth knowing when
23
+ * you change it. It is the right trade anyway: the SDK is already dependency-free and browser-safe
24
+ * by construction, so the declaration costs it nothing, while the CLI bundles every `@relyio/*`
25
+ * into its published artifact and can absorb the import. The alternative — a third package — buys
26
+ * a version stream for four constants and a parser.
27
+ */
28
+ /** Directory, relative to the project root, that holds the dev artifact. Hidden, git-ignored. */
29
+ declare const DEV_CONTEXT_DIR = ".relyio";
30
+ /** Filename of the dev artifact inside {@link DEV_CONTEXT_DIR}. */
31
+ declare const DEV_CONTEXT_FILENAME = "dev.json";
32
+ /**
33
+ * Path of the dev artifact relative to the project root, POSIX-separated.
34
+ *
35
+ * The one place this path is spelled. It is also exactly the `.gitignore` entry, which must use a
36
+ * forward slash on every platform — so the constant is a literal rather than a `path.join`, and
37
+ * callers that need a filesystem path join it onto their own root.
38
+ */
39
+ declare const DEV_CONTEXT_FILE = ".relyio/dev.json";
40
+ /**
41
+ * The environment variables `relyio dev` injects into a wrapped child process.
42
+ *
43
+ * `expiresAt` is the REL-647 addition. Without it the env carrier could not express a deadline, so
44
+ * it was exempt from the expiry the file carrier enforced — which is the whole of Gap 3.
45
+ */
46
+ declare const DEV_ENV: {
47
+ readonly dataset: "RELYIO_DEV_DATASET";
48
+ readonly apiKey: "RELYIO_DEV_API_KEY";
49
+ readonly expiresAt: "RELYIO_DEV_EXPIRES_AT";
50
+ };
51
+ /** The `.relyio/dev.json` shape, as `relyio dev` writes it. All four keys; `expiresAt` nullable. */
52
+ interface DevContext {
53
+ /** Ephemeral sandbox dataset the app should read (`X-RelyIO-Dataset`). */
54
+ datasetId: string;
55
+ /** Scoped read-only preview key for the sandbox dataset (`X-API-Key`). */
56
+ previewApiKey: string;
57
+ /** Sandbox branch id — informational to the SDK; `relyio promote` identifies the sandbox by it. */
58
+ branchId: string;
59
+ /**
60
+ * ISO deadline of the sandbox's current lifecycle state, or null when unbounded.
61
+ *
62
+ * This is `sandbox.expiresAt` from the provisioning bundle — when the sandbox is due to be
63
+ * suspended or archived — not the preview key's own `expiresAt`. Past it, the dataset may be
64
+ * archived and the key deactivated, so the handshake names a sandbox that no longer answers.
65
+ */
66
+ expiresAt: string | null;
67
+ }
68
+ /** The credentials a carrier yields once it has been accepted. */
69
+ interface DevCredentials {
70
+ dataset: string;
71
+ apiKey: string;
72
+ }
73
+ /** Why a carrier's payload could not be understood. */
74
+ type DevUnreadableReason = 'not-json' | 'missing-fields' | 'bad-expiry';
75
+ /**
76
+ * What a carrier says, as a closed set of named states.
77
+ *
78
+ * There is deliberately no `null` or falsy arm, on any path. "Expired", "absent" and "corrupt" lead
79
+ * to different advice — refresh the key, start a sandbox, delete the file — and collapsing them to
80
+ * one falsy value is what let an app with a lapsed sandbox read **production** in silence and let
81
+ * `relyio promote` act on a stale identity. An absent input is a declared state, not a default.
82
+ */
83
+ type DevContextVerdict = {
84
+ state: 'active';
85
+ context: DevContext;
86
+ } | {
87
+ state: 'expired';
88
+ context: DevContext;
89
+ expiredAt: string;
90
+ } | {
91
+ state: 'unreadable';
92
+ reason: DevUnreadableReason;
93
+ } | {
94
+ state: 'absent';
95
+ };
96
+ /** What the env carrier says. It carries no `branchId`; only the file identifies a branch. */
97
+ type DevEnvVerdict = {
98
+ state: 'active';
99
+ credentials: DevCredentials;
100
+ expiresAt: string | null;
101
+ } | {
102
+ state: 'expired';
103
+ expiredAt: string;
104
+ } | {
105
+ state: 'unreadable';
106
+ reason: DevUnreadableReason;
107
+ } | {
108
+ state: 'absent';
109
+ };
110
+ /**
111
+ * Decide what the text of `.relyio/dev.json` says, against a caller-supplied clock.
112
+ *
113
+ * All three of `datasetId`, `previewApiKey` and `branchId` are **required**. `relyio dev` has
114
+ * always written all four keys and the spec documents all four, so a file missing one is corrupt
115
+ * rather than a narrower dialect — before REL-647 the CLI required `branchId` and the SDK did not,
116
+ * so one file read as absent to one binary and usable to the other.
117
+ *
118
+ * The clock is a parameter rather than a `Date.now()` inside, so the boundary is testable without
119
+ * faking time, and so this module stays pure.
120
+ */
121
+ declare function parseDevContextFile(raw: string, now: number): DevContextVerdict;
122
+ /**
123
+ * Build the `RELYIO_DEV_*` environment `relyio dev` injects into a wrapped child.
124
+ *
125
+ * The counterpart of {@link parseDevEnv}, and the reason the env names are single-sourced: the
126
+ * binary that writes them and the library that reads them now use one object. `expiresAt` is
127
+ * omitted rather than emitted empty when the sandbox is unbounded, so the variable's presence
128
+ * means "there is a deadline".
129
+ */
130
+ declare function buildDevEnv(context: Pick<DevContext, 'datasetId' | 'previewApiKey' | 'expiresAt'>): Record<string, string>;
131
+ /**
132
+ * Decide what the `RELYIO_DEV_*` environment says, against a caller-supplied clock.
133
+ *
134
+ * The env carrier names no branch, so it yields credentials rather than a {@link DevContext}. It
135
+ * applies the same deadline rule the file does — that equivalence is Gap 3, and the reason
136
+ * {@link DEV_ENV}`.expiresAt` exists at all.
137
+ *
138
+ * A deadline present but unreadable refuses the credentials. That is deliberate and is the same
139
+ * choice the file path makes: a wrapped process whose deadline we cannot read is not a process we
140
+ * can say is inside its window.
141
+ */
142
+ declare function parseDevEnv(env: Record<string, string | undefined> | undefined, now: number): DevEnvVerdict;
143
+
144
+ export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, type DevContext, type DevContextVerdict, type DevCredentials, type DevEnvVerdict, type DevUnreadableReason, buildDevEnv, parseDevContextFile, parseDevEnv };
@@ -0,0 +1,4 @@
1
+ export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, buildDevEnv, parseDevContextFile, parseDevEnv } from '../chunk-BBUB7C2Z.js';
2
+ import '../chunk-XQ4QHWZE.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -1,5 +1,6 @@
1
- import { M as MergedRelyIOConfig, A as ApiPath, a as ApiMethod, G as PathParamsOf, r as ApiResponse, W as Wire, q as RequestConfig, B as BaseContent, c as WhereClause, e as SortOptions, f as ContentQueryResult, Q as QueryOptions, C as CreateInput, U as UpdateInput, S as SDKError, v as BaseValidationError, u as ValidationViolation, H as components, R as RelyIOConfig } from './index-BsUqCAu8.cjs';
2
- import { x as SchemaDefinition, y as SchemaContentTypeNames, a6 as InferContentType, K as SchemaAssetTypeNames, at as InferAssetType, z as SchemaSingletonNames, ac as InferSingleton, J as SchemaSettingsGroupNames, an as InferSettingsGroup, G as SchemaQueryNames, H as SchemaLocaleCodes } from './define-schema-DHvUCKwj.cjs';
1
+ import { M as MergedRelyIOConfig, A as ApiPath, a as ApiMethod, G as PathParamsOf, r as ApiResponse, W as Wire, q as RequestConfig, B as BaseContent, c as WhereClause, e as SortOptions, f as ContentQueryResult, Q as QueryOptions, C as CreateInput, U as UpdateInput, S as SDKError, v as BaseValidationError, u as ValidationViolation, H as components, R as RelyIOConfig } from './index-ulOrcfPa.cjs';
2
+ import { a as SchemaDefinition, b as SchemaContentTypeNames, h as SchemaAssetTypeNames, M as InferAssetType, c as SchemaSingletonNames, t as InferSingleton, g as SchemaSettingsGroupNames, E as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-BfXeR6K8.cjs';
3
+ import { J as InferContentType } from './define-content-type-CBfnTWSS.cjs';
3
4
 
4
5
  /**
5
6
  * What a call site supplies beside the route it named.
@@ -38,7 +39,7 @@ declare class HttpClient {
38
39
  private baseUrl;
39
40
  private defaultHeaders;
40
41
  private timeout;
41
- private retryConfig;
42
+ private retryPolicy;
42
43
  private debug;
43
44
  private logger?;
44
45
  private config;
@@ -56,7 +57,16 @@ declare class HttpClient {
56
57
  data: unknown;
57
58
  } ? Wire<P, M, T>['data'] : never>;
58
59
  /**
59
- * Make an HTTP request with retry logic
60
+ * Make an HTTP request, retrying only where a retry is safe.
61
+ *
62
+ * The headers are merged **once**, before the first attempt, and every attempt
63
+ * sends that same object. That is what makes a minted `Idempotency-Key` stable
64
+ * across the retries of one logical write: the service sees one key and
65
+ * answers the replay from the original outcome instead of applying it twice.
66
+ *
67
+ * The loop always makes one attempt. The incumbent's `while (attempt <
68
+ * maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
69
+ * accepts — and then dereferenced an unassigned `lastError`.
60
70
  */
61
71
  request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>>;
62
72
  /**
@@ -113,7 +123,6 @@ declare class HttpClient {
113
123
  private mergeRequestConfig;
114
124
  private buildQueryString;
115
125
  private headersToObject;
116
- private calculateRetryDelay;
117
126
  private sleep;
118
127
  private log;
119
128
  }
@@ -427,13 +436,20 @@ declare class ContentByIdBuilder<T extends BaseContent = BaseContent> {
427
436
  */
428
437
  interface RetryableWriteOptions {
429
438
  /**
430
- * A caller-chosen key that makes a retry of **this** write safe.
439
+ * A key that makes a retry of **this** write safe.
431
440
  *
432
441
  * A replay inside the service's window returns the original outcome rather
433
442
  * than applying twice. The service derives that response from committed state
434
443
  * pinned to the recorded version — it does not store bytes — so a replay after
435
444
  * the version has been pruned is refused `RESOURCE_EXPIRED` rather than
436
445
  * answered from a stale copy.
446
+ *
447
+ * **The SDK mints one when you do not.** It used to be caller-supplied and
448
+ * nothing else, which meant the default write carried no key while the retry
449
+ * loop replayed it anyway — the one mechanism that makes a replay safe was
450
+ * optional on the one path that needed it. Supply your own to make a key
451
+ * outlive the process: a job that may be restarted wants a key derived from
452
+ * the work, not one minted per call.
437
453
  */
438
454
  idempotencyKey?: string;
439
455
  }