@beam-network/sdk 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -192,8 +192,17 @@ export class BeamClient {
192
192
  if (!input.target.object_key) {
193
193
  throw new Error("destination signing target is missing object_key");
194
194
  }
195
- const { copyUrl, copySource } = await signUploadPartCopy(input.destination, input.finalObjectKey, input.target.object_key, input.upload.uploadId, input.partNumber, input.expiresIn);
196
- const deleteUrl = await signDeleteObject(input.destination, input.target.object_key, input.expiresIn);
195
+ const stagingObjectKey = buildStagingObjectKey({
196
+ finalObjectKey: input.finalObjectKey,
197
+ transferId: input.transferId,
198
+ sourceId: input.chunk.source_id,
199
+ destinationId: input.target.destination_id,
200
+ chunkIndex: input.chunk.chunk_index,
201
+ partNumber: input.partNumber
202
+ });
203
+ const copySourceRange = `bytes=0-${Math.max(0, input.chunk.chunk_size - 1)}`;
204
+ const { copyUrl, copySource } = await signUploadPartCopy(input.destination, input.finalObjectKey, stagingObjectKey, input.upload.uploadId, input.partNumber, input.expiresIn, copySourceRange);
205
+ const deleteUrl = await signDeleteObject(input.destination, stagingObjectKey, input.expiresIn);
197
206
  return signDestinationRoute({
198
207
  chunk: input.chunk,
199
208
  target: input.target,
@@ -209,9 +218,10 @@ export class BeamClient {
209
218
  multipartGroupId: input.upload.multipartGroupId,
210
219
  multipartCreatedAt: input.upload.multipartCreatedAt,
211
220
  commitMethod: "upload_part_copy",
212
- stagingObjectKey: input.target.object_key,
221
+ stagingObjectKey,
213
222
  copyUrl,
214
223
  copySource,
224
+ copySourceRange,
215
225
  deleteUrl,
216
226
  fetchImpl: this.fetchImpl
217
227
  });
@@ -292,6 +302,19 @@ function normalizeBaseUrl(value) {
292
302
  function compact(input) {
293
303
  return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
294
304
  }
305
+ function buildStagingObjectKey(input) {
306
+ const base = input.finalObjectKey.replace(/\/+$/, "") || "object";
307
+ return [
308
+ `${base}.beam-staging`,
309
+ safeObjectKeySegment(input.transferId),
310
+ safeObjectKeySegment(input.sourceId),
311
+ safeObjectKeySegment(input.destinationId),
312
+ `part-${input.partNumber}-chunk-${input.chunkIndex}`
313
+ ].join("/");
314
+ }
315
+ function safeObjectKeySegment(value) {
316
+ return encodeURIComponent(value).replace(/%2F/gi, "_");
317
+ }
295
318
  function validateId(value, name) {
296
319
  if (!value || value.includes("/") || value.includes("..")) {
297
320
  throw new Error(`${name} is invalid`);
@@ -14,7 +14,7 @@ export declare function createMultipartUpload(destination: ProviderDestinationCo
14
14
  export declare function signCompleteMultipartUpload(destination: ProviderDestinationConfig, objectKey: string, uploadId: string, expiresIn: number): Promise<string>;
15
15
  export declare function signAbortMultipartUpload(destination: ProviderDestinationConfig, objectKey: string, uploadId: string, expiresIn: number): Promise<string>;
16
16
  export declare function signListMultipartUpload(destination: ProviderDestinationConfig, objectKey: string, uploadId: string, expiresIn: number): Promise<string>;
17
- export declare function signUploadPartCopy(destination: ProviderDestinationConfig, finalObjectKey: string, stagingObjectKey: string, uploadId: string, partNumber: number, expiresIn: number): Promise<{
17
+ export declare function signUploadPartCopy(destination: ProviderDestinationConfig, finalObjectKey: string, stagingObjectKey: string, uploadId: string, partNumber: number, expiresIn: number, copySourceRange?: string): Promise<{
18
18
  copyUrl: string;
19
19
  copySource: string;
20
20
  }>;
@@ -38,6 +38,7 @@ export declare function signDestinationRoute(input: {
38
38
  stagingObjectKey?: string;
39
39
  copyUrl?: string;
40
40
  copySource?: string;
41
+ copySourceRange?: string;
41
42
  deleteUrl?: string;
42
43
  fetchImpl?: typeof fetch;
43
44
  }): Promise<SignedChunkRoute>;
@@ -103,7 +103,7 @@ export async function signListMultipartUpload(destination, objectKey, uploadId,
103
103
  }
104
104
  throw new Error(`multipart list-parts is not supported for ${destination.provider}`);
105
105
  }
106
- export async function signUploadPartCopy(destination, finalObjectKey, stagingObjectKey, uploadId, partNumber, expiresIn) {
106
+ export async function signUploadPartCopy(destination, finalObjectKey, stagingObjectKey, uploadId, partNumber, expiresIn, copySourceRange) {
107
107
  if (isS3CompatibleProvider(destination)) {
108
108
  const client = createS3CompatibleClient(destination);
109
109
  const copySource = copySourceHeader(destination, stagingObjectKey);
@@ -114,7 +114,8 @@ export async function signUploadPartCopy(destination, finalObjectKey, stagingObj
114
114
  Key: finalObjectKey,
115
115
  UploadId: uploadId,
116
116
  PartNumber: partNumber,
117
- CopySource: copySource
117
+ CopySource: copySource,
118
+ CopySourceRange: copySourceRange
118
119
  }), { expiresIn })
119
120
  };
120
121
  }
@@ -135,11 +136,14 @@ export async function abortMultipartUpload(destination, objectKey, uploadId) {
135
136
  throw new Error(`multipart abort is not supported for ${destination.provider}`);
136
137
  }
137
138
  export async function signDestinationRoute(input) {
138
- const objectKey = input.target.object_key;
139
- if (!objectKey) {
139
+ const targetObjectKey = input.target.object_key;
140
+ if (!targetObjectKey) {
140
141
  throw new Error("destination signing target is missing object_key");
141
142
  }
142
- const uploadPartObjectKey = input.multipartObjectKey ?? objectKey;
143
+ const objectKey = input.commitMethod === "upload_part_copy" && input.stagingObjectKey
144
+ ? input.stagingObjectKey
145
+ : targetObjectKey;
146
+ const uploadPartObjectKey = input.multipartObjectKey ?? targetObjectKey;
143
147
  const destUrl = await signDestinationUrl({
144
148
  destination: input.destination,
145
149
  objectKey,
@@ -168,6 +172,7 @@ export async function signDestinationRoute(input) {
168
172
  ...(input.stagingObjectKey ? { staging_object_key: input.stagingObjectKey } : {}),
169
173
  ...(input.copyUrl ? { copy_url: input.copyUrl } : {}),
170
174
  ...(input.copySource ? { copy_source: input.copySource } : {}),
175
+ ...(input.copySourceRange ? { copy_source_range: input.copySourceRange } : {}),
171
176
  ...(input.deleteUrl ? { delete_url: input.deleteUrl } : {}),
172
177
  ...(input.uploadId ? { upload_id: input.uploadId } : {}),
173
178
  ...(input.partNumber ? { part_number: input.partNumber } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beam-network/sdk",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "TypeScript SDK for BEAM transfer creation and management.",
5
5
  "type": "module",
6
6
  "license": "MIT",