@beam-network/sdk 0.2.0 → 0.2.2
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.d.ts +1 -0
- package/dist/client.js +48 -11
- package/dist/provider-signing.d.ts +12 -0
- package/dist/provider-signing.js +52 -5
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare class BeamClient {
|
|
|
28
28
|
urlsExpiresAt?: string;
|
|
29
29
|
}): Promise<AttachSignedUrlsResponse>;
|
|
30
30
|
prepareProviderTransfer(input: ProviderTransferCreateInput): Promise<TransferPrepareResponse>;
|
|
31
|
+
private signProviderRoute;
|
|
31
32
|
createAndDistribute(input: RawTransferCreateInput): Promise<TransferCreateResponse>;
|
|
32
33
|
waitForTransfer(transferId: string, options?: {
|
|
33
34
|
timeoutMs?: number;
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { abortMultipartUpload, createMultipartUpload, nowIso, prepareProviderDestination, prepareProviderSource, signAbortMultipartUpload, signCompleteMultipartUpload, signDestinationRoute } from "./provider-signing.js";
|
|
1
|
+
import { abortMultipartUpload, createMultipartUpload, nowIso, prepareProviderDestination, prepareProviderSource, signAbortMultipartUpload, signCompleteMultipartUpload, signDeleteObject, signDestinationRoute, signListMultipartUpload, signUploadPartCopy } from "./provider-signing.js";
|
|
2
2
|
export const BEAM_DEFAULT_URL = "https://beamcore.b1m.ai";
|
|
3
3
|
export class BeamApiError extends Error {
|
|
4
4
|
status;
|
|
@@ -119,6 +119,7 @@ export class BeamClient {
|
|
|
119
119
|
uploadId: "",
|
|
120
120
|
completeUrl: "",
|
|
121
121
|
abortUrl: "",
|
|
122
|
+
listUrl: "",
|
|
122
123
|
multipartGroupId: multipartKey,
|
|
123
124
|
multipartCreatedAt
|
|
124
125
|
};
|
|
@@ -131,28 +132,24 @@ export class BeamClient {
|
|
|
131
132
|
uploadId,
|
|
132
133
|
completeUrl: await signCompleteMultipartUpload(destination, finalObjectKey, uploadId, expiresIn),
|
|
133
134
|
abortUrl: await signAbortMultipartUpload(destination, finalObjectKey, uploadId, expiresIn),
|
|
135
|
+
listUrl: await signListMultipartUpload(destination, finalObjectKey, uploadId, expiresIn),
|
|
134
136
|
multipartGroupId: multipartKey,
|
|
135
137
|
multipartCreatedAt
|
|
136
138
|
};
|
|
137
139
|
}
|
|
138
140
|
multipartUploads.set(multipartKey, upload);
|
|
139
141
|
}
|
|
140
|
-
routes.push(await
|
|
142
|
+
routes.push(await this.signProviderRoute({
|
|
141
143
|
chunk,
|
|
142
144
|
target,
|
|
143
145
|
destination,
|
|
144
146
|
expiresIn,
|
|
145
|
-
|
|
147
|
+
upload,
|
|
148
|
+
transferId: prepared.transfer_id,
|
|
149
|
+
finalObjectKey,
|
|
146
150
|
partNumber: typeof metadata.part_number === "number"
|
|
147
151
|
? metadata.part_number
|
|
148
|
-
: chunk.source_chunk_index + 1
|
|
149
|
-
multipartObjectKey: finalObjectKey,
|
|
150
|
-
completeUrl: upload.completeUrl,
|
|
151
|
-
abortUrl: upload.abortUrl,
|
|
152
|
-
transferId: prepared.transfer_id,
|
|
153
|
-
multipartGroupId: upload.multipartGroupId,
|
|
154
|
-
multipartCreatedAt: upload.multipartCreatedAt,
|
|
155
|
-
fetchImpl: this.fetchImpl
|
|
152
|
+
: chunk.source_chunk_index + 1
|
|
156
153
|
}));
|
|
157
154
|
}
|
|
158
155
|
}
|
|
@@ -179,6 +176,46 @@ export class BeamClient {
|
|
|
179
176
|
}
|
|
180
177
|
return prepared;
|
|
181
178
|
}
|
|
179
|
+
async signProviderRoute(input) {
|
|
180
|
+
if (isHippiusDestination(input.destination)) {
|
|
181
|
+
return signDestinationRoute({
|
|
182
|
+
chunk: input.chunk,
|
|
183
|
+
target: input.target,
|
|
184
|
+
destination: input.destination,
|
|
185
|
+
expiresIn: input.expiresIn,
|
|
186
|
+
transferId: input.transferId,
|
|
187
|
+
multipartGroupId: input.upload.multipartGroupId,
|
|
188
|
+
multipartCreatedAt: input.upload.multipartCreatedAt,
|
|
189
|
+
fetchImpl: this.fetchImpl
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (!input.target.object_key) {
|
|
193
|
+
throw new Error("destination signing target is missing object_key");
|
|
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);
|
|
197
|
+
return signDestinationRoute({
|
|
198
|
+
chunk: input.chunk,
|
|
199
|
+
target: input.target,
|
|
200
|
+
destination: input.destination,
|
|
201
|
+
expiresIn: input.expiresIn,
|
|
202
|
+
uploadId: input.upload.uploadId,
|
|
203
|
+
partNumber: input.partNumber,
|
|
204
|
+
multipartObjectKey: input.finalObjectKey,
|
|
205
|
+
completeUrl: input.upload.completeUrl,
|
|
206
|
+
abortUrl: input.upload.abortUrl,
|
|
207
|
+
listUrl: input.upload.listUrl,
|
|
208
|
+
transferId: input.transferId,
|
|
209
|
+
multipartGroupId: input.upload.multipartGroupId,
|
|
210
|
+
multipartCreatedAt: input.upload.multipartCreatedAt,
|
|
211
|
+
commitMethod: "upload_part_copy",
|
|
212
|
+
stagingObjectKey: input.target.object_key,
|
|
213
|
+
copyUrl,
|
|
214
|
+
copySource,
|
|
215
|
+
deleteUrl,
|
|
216
|
+
fetchImpl: this.fetchImpl
|
|
217
|
+
});
|
|
218
|
+
}
|
|
182
219
|
async createAndDistribute(input) {
|
|
183
220
|
const transfer = await this.createRawTransfer(input);
|
|
184
221
|
if (transfer.success) {
|
|
@@ -13,6 +13,12 @@ export declare function prepareProviderDestination(destination: ProviderDestinat
|
|
|
13
13
|
export declare function createMultipartUpload(destination: ProviderDestinationConfig, objectKey: string): Promise<string>;
|
|
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
|
+
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<{
|
|
18
|
+
copyUrl: string;
|
|
19
|
+
copySource: string;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function signDeleteObject(destination: ProviderDestinationConfig, objectKey: string, expiresIn: number): Promise<string>;
|
|
16
22
|
export declare function abortMultipartUpload(destination: ProviderDestinationConfig, objectKey: string, uploadId: string): Promise<void>;
|
|
17
23
|
export declare function signDestinationRoute(input: {
|
|
18
24
|
chunk: ChunkSigningPlanItem;
|
|
@@ -24,9 +30,15 @@ export declare function signDestinationRoute(input: {
|
|
|
24
30
|
multipartObjectKey?: string;
|
|
25
31
|
completeUrl?: string;
|
|
26
32
|
abortUrl?: string;
|
|
33
|
+
listUrl?: string;
|
|
27
34
|
transferId?: string;
|
|
28
35
|
multipartGroupId?: string;
|
|
29
36
|
multipartCreatedAt?: string;
|
|
37
|
+
commitMethod?: "upload_part_copy";
|
|
38
|
+
stagingObjectKey?: string;
|
|
39
|
+
copyUrl?: string;
|
|
40
|
+
copySource?: string;
|
|
41
|
+
deleteUrl?: string;
|
|
30
42
|
fetchImpl?: typeof fetch;
|
|
31
43
|
}): Promise<SignedChunkRoute>;
|
|
32
44
|
export declare function isS3CompatibleProvider(config: ProviderSourceConfig | ProviderDestinationConfig): config is AnyS3CompatibleProviderConfig;
|
package/dist/provider-signing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbortMultipartUploadCommand, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client, UploadPartCommand } from "@aws-sdk/client-s3";
|
|
1
|
+
import { AbortMultipartUploadCommand, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListPartsCommand, PutObjectCommand, S3Client, UploadPartCopyCommand, UploadPartCommand } 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();
|
|
@@ -52,7 +52,9 @@ export function prepareProviderDestination(destination, options = {}) {
|
|
|
52
52
|
destination_id: destinationId,
|
|
53
53
|
provider: destination.provider,
|
|
54
54
|
logical_prefix: destination.key,
|
|
55
|
-
metadata:
|
|
55
|
+
metadata: {
|
|
56
|
+
...s3CompatibleMetadata(destination, endpoint)
|
|
57
|
+
}
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
if (isHippiusProvider(destination)) {
|
|
@@ -60,7 +62,11 @@ export function prepareProviderDestination(destination, options = {}) {
|
|
|
60
62
|
destination_id: destinationId,
|
|
61
63
|
provider: "hippius",
|
|
62
64
|
logical_prefix: destination.key.replace(/\/+$/, ""),
|
|
63
|
-
metadata: {
|
|
65
|
+
metadata: {
|
|
66
|
+
bucket: destination.bucket,
|
|
67
|
+
key: destination.key,
|
|
68
|
+
base_url: destination.base_url ?? "https://api.hippius.com"
|
|
69
|
+
}
|
|
64
70
|
};
|
|
65
71
|
}
|
|
66
72
|
return unsupportedProviderConfig(destination);
|
|
@@ -90,6 +96,37 @@ export async function signAbortMultipartUpload(destination, objectKey, uploadId,
|
|
|
90
96
|
}
|
|
91
97
|
throw new Error(`multipart abort is not supported for ${destination.provider}`);
|
|
92
98
|
}
|
|
99
|
+
export async function signListMultipartUpload(destination, objectKey, uploadId, expiresIn) {
|
|
100
|
+
if (isS3CompatibleProvider(destination)) {
|
|
101
|
+
const client = createS3CompatibleClient(destination);
|
|
102
|
+
return getSignedUrl(client, new ListPartsCommand({ Bucket: destination.bucket, Key: objectKey, UploadId: uploadId }), { expiresIn });
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`multipart list-parts is not supported for ${destination.provider}`);
|
|
105
|
+
}
|
|
106
|
+
export async function signUploadPartCopy(destination, finalObjectKey, stagingObjectKey, uploadId, partNumber, expiresIn) {
|
|
107
|
+
if (isS3CompatibleProvider(destination)) {
|
|
108
|
+
const client = createS3CompatibleClient(destination);
|
|
109
|
+
const copySource = copySourceHeader(destination, stagingObjectKey);
|
|
110
|
+
return {
|
|
111
|
+
copySource,
|
|
112
|
+
copyUrl: await getSignedUrl(client, new UploadPartCopyCommand({
|
|
113
|
+
Bucket: destination.bucket,
|
|
114
|
+
Key: finalObjectKey,
|
|
115
|
+
UploadId: uploadId,
|
|
116
|
+
PartNumber: partNumber,
|
|
117
|
+
CopySource: copySource
|
|
118
|
+
}), { expiresIn })
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`multipart copy is not supported for ${destination.provider}`);
|
|
122
|
+
}
|
|
123
|
+
export async function signDeleteObject(destination, objectKey, expiresIn) {
|
|
124
|
+
if (isS3CompatibleProvider(destination)) {
|
|
125
|
+
const client = createS3CompatibleClient(destination);
|
|
126
|
+
return getSignedUrl(client, new DeleteObjectCommand({ Bucket: destination.bucket, Key: objectKey }), { expiresIn });
|
|
127
|
+
}
|
|
128
|
+
throw new Error(`object delete signing is not supported for ${destination.provider}`);
|
|
129
|
+
}
|
|
93
130
|
export async function abortMultipartUpload(destination, objectKey, uploadId) {
|
|
94
131
|
if (isS3CompatibleProvider(destination)) {
|
|
95
132
|
await createS3CompatibleClient(destination).send(new AbortMultipartUploadCommand({ Bucket: destination.bucket, Key: objectKey, UploadId: uploadId }));
|
|
@@ -110,6 +147,7 @@ export async function signDestinationRoute(input) {
|
|
|
110
147
|
expiresIn: input.expiresIn,
|
|
111
148
|
uploadId: input.uploadId,
|
|
112
149
|
partNumber: input.partNumber,
|
|
150
|
+
useStagingPut: input.commitMethod === "upload_part_copy",
|
|
113
151
|
fetchImpl: input.fetchImpl
|
|
114
152
|
});
|
|
115
153
|
return {
|
|
@@ -126,17 +164,23 @@ export async function signDestinationRoute(input) {
|
|
|
126
164
|
...(input.transferId ? { transfer_id: input.transferId } : {}),
|
|
127
165
|
...(input.multipartGroupId ? { multipart_group_id: input.multipartGroupId } : {}),
|
|
128
166
|
...(input.multipartCreatedAt ? { multipart_created_at: input.multipartCreatedAt } : {}),
|
|
167
|
+
...(input.commitMethod ? { commit_method: input.commitMethod } : {}),
|
|
168
|
+
...(input.stagingObjectKey ? { staging_object_key: input.stagingObjectKey } : {}),
|
|
169
|
+
...(input.copyUrl ? { copy_url: input.copyUrl } : {}),
|
|
170
|
+
...(input.copySource ? { copy_source: input.copySource } : {}),
|
|
171
|
+
...(input.deleteUrl ? { delete_url: input.deleteUrl } : {}),
|
|
129
172
|
...(input.uploadId ? { upload_id: input.uploadId } : {}),
|
|
130
173
|
...(input.partNumber ? { part_number: input.partNumber } : {}),
|
|
131
174
|
...(input.completeUrl ? { complete_url: input.completeUrl } : {}),
|
|
132
|
-
...(input.abortUrl ? { abort_url: input.abortUrl } : {})
|
|
175
|
+
...(input.abortUrl ? { abort_url: input.abortUrl } : {}),
|
|
176
|
+
...(input.listUrl ? { list_url: input.listUrl } : {})
|
|
133
177
|
}
|
|
134
178
|
};
|
|
135
179
|
}
|
|
136
180
|
async function signDestinationUrl(input) {
|
|
137
181
|
if (isS3CompatibleProvider(input.destination)) {
|
|
138
182
|
const client = createS3CompatibleClient(input.destination);
|
|
139
|
-
if (input.uploadId && input.partNumber) {
|
|
183
|
+
if (input.uploadId && input.partNumber && !input.useStagingPut) {
|
|
140
184
|
return getSignedUrl(client, new UploadPartCommand({
|
|
141
185
|
Bucket: input.destination.bucket,
|
|
142
186
|
Key: input.uploadPartObjectKey,
|
|
@@ -255,3 +299,6 @@ function hasText(value) {
|
|
|
255
299
|
function unsupportedProviderConfig(value) {
|
|
256
300
|
throw new Error(`Unsupported provider config: ${JSON.stringify(value)}`);
|
|
257
301
|
}
|
|
302
|
+
function copySourceHeader(destination, objectKey) {
|
|
303
|
+
return `/${destination.bucket}/${objectKey.split("/").map(encodeURIComponent).join("/")}`;
|
|
304
|
+
}
|