@rehearsal-db/core 0.1.0-beta.14 → 0.1.0-beta.16

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 (236) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +1 -0
  3. package/dist/package.json +101 -0
  4. package/dist/scripts/install/create_root_config.d.mts +3 -0
  5. package/dist/scripts/install/create_root_config.mjs +13 -0
  6. package/dist/scripts/runtime/manage_database.d.mts +6 -0
  7. package/{scripts → dist/scripts}/runtime/manage_database.mjs +6 -8
  8. package/dist/src/application/session.d.mts +96 -0
  9. package/dist/src/application/session.mjs +380 -0
  10. package/dist/src/baseline/artifact.d.mts +119 -0
  11. package/dist/src/baseline/artifact.mjs +522 -0
  12. package/dist/src/baseline/builder.d.mts +19 -0
  13. package/dist/src/baseline/builder.mjs +142 -0
  14. package/dist/src/baseline/input_discovery.d.mts +13 -0
  15. package/dist/src/baseline/input_discovery.mjs +149 -0
  16. package/dist/src/baseline/policy_review.d.mts +56 -0
  17. package/dist/src/baseline/policy_review.mjs +73 -0
  18. package/dist/src/baseline/preparation.d.mts +63 -0
  19. package/dist/src/baseline/preparation.mjs +295 -0
  20. package/dist/src/baseline/privacy_contract.d.mts +147 -0
  21. package/dist/src/baseline/privacy_contract.mjs +2 -0
  22. package/dist/src/baseline/privacy_dependency_graph.d.mts +7 -0
  23. package/dist/src/baseline/privacy_dependency_graph.mjs +110 -0
  24. package/dist/src/baseline/privacy_engine.d.mts +5 -0
  25. package/dist/src/baseline/privacy_engine.mjs +4 -0
  26. package/dist/src/baseline/privacy_key.d.mts +7 -0
  27. package/dist/src/baseline/privacy_key.mjs +42 -0
  28. package/dist/src/baseline/privacy_pipeline.d.mts +7 -0
  29. package/dist/src/baseline/privacy_pipeline.mjs +127 -0
  30. package/dist/src/baseline/privacy_policy.d.mts +6 -0
  31. package/dist/src/baseline/privacy_policy.mjs +237 -0
  32. package/dist/src/baseline/privacy_recipe_validation.d.mts +5 -0
  33. package/dist/src/baseline/privacy_recipe_validation.mjs +289 -0
  34. package/dist/src/baseline/privacy_rule_registry.d.mts +18 -0
  35. package/dist/src/baseline/privacy_rule_registry.mjs +143 -0
  36. package/dist/src/baseline/privacy_structured_json.d.mts +66 -0
  37. package/dist/src/baseline/privacy_structured_json.mjs +464 -0
  38. package/dist/src/baseline/privacy_transforms.d.mts +18 -0
  39. package/dist/src/baseline/privacy_transforms.mjs +142 -0
  40. package/dist/src/baseline/privacy_validation_shared.d.mts +31 -0
  41. package/dist/src/baseline/privacy_validation_shared.mjs +127 -0
  42. package/dist/src/baseline/sanitization_policy.d.mts +69 -0
  43. package/dist/src/baseline/sanitization_policy.mjs +227 -0
  44. package/dist/src/baseline/schema_snapshot.d.mts +19 -0
  45. package/dist/src/baseline/schema_snapshot.mjs +79 -0
  46. package/dist/src/cli/application_command_handlers.d.mts +8 -0
  47. package/dist/src/cli/application_command_handlers.mjs +52 -0
  48. package/dist/src/cli/arguments.d.mts +38 -0
  49. package/dist/src/cli/arguments.mjs +128 -0
  50. package/dist/src/cli/basic_command_handlers.d.mts +4 -0
  51. package/dist/src/cli/basic_command_handlers.mjs +56 -0
  52. package/dist/src/cli/cli_commands.d.mts +14 -0
  53. package/dist/src/cli/cli_commands.mjs +32 -0
  54. package/dist/src/cli/command_contract.d.mts +57 -0
  55. package/dist/src/cli/command_contract.mjs +39 -0
  56. package/dist/src/cli/command_output.d.mts +12 -0
  57. package/dist/src/cli/command_output.mjs +20 -0
  58. package/dist/src/cli/command_registry.d.mts +7 -0
  59. package/dist/src/cli/command_registry.mjs +14 -0
  60. package/dist/src/cli/guided.d.mts +53 -0
  61. package/dist/src/cli/guided.mjs +719 -0
  62. package/dist/src/cli/identity_command_handlers.d.mts +8 -0
  63. package/dist/src/cli/identity_command_handlers.mjs +43 -0
  64. package/dist/src/cli/init_command.d.mts +21 -0
  65. package/dist/src/cli/init_command.mjs +90 -0
  66. package/dist/src/cli/inspection_command_handlers.d.mts +3 -0
  67. package/dist/src/cli/inspection_command_handlers.mjs +79 -0
  68. package/dist/src/cli/project_command_handlers.d.mts +11 -0
  69. package/dist/src/cli/project_command_handlers.mjs +92 -0
  70. package/dist/src/cli/project_commands.d.mts +159 -0
  71. package/dist/src/cli/project_commands.mjs +183 -0
  72. package/dist/src/cli/rehearsal.d.mts +7 -0
  73. package/dist/src/cli/rehearsal.mjs +190 -0
  74. package/dist/src/cli/renderers.d.mts +299 -0
  75. package/dist/src/cli/renderers.mjs +554 -0
  76. package/dist/src/cli/runtime_action_handlers.d.mts +12 -0
  77. package/dist/src/cli/runtime_action_handlers.mjs +201 -0
  78. package/dist/src/cli/runtime_commands.d.mts +269 -0
  79. package/dist/src/cli/runtime_commands.mjs +601 -0
  80. package/dist/src/cli/source_command_handlers.d.mts +8 -0
  81. package/dist/src/cli/source_command_handlers.mjs +62 -0
  82. package/dist/src/cli/source_commands.d.mts +436 -0
  83. package/dist/src/cli/source_commands.mjs +301 -0
  84. package/dist/src/cli/terminal.d.mts +59 -0
  85. package/dist/src/cli/terminal.mjs +230 -0
  86. package/dist/src/identity/claim.d.mts +5 -0
  87. package/dist/src/identity/claim.mjs +4 -0
  88. package/dist/src/identity/claim_contract.d.mts +135 -0
  89. package/dist/src/identity/claim_contract.mjs +6 -0
  90. package/dist/src/identity/claim_executor.d.mts +10 -0
  91. package/dist/src/identity/claim_executor.mjs +358 -0
  92. package/dist/src/identity/claim_identity_lookup.d.mts +17 -0
  93. package/dist/src/identity/claim_identity_lookup.mjs +125 -0
  94. package/dist/src/identity/claim_plan.d.mts +8 -0
  95. package/dist/src/identity/claim_plan.mjs +61 -0
  96. package/dist/src/identity/claim_policy.d.mts +3 -0
  97. package/dist/src/identity/claim_policy.mjs +377 -0
  98. package/dist/src/identity/claim_sql.d.mts +10 -0
  99. package/dist/src/identity/claim_sql.mjs +46 -0
  100. package/dist/src/identity/claim_verification.d.mts +13 -0
  101. package/dist/src/identity/claim_verification.mjs +35 -0
  102. package/dist/src/identity/provider_configuration.d.mts +37 -0
  103. package/dist/src/identity/provider_configuration.mjs +132 -0
  104. package/dist/src/identity/storage.d.mts +21 -0
  105. package/dist/src/identity/storage.mjs +122 -0
  106. package/dist/src/index.d.mts +4 -0
  107. package/dist/src/index.mjs +3 -0
  108. package/dist/src/project/configuration.d.mts +13 -0
  109. package/dist/src/project/configuration.mjs +9 -0
  110. package/dist/src/project/configuration_contract.d.mts +125 -0
  111. package/dist/src/project/configuration_contract.mjs +27 -0
  112. package/dist/src/project/configuration_discovery.d.mts +7 -0
  113. package/dist/src/project/configuration_discovery.mjs +37 -0
  114. package/dist/src/project/configuration_normalization.d.mts +107 -0
  115. package/dist/src/project/configuration_normalization.mjs +302 -0
  116. package/dist/src/project/configuration_rendering.d.mts +14 -0
  117. package/dist/src/project/configuration_rendering.mjs +224 -0
  118. package/dist/src/project/configuration_resolution.d.mts +125 -0
  119. package/dist/src/project/configuration_resolution.mjs +81 -0
  120. package/dist/src/project/configuration_schema.d.mts +22 -0
  121. package/dist/src/project/configuration_schema.mjs +160 -0
  122. package/dist/src/project/configuration_validation.d.mts +22 -0
  123. package/dist/src/project/configuration_validation.mjs +136 -0
  124. package/dist/src/project/install_scaffold.d.mts +42 -0
  125. package/dist/src/project/install_scaffold.mjs +263 -0
  126. package/dist/src/project/project_detection.d.mts +14 -0
  127. package/dist/src/project/project_detection.mjs +47 -0
  128. package/dist/src/project/setup.d.mts +87 -0
  129. package/dist/src/project/setup.mjs +414 -0
  130. package/dist/src/project/support_report.d.mts +88 -0
  131. package/dist/src/project/support_report.mjs +83 -0
  132. package/dist/src/runtime/cleanup.d.mts +85 -0
  133. package/dist/src/runtime/cleanup.mjs +311 -0
  134. package/dist/src/runtime/lifecycle_engine.d.mts +63 -0
  135. package/dist/src/runtime/lifecycle_engine.mjs +114 -0
  136. package/dist/src/runtime/migration_history.d.mts +51 -0
  137. package/dist/src/runtime/migration_history.mjs +170 -0
  138. package/dist/src/runtime/plan.d.mts +134 -0
  139. package/dist/src/runtime/plan.mjs +637 -0
  140. package/dist/src/runtime/policy.d.mts +66 -0
  141. package/dist/src/runtime/policy.mjs +369 -0
  142. package/dist/src/runtime/restore.d.mts +22 -0
  143. package/dist/src/runtime/restore.mjs +276 -0
  144. package/dist/src/runtime/service_environment.d.mts +11 -0
  145. package/dist/src/runtime/service_environment.mjs +58 -0
  146. package/dist/src/runtime/topology.d.mts +51 -0
  147. package/dist/src/runtime/topology.mjs +128 -0
  148. package/dist/src/shared/diagnostics.d.mts +97 -0
  149. package/dist/src/shared/diagnostics.mjs +170 -0
  150. package/dist/src/shared/human_output.d.mts +2 -0
  151. package/{src → dist/src}/shared/human_output.mjs +1 -3
  152. package/dist/src/shared/node_runtime.d.mts +14 -0
  153. package/dist/src/shared/node_runtime.mjs +25 -0
  154. package/dist/src/shared/operation_guard.d.mts +22 -0
  155. package/dist/src/shared/operation_guard.mjs +150 -0
  156. package/dist/src/shared/process_environment.d.mts +15 -0
  157. package/dist/src/shared/process_environment.mjs +50 -0
  158. package/dist/src/source/access.d.mts +165 -0
  159. package/dist/src/source/access.mjs +602 -0
  160. package/dist/src/source/asset_transfer.d.mts +27 -0
  161. package/dist/src/source/asset_transfer.mjs +202 -0
  162. package/dist/src/source/baseline.d.mts +66 -0
  163. package/dist/src/source/baseline.mjs +372 -0
  164. package/dist/src/source/external_reader.d.mts +42 -0
  165. package/dist/src/source/external_reader.mjs +278 -0
  166. package/dist/src/source/postgresql_access.d.mts +86 -0
  167. package/dist/src/source/postgresql_access.mjs +454 -0
  168. package/dist/src/source/privacy_paths.d.mts +10 -0
  169. package/dist/src/source/privacy_paths.mjs +27 -0
  170. package/dist/src/targets/driver.d.mts +2 -0
  171. package/dist/src/targets/driver.mjs +13 -0
  172. package/dist/src/targets/postgresql.d.mts +5 -0
  173. package/dist/src/targets/postgresql.mjs +620 -0
  174. package/dist/src/targets/supabase.d.mts +8 -0
  175. package/dist/src/targets/supabase.mjs +627 -0
  176. package/dist/src/targets/supabase_environment.d.mts +49 -0
  177. package/dist/src/targets/supabase_environment.mjs +162 -0
  178. package/dist/src/targets/target.d.mts +33 -0
  179. package/dist/src/targets/target.mjs +39 -0
  180. package/docs/README.md +1 -0
  181. package/docs/architecture.md +133 -10
  182. package/docs/configuration.md +9 -3
  183. package/docs/index.md +1 -0
  184. package/docs/releasing.md +8 -3
  185. package/docs/typescript.md +134 -0
  186. package/package.json +36 -29
  187. package/types/configuration.d.mts +5 -0
  188. package/scripts/install/create_root_config.mjs +0 -19
  189. package/src/README.md +0 -17
  190. package/src/application/session.mjs +0 -435
  191. package/src/baseline/artifact.mjs +0 -684
  192. package/src/baseline/builder.mjs +0 -164
  193. package/src/baseline/input_discovery.mjs +0 -155
  194. package/src/baseline/policy_review.mjs +0 -92
  195. package/src/baseline/preparation.mjs +0 -323
  196. package/src/baseline/privacy_engine.mjs +0 -1399
  197. package/src/baseline/privacy_structured_json.mjs +0 -554
  198. package/src/baseline/sanitization_policy.mjs +0 -299
  199. package/src/baseline/schema_snapshot.mjs +0 -113
  200. package/src/cli/arguments.mjs +0 -126
  201. package/src/cli/guided.mjs +0 -814
  202. package/src/cli/init_command.mjs +0 -94
  203. package/src/cli/rehearsal.mjs +0 -972
  204. package/src/cli/renderers.mjs +0 -638
  205. package/src/cli/runtime_commands.mjs +0 -707
  206. package/src/cli/source_commands.mjs +0 -355
  207. package/src/cli/terminal.mjs +0 -275
  208. package/src/identity/claim.mjs +0 -1165
  209. package/src/identity/provider_configuration.mjs +0 -177
  210. package/src/identity/storage.mjs +0 -165
  211. package/src/project/configuration.d.mts +0 -164
  212. package/src/project/configuration.mjs +0 -1337
  213. package/src/project/install_scaffold.mjs +0 -325
  214. package/src/project/setup.mjs +0 -474
  215. package/src/project/support_report.mjs +0 -105
  216. package/src/runtime/cleanup.mjs +0 -381
  217. package/src/runtime/migration_history.mjs +0 -220
  218. package/src/runtime/plan.mjs +0 -722
  219. package/src/runtime/policy.mjs +0 -438
  220. package/src/runtime/restore.mjs +0 -337
  221. package/src/runtime/service_environment.mjs +0 -82
  222. package/src/runtime/topology.mjs +0 -177
  223. package/src/shared/diagnostics.mjs +0 -207
  224. package/src/shared/node_runtime.mjs +0 -31
  225. package/src/shared/operation_guard.mjs +0 -162
  226. package/src/shared/process_environment.mjs +0 -68
  227. package/src/source/access.mjs +0 -798
  228. package/src/source/asset_transfer.mjs +0 -259
  229. package/src/source/baseline.mjs +0 -482
  230. package/src/source/external_reader.mjs +0 -368
  231. package/src/source/postgresql_access.mjs +0 -638
  232. package/src/source/privacy_paths.mjs +0 -38
  233. package/src/targets/postgresql.mjs +0 -808
  234. package/src/targets/supabase.mjs +0 -840
  235. package/src/targets/supabase_environment.mjs +0 -229
  236. package/src/targets/target.mjs +0 -66
@@ -1,259 +0,0 @@
1
- /** Stream only explicitly approved Supabase Storage objects into a baseline. */
2
-
3
- const BUCKET = /^[a-z0-9][a-z0-9.-]{0,99}$/u;
4
- const LOOPBACK = new Set(["127.0.0.1", "::1", "localhost"]);
5
- const MAXIMUM_STORAGE_DEPTH = 64;
6
- const MAXIMUM_STORAGE_PATH_BYTES = 4096;
7
-
8
- const safeBaseUrl = (value) => {
9
- let url;
10
- try {
11
- url = new URL(value);
12
- } catch {
13
- throw new Error("Asset reader URL is invalid.");
14
- }
15
- if (
16
- url.protocol !== "https:" &&
17
- !(url.protocol === "http:" && LOOPBACK.has(url.hostname))
18
- ) {
19
- throw new Error(
20
- "Asset reader URL must use HTTPS or a loopback HTTP endpoint.",
21
- );
22
- }
23
- url.username = "";
24
- url.password = "";
25
- url.search = "";
26
- url.hash = "";
27
- return url.toString().replace(/\/$/u, "");
28
- };
29
-
30
- const safePath = (value, label) => {
31
- if (
32
- typeof value !== "string" ||
33
- !value ||
34
- value.startsWith("/") ||
35
- value.split("/").some((part) => !part || part === "." || part === "..")
36
- ) {
37
- throw new Error(`${label} is unsafe.`);
38
- }
39
- if (Buffer.byteLength(value) > MAXIMUM_STORAGE_PATH_BYTES) {
40
- throw new Error(`${label} is too long.`);
41
- }
42
- return value;
43
- };
44
-
45
- const safeInventoryName = (value) => {
46
- const name = safePath(value, "Storage inventory name");
47
- if (name.includes("/") || name.includes("\\")) {
48
- throw new Error("Storage inventory name is not a single path segment.");
49
- }
50
- return name;
51
- };
52
-
53
- const readError = (label, response) =>
54
- new Error(
55
- `${label} failed with HTTP ${response.status}; response content was withheld.`,
56
- );
57
-
58
- const canonicalContentType = (...values) => {
59
- for (const value of values) {
60
- if (typeof value !== "string") continue;
61
- const mediaType = value.split(";", 1)[0].trim().toLowerCase();
62
- if (
63
- /^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/u.test(
64
- mediaType,
65
- )
66
- ) {
67
- return mediaType;
68
- }
69
- }
70
- return "application/octet-stream";
71
- };
72
-
73
- const responseBody = async function* ({
74
- response,
75
- expectedBytes,
76
- maximumBytes,
77
- }) {
78
- if (!response.body) throw new Error("Storage object response has no body.");
79
- let bytes = 0;
80
- for await (const chunk of response.body) {
81
- const buffer = Buffer.from(chunk);
82
- bytes += buffer.length;
83
- if (bytes > maximumBytes)
84
- throw new Error("Storage object exceeded its reviewed size limit.");
85
- yield buffer;
86
- }
87
- if (expectedBytes !== null && bytes !== expectedBytes) {
88
- throw new Error("Storage object size changed during transfer.");
89
- }
90
- };
91
-
92
- export const streamApprovedSupabaseAssets = async function* ({
93
- baseUrl,
94
- token,
95
- declarations,
96
- fetchImplementation = fetch,
97
- maximumObjects = 10_000,
98
- maximumObjectBytes = 50 * 1024 * 1024,
99
- maximumTotalBytes = 2 * 1024 * 1024 * 1024,
100
- pathMapper,
101
- }) {
102
- const endpoint = safeBaseUrl(baseUrl);
103
- if (typeof token !== "string" || token.length < 16) {
104
- throw new Error("A scoped Storage reader token is required.");
105
- }
106
- if (!Array.isArray(declarations) || declarations.length === 0) return;
107
- let objectCount = 0;
108
- let totalBytes = 0;
109
- const inventoryPaths = new Set();
110
- for (const declaration of declarations) {
111
- if (!BUCKET.test(declaration.bucket ?? "")) {
112
- throw new Error("Approved Storage bucket is invalid.");
113
- }
114
- const approvedPrefix = safePath(
115
- declaration.prefix.replace(/\/$/u, ""),
116
- "Approved Storage prefix",
117
- );
118
- const prefixes = [{ path: approvedPrefix, depth: 0 }];
119
- const scheduledPrefixes = new Set([approvedPrefix]);
120
- for (let prefixIndex = 0; prefixIndex < prefixes.length; prefixIndex += 1) {
121
- const prefix = prefixes[prefixIndex];
122
- let offset = 0;
123
- while (true) {
124
- const response = await fetchImplementation(
125
- `${endpoint}/storage/v1/object/list/${encodeURIComponent(declaration.bucket)}`,
126
- {
127
- method: "POST",
128
- headers: {
129
- authorization: `Bearer ${token}`,
130
- "content-type": "application/json",
131
- },
132
- body: JSON.stringify({
133
- prefix: prefix.path,
134
- limit: 100,
135
- offset,
136
- sortBy: { column: "name", order: "asc" },
137
- }),
138
- },
139
- );
140
- if (!response.ok) throw readError("Storage inventory", response);
141
- const inventory = await response.json();
142
- if (!Array.isArray(inventory))
143
- throw new Error("Storage inventory response is invalid.");
144
- for (const object of inventory) {
145
- if (
146
- object === null ||
147
- typeof object !== "object" ||
148
- Array.isArray(object)
149
- ) {
150
- throw new Error("Storage inventory entry is invalid.");
151
- }
152
- const entryName = safeInventoryName(object.name);
153
- const name = safePath(
154
- `${prefix.path}/${entryName}`,
155
- "Storage object path",
156
- );
157
- if (!name.startsWith(`${approvedPrefix}/`))
158
- throw new Error("Storage inventory escaped its approved prefix.");
159
- const inventoryKey = `${declaration.bucket}\0${name}`;
160
- if (inventoryPaths.has(inventoryKey)) {
161
- throw new Error("Storage inventory returned a duplicate path.");
162
- }
163
- inventoryPaths.add(inventoryKey);
164
- objectCount += 1;
165
- if (objectCount > maximumObjects) {
166
- throw new Error(
167
- "Storage inventory exceeds its reviewed transfer boundary.",
168
- );
169
- }
170
- const directory = object.id === null && object.metadata === null;
171
- if (directory) {
172
- if (prefix.depth >= MAXIMUM_STORAGE_DEPTH) {
173
- throw new Error(
174
- "Storage inventory exceeds its safe folder depth.",
175
- );
176
- }
177
- if (scheduledPrefixes.has(name)) {
178
- throw new Error("Storage inventory returned a duplicate folder.");
179
- }
180
- scheduledPrefixes.add(name);
181
- prefixes.push({ path: name, depth: prefix.depth + 1 });
182
- continue;
183
- }
184
- const expectedBytes = Number(
185
- object.metadata?.size ?? object.metadata?.contentLength,
186
- );
187
- if (!Number.isSafeInteger(expectedBytes) || expectedBytes < 0) {
188
- throw new Error("Storage inventory omitted an exact object size.");
189
- }
190
- if (expectedBytes > maximumObjectBytes) {
191
- throw new Error("Storage object exceeds its reviewed size limit.");
192
- }
193
- totalBytes += expectedBytes;
194
- if (totalBytes > maximumTotalBytes) {
195
- throw new Error(
196
- "Storage inventory exceeds its reviewed transfer boundary.",
197
- );
198
- }
199
- const encodedPath = name.split("/").map(encodeURIComponent).join("/");
200
- const download = await fetchImplementation(
201
- `${endpoint}/storage/v1/object/authenticated/${encodeURIComponent(declaration.bucket)}/${encodedPath}`,
202
- {
203
- headers: {
204
- authorization: `Bearer ${token}`,
205
- ...(object.metadata?.eTag
206
- ? { "if-match": object.metadata.eTag }
207
- : {}),
208
- },
209
- },
210
- );
211
- if (!download.ok)
212
- throw readError("Storage object transfer", download);
213
- const responseEtag = download.headers.get("etag");
214
- if (object.metadata?.eTag) {
215
- if (!responseEtag) {
216
- throw new Error(
217
- "Storage transfer omitted the reviewed object version.",
218
- );
219
- }
220
- if (responseEtag !== object.metadata.eTag) {
221
- throw new Error(
222
- "Storage object changed between inventory and transfer.",
223
- );
224
- }
225
- }
226
- if (declaration.pathMapping && typeof pathMapper !== "function") {
227
- throw new Error(
228
- "Storage path mapping requires the package-owned privacy mapper.",
229
- );
230
- }
231
- const objectPath = declaration.pathMapping
232
- ? safePath(
233
- pathMapper({
234
- mapping: declaration.pathMapping,
235
- value: name,
236
- }),
237
- "Mapped Storage object path",
238
- )
239
- : name;
240
- yield {
241
- bucket: declaration.bucket,
242
- objectPath,
243
- contentType: canonicalContentType(
244
- object.metadata?.mimetype,
245
- download.headers.get("content-type"),
246
- ),
247
- content: responseBody({
248
- response: download,
249
- expectedBytes,
250
- maximumBytes: maximumObjectBytes,
251
- }),
252
- };
253
- }
254
- if (inventory.length < 100) break;
255
- offset += inventory.length;
256
- }
257
- }
258
- }
259
- };