@beam-network/sdk 0.2.22 → 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.
@@ -1,4 +1,4 @@
1
- import { AbortMultipartUploadCommand, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, ListPartsCommand, PutObjectCommand, S3Client, UploadPartCopyCommand, UploadPartCommand } from "@aws-sdk/client-s3";
1
+ import { AbortMultipartUploadCommand, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, ListPartsCommand, PutObjectCommand, S3Client, UploadPartCopyCommand } from "@aws-sdk/client-s3";
2
2
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
3
3
  export function nowIso() {
4
4
  return new Date().toISOString();
@@ -113,16 +113,27 @@ export function prepareProviderDestination(destination, options = {}) {
113
113
  }
114
114
  return unsupportedProviderConfig(destination);
115
115
  }
116
- export async function createMultipartUpload(destination, objectKey) {
117
- if (isS3CompatibleProvider(destination)) {
118
- const client = createS3CompatibleClient(destination);
119
- const response = await client.send(new CreateMultipartUploadCommand({ Bucket: destination.bucket, Key: objectKey }));
116
+ export async function createMultipartUpload(input) {
117
+ if (isS3CompatibleProvider(input.destination)) {
118
+ const client = createS3CompatibleClient(input.destination);
119
+ const response = await client.send(new CreateMultipartUploadCommand({
120
+ Bucket: input.destination.bucket,
121
+ Key: input.objectKey,
122
+ Metadata: input.metadata
123
+ }));
120
124
  if (!response.UploadId) {
121
- throw new Error(`provider did not return UploadId for ${objectKey}`);
125
+ throw new Error(`provider did not return UploadId for ${input.objectKey}`);
122
126
  }
123
127
  return response.UploadId;
124
128
  }
125
- throw new Error(`multipart upload is not supported for ${destination.provider}`);
129
+ throw new Error(`multipart upload is not supported for ${input.destination.provider}`);
130
+ }
131
+ export async function signFinalObjectHead(destination, objectKey, expiresIn) {
132
+ if (isS3CompatibleProvider(destination)) {
133
+ const client = createS3CompatibleClient(destination);
134
+ return getSignedUrl(client, new HeadObjectCommand({ Bucket: destination.bucket, Key: objectKey }), { expiresIn });
135
+ }
136
+ throw new Error(`final object HEAD signing is not supported for ${destination.provider}`);
126
137
  }
127
138
  export async function signCompleteMultipartUpload(destination, objectKey, uploadId, expiresIn) {
128
139
  if (isS3CompatibleProvider(destination)) {
@@ -138,10 +149,15 @@ export async function signAbortMultipartUpload(destination, objectKey, uploadId,
138
149
  }
139
150
  throw new Error(`multipart abort is not supported for ${destination.provider}`);
140
151
  }
141
- export async function signListObjects(destination, prefix, expiresIn) {
152
+ export async function signListObjects(destination, prefix, expiresIn, options = {}) {
142
153
  if (isS3CompatibleProvider(destination)) {
143
154
  const client = createS3CompatibleClient(destination);
144
- return getSignedUrl(client, new ListObjectsV2Command({ Bucket: destination.bucket, Prefix: prefix }), { expiresIn });
155
+ return getSignedUrl(client, new ListObjectsV2Command({
156
+ Bucket: destination.bucket,
157
+ Prefix: prefix,
158
+ MaxKeys: 1_000,
159
+ StartAfter: options.startAfter
160
+ }), { expiresIn });
145
161
  }
146
162
  throw new Error(`multipart staging list is not supported for ${destination.provider}`);
147
163
  }
@@ -158,13 +174,6 @@ export async function signListMultipartUpload(destination, objectKey, uploadId,
158
174
  }
159
175
  throw new Error(`multipart list-parts is not supported for ${destination.provider}`);
160
176
  }
161
- export function listPartsPageMarker(partNumber, pageSize = 1000) {
162
- const marker = Math.floor((Math.max(1, partNumber) - 1) / pageSize) * pageSize;
163
- return marker > 0 ? marker : undefined;
164
- }
165
- export function listPartsVerifyMarker(partNumber) {
166
- return partNumber > 1 ? partNumber - 1 : undefined;
167
- }
168
177
  export async function signUploadPartCopy(destination, finalObjectKey, stagingObjectKey, uploadId, partNumber, expiresIn, copySourceRange) {
169
178
  if (isS3CompatibleProvider(destination)) {
170
179
  const client = createS3CompatibleClient(destination);
@@ -209,31 +218,29 @@ export async function abortMultipartUpload(destination, objectKey, uploadId) {
209
218
  throw new Error(`multipart abort is not supported for ${destination.provider}`);
210
219
  }
211
220
  export async function signDestinationRoute(input) {
221
+ if (input.commitMethod !== undefined && input.commitMethod !== "upload_part_copy") {
222
+ throw new Error(`unsupported signed_url_v2 commit method: ${String(input.commitMethod)}`);
223
+ }
212
224
  const targetObjectKey = input.target.object_key;
213
225
  if (!targetObjectKey) {
214
226
  throw new Error("destination signing target is missing object_key");
215
227
  }
216
- const objectKey = input.commitMethod === "upload_part_copy" && input.stagingObjectKey
217
- ? input.stagingObjectKey
218
- : targetObjectKey;
219
- const uploadPartObjectKey = input.multipartObjectKey ?? targetObjectKey;
220
- const destUrl = await signDestinationUrl({
221
- destination: input.destination,
222
- objectKey,
223
- uploadPartObjectKey,
224
- expiresIn: input.expiresIn,
225
- uploadId: input.uploadId,
226
- partNumber: input.partNumber,
227
- useStagingPut: input.commitMethod === "upload_part_copy",
228
- fetchImpl: input.fetchImpl,
229
- });
230
- const sourceRoute = await signSourceRoute({
231
- source: input.source,
232
- fallbackUrl: input.chunk.source_url,
233
- chunk: input.chunk,
234
- expiresIn: input.expiresIn,
235
- fetchImpl: input.fetchImpl
236
- });
228
+ const objectKey = input.stagingObjectKey ?? targetObjectKey;
229
+ const [destUrl, sourceRoute] = await Promise.all([
230
+ signDestinationUrl({
231
+ destination: input.destination,
232
+ objectKey,
233
+ expiresIn: input.expiresIn,
234
+ fetchImpl: input.fetchImpl,
235
+ }),
236
+ signSourceRoute({
237
+ source: input.source,
238
+ fallbackUrl: input.chunk.source_url,
239
+ chunk: input.chunk,
240
+ expiresIn: input.expiresIn,
241
+ fetchImpl: input.fetchImpl
242
+ })
243
+ ]);
237
244
  return {
238
245
  source_id: input.chunk.source_id,
239
246
  destination_id: input.target.destination_id,
@@ -246,23 +253,14 @@ export async function signDestinationRoute(input) {
246
253
  headers: sourceRoute.headers,
247
254
  metadata: {
248
255
  ...(input.target.metadata ?? {}),
249
- ...(input.transferId ? { transfer_id: input.transferId } : {}),
250
256
  ...(input.multipartGroupId ? { multipart_group_id: input.multipartGroupId } : {}),
251
- ...(input.multipartCreatedAt ? { multipart_created_at: input.multipartCreatedAt } : {}),
252
257
  ...(input.commitMethod ? { commit_method: input.commitMethod } : {}),
253
258
  ...(input.stagingObjectKey ? { staging_object_key: input.stagingObjectKey } : {}),
254
- ...(input.stagingListUrl ? { staging_list_url: input.stagingListUrl } : {}),
255
259
  ...(input.copyUrl ? { copy_url: input.copyUrl } : {}),
256
260
  ...(input.copySource ? { copy_source: input.copySource } : {}),
257
261
  ...(input.copySourceRange ? { copy_source_range: input.copySourceRange } : {}),
258
262
  ...(input.deleteUrl ? { delete_url: input.deleteUrl } : {}),
259
- ...(input.uploadId ? { upload_id: input.uploadId } : {}),
260
- ...(input.partNumber ? { part_number: input.partNumber } : {}),
261
- ...(input.partVerifyUrl ? { part_verify_url: input.partVerifyUrl } : {}),
262
- ...(input.listPageUrl ? { list_page_url: input.listPageUrl } : {}),
263
- ...(input.completeUrl ? { complete_url: input.completeUrl } : {}),
264
- ...(input.abortUrl ? { abort_url: input.abortUrl } : {}),
265
- ...(input.listUrl ? { list_url: input.listUrl } : {})
263
+ ...(input.partNumber ? { part_number: input.partNumber } : {})
266
264
  }
267
265
  };
268
266
  }
@@ -301,14 +299,6 @@ async function signSourceRoute(input) {
301
299
  async function signDestinationUrl(input) {
302
300
  if (isS3CompatibleProvider(input.destination)) {
303
301
  const client = createS3CompatibleClient(input.destination);
304
- if (input.uploadId && input.partNumber && !input.useStagingPut) {
305
- return getSignedUrl(client, new UploadPartCommand({
306
- Bucket: input.destination.bucket,
307
- Key: input.uploadPartObjectKey,
308
- UploadId: input.uploadId,
309
- PartNumber: input.partNumber,
310
- }), { expiresIn: input.expiresIn });
311
- }
312
302
  return getSignedUrl(client, new PutObjectCommand({ Bucket: input.destination.bucket, Key: input.objectKey }), { expiresIn: input.expiresIn });
313
303
  }
314
304
  if (isHippiusProvider(input.destination)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beam-network/sdk",
3
- "version": "0.2.22",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript SDK for BEAM transfer creation and management.",
5
5
  "type": "module",
6
6
  "license": "MIT",