@beam-network/sdk 0.2.3 → 0.2.5
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 +14 -1
- package/dist/provider-signing.d.ts +3 -1
- package/dist/provider-signing.js +42 -3
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -92,6 +92,10 @@ export class BeamClient {
|
|
|
92
92
|
preparedDestinations.forEach((preparedDestination, index) => {
|
|
93
93
|
destinationsById.set(preparedDestination.destination_id, input.destinations[index]);
|
|
94
94
|
});
|
|
95
|
+
const sourcesById = new Map();
|
|
96
|
+
preparedSources.forEach((preparedSource, index) => {
|
|
97
|
+
sourcesById.set(preparedSource.source_id, input.sources[index]);
|
|
98
|
+
});
|
|
95
99
|
const routes = [];
|
|
96
100
|
const multipartUploads = new Map();
|
|
97
101
|
try {
|
|
@@ -101,6 +105,10 @@ export class BeamClient {
|
|
|
101
105
|
if (!destination) {
|
|
102
106
|
throw new Error(`BeamCore returned unknown destination_id: ${target.destination_id}`);
|
|
103
107
|
}
|
|
108
|
+
const source = sourcesById.get(chunk.source_id);
|
|
109
|
+
if (!source) {
|
|
110
|
+
throw new Error(`BeamCore returned unknown source_id: ${chunk.source_id}`);
|
|
111
|
+
}
|
|
104
112
|
const metadata = target.metadata ?? {};
|
|
105
113
|
const finalObjectKey = typeof metadata.final_object_key === "string"
|
|
106
114
|
? metadata.final_object_key
|
|
@@ -142,6 +150,7 @@ export class BeamClient {
|
|
|
142
150
|
routes.push(await this.signProviderRoute({
|
|
143
151
|
chunk,
|
|
144
152
|
target,
|
|
153
|
+
source,
|
|
145
154
|
destination,
|
|
146
155
|
expiresIn,
|
|
147
156
|
upload,
|
|
@@ -181,6 +190,7 @@ export class BeamClient {
|
|
|
181
190
|
return signDestinationRoute({
|
|
182
191
|
chunk: input.chunk,
|
|
183
192
|
target: input.target,
|
|
193
|
+
source: input.source,
|
|
184
194
|
destination: input.destination,
|
|
185
195
|
expiresIn: input.expiresIn,
|
|
186
196
|
transferId: input.transferId,
|
|
@@ -200,11 +210,13 @@ export class BeamClient {
|
|
|
200
210
|
chunkIndex: input.chunk.chunk_index,
|
|
201
211
|
partNumber: input.partNumber
|
|
202
212
|
});
|
|
203
|
-
const
|
|
213
|
+
const copySourceRange = `bytes=0-${Math.max(0, input.chunk.chunk_size - 1)}`;
|
|
214
|
+
const { copyUrl, copySource } = await signUploadPartCopy(input.destination, input.finalObjectKey, stagingObjectKey, input.upload.uploadId, input.partNumber, input.expiresIn, copySourceRange);
|
|
204
215
|
const deleteUrl = await signDeleteObject(input.destination, stagingObjectKey, input.expiresIn);
|
|
205
216
|
return signDestinationRoute({
|
|
206
217
|
chunk: input.chunk,
|
|
207
218
|
target: input.target,
|
|
219
|
+
source: input.source,
|
|
208
220
|
destination: input.destination,
|
|
209
221
|
expiresIn: input.expiresIn,
|
|
210
222
|
uploadId: input.upload.uploadId,
|
|
@@ -220,6 +232,7 @@ export class BeamClient {
|
|
|
220
232
|
stagingObjectKey,
|
|
221
233
|
copyUrl,
|
|
222
234
|
copySource,
|
|
235
|
+
copySourceRange,
|
|
223
236
|
deleteUrl,
|
|
224
237
|
fetchImpl: this.fetchImpl
|
|
225
238
|
});
|
|
@@ -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
|
}>;
|
|
@@ -23,6 +23,7 @@ export declare function abortMultipartUpload(destination: ProviderDestinationCon
|
|
|
23
23
|
export declare function signDestinationRoute(input: {
|
|
24
24
|
chunk: ChunkSigningPlanItem;
|
|
25
25
|
target: ChunkDestinationSigningTarget;
|
|
26
|
+
source?: ProviderSourceConfig;
|
|
26
27
|
destination: ProviderDestinationConfig;
|
|
27
28
|
expiresIn: number;
|
|
28
29
|
uploadId?: string;
|
|
@@ -38,6 +39,7 @@ export declare function signDestinationRoute(input: {
|
|
|
38
39
|
stagingObjectKey?: string;
|
|
39
40
|
copyUrl?: string;
|
|
40
41
|
copySource?: string;
|
|
42
|
+
copySourceRange?: string;
|
|
41
43
|
deleteUrl?: string;
|
|
42
44
|
fetchImpl?: typeof fetch;
|
|
43
45
|
}): Promise<SignedChunkRoute>;
|
package/dist/provider-signing.js
CHANGED
|
@@ -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
|
}
|
|
@@ -153,15 +154,23 @@ export async function signDestinationRoute(input) {
|
|
|
153
154
|
useStagingPut: input.commitMethod === "upload_part_copy",
|
|
154
155
|
fetchImpl: input.fetchImpl
|
|
155
156
|
});
|
|
157
|
+
const sourceRoute = await signSourceRoute({
|
|
158
|
+
source: input.source,
|
|
159
|
+
fallbackUrl: input.chunk.source_url,
|
|
160
|
+
chunk: input.chunk,
|
|
161
|
+
expiresIn: input.expiresIn,
|
|
162
|
+
fetchImpl: input.fetchImpl
|
|
163
|
+
});
|
|
156
164
|
return {
|
|
157
165
|
source_id: input.chunk.source_id,
|
|
158
166
|
destination_id: input.target.destination_id,
|
|
159
167
|
chunk_index: input.chunk.chunk_index,
|
|
160
|
-
source_url:
|
|
168
|
+
source_url: sourceRoute.url,
|
|
161
169
|
dest_url: destUrl,
|
|
162
170
|
source_offset: input.chunk.source_offset,
|
|
163
171
|
chunk_size: input.chunk.chunk_size,
|
|
164
172
|
expires_at: expiresAtIso(input.expiresIn),
|
|
173
|
+
headers: sourceRoute.headers,
|
|
165
174
|
metadata: {
|
|
166
175
|
...(input.target.metadata ?? {}),
|
|
167
176
|
...(input.transferId ? { transfer_id: input.transferId } : {}),
|
|
@@ -171,6 +180,7 @@ export async function signDestinationRoute(input) {
|
|
|
171
180
|
...(input.stagingObjectKey ? { staging_object_key: input.stagingObjectKey } : {}),
|
|
172
181
|
...(input.copyUrl ? { copy_url: input.copyUrl } : {}),
|
|
173
182
|
...(input.copySource ? { copy_source: input.copySource } : {}),
|
|
183
|
+
...(input.copySourceRange ? { copy_source_range: input.copySourceRange } : {}),
|
|
174
184
|
...(input.deleteUrl ? { delete_url: input.deleteUrl } : {}),
|
|
175
185
|
...(input.uploadId ? { upload_id: input.uploadId } : {}),
|
|
176
186
|
...(input.partNumber ? { part_number: input.partNumber } : {}),
|
|
@@ -180,6 +190,35 @@ export async function signDestinationRoute(input) {
|
|
|
180
190
|
}
|
|
181
191
|
};
|
|
182
192
|
}
|
|
193
|
+
function rangeHeaderForChunk(chunk) {
|
|
194
|
+
const start = Math.max(0, Math.floor(chunk.source_offset));
|
|
195
|
+
const size = Math.max(1, Math.floor(chunk.chunk_size));
|
|
196
|
+
return `bytes=${start}-${start + size - 1}`;
|
|
197
|
+
}
|
|
198
|
+
async function signSourceRoute(input) {
|
|
199
|
+
const range = rangeHeaderForChunk(input.chunk);
|
|
200
|
+
if (!input.source) {
|
|
201
|
+
return { url: input.fallbackUrl, headers: { Range: range } };
|
|
202
|
+
}
|
|
203
|
+
if (isS3CompatibleProvider(input.source)) {
|
|
204
|
+
const client = createS3CompatibleClient(input.source);
|
|
205
|
+
return {
|
|
206
|
+
url: await getSignedUrl(client, new GetObjectCommand({
|
|
207
|
+
Bucket: input.source.bucket,
|
|
208
|
+
Key: input.source.key,
|
|
209
|
+
Range: range
|
|
210
|
+
}), { expiresIn: input.expiresIn }),
|
|
211
|
+
headers: { Range: range }
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (isHippiusProvider(input.source)) {
|
|
215
|
+
return {
|
|
216
|
+
url: await hippiusPresign(input.fetchImpl ?? globalThis.fetch, input.source.base_url ?? "https://api.hippius.com", input.source.api_token, input.source.bucket, input.source.key, "get", input.expiresIn),
|
|
217
|
+
headers: { Range: range }
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return unsupportedProviderConfig(input.source);
|
|
221
|
+
}
|
|
183
222
|
async function signDestinationUrl(input) {
|
|
184
223
|
if (isS3CompatibleProvider(input.destination)) {
|
|
185
224
|
const client = createS3CompatibleClient(input.destination);
|