@forge/bridge 5.6.1-next.6 → 5.7.0-next.8
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/CHANGELOG.md +12 -0
- package/out/object-store/download.d.ts +6 -0
- package/out/object-store/download.d.ts.map +1 -0
- package/out/object-store/download.js +52 -0
- package/out/object-store/types.d.ts +33 -0
- package/out/object-store/types.d.ts.map +1 -0
- package/out/object-store/types.js +2 -0
- package/out/object-store/upload.d.ts +6 -0
- package/out/object-store/upload.d.ts.map +1 -0
- package/out/object-store/upload.js +76 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DownloadResult, FilterAndGenerateUrls } from './types';
|
|
2
|
+
export declare const download: ({ filterAndGenerateDownloadUrls, objectKeys }: {
|
|
3
|
+
filterAndGenerateDownloadUrls: FilterAndGenerateUrls;
|
|
4
|
+
objectKeys: string[];
|
|
5
|
+
}) => Promise<DownloadResult[]>;
|
|
6
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/object-store/download.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAsB,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAUzF,eAAO,MAAM,QAAQ;mCAIY,qBAAqB;gBACxC,MAAM,EAAE;MAClB,QAAQ,cAAc,EAAE,CAqD3B,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.download = void 0;
|
|
4
|
+
const invoke_1 = require("../invoke");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const download = async ({ filterAndGenerateDownloadUrls, objectKeys }) => {
|
|
7
|
+
if (!(filterAndGenerateDownloadUrls === null || filterAndGenerateDownloadUrls === void 0 ? void 0 : filterAndGenerateDownloadUrls.function)) {
|
|
8
|
+
throw new errors_1.BridgeAPIError('filterAndGenerateDownloadUrls.function is required');
|
|
9
|
+
}
|
|
10
|
+
if (!Array.isArray(objectKeys) || objectKeys.length === 0) {
|
|
11
|
+
throw new errors_1.BridgeAPIError('objectKeys array is required and must not be empty');
|
|
12
|
+
}
|
|
13
|
+
const downloadUrlsToObjectKeys = (await (0, invoke_1.invoke)(filterAndGenerateDownloadUrls.function, {
|
|
14
|
+
objectKeys
|
|
15
|
+
}));
|
|
16
|
+
if (!downloadUrlsToObjectKeys || typeof downloadUrlsToObjectKeys !== 'object') {
|
|
17
|
+
throw new errors_1.BridgeAPIError('Invalid response from filterAndGenerateDownloadUrls function');
|
|
18
|
+
}
|
|
19
|
+
const downloadPromises = Object.entries(downloadUrlsToObjectKeys).map(async ([downloadUrl, key]) => {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(downloadUrl, {
|
|
22
|
+
method: 'GET'
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
objectKey: key,
|
|
28
|
+
status: response.status,
|
|
29
|
+
error: `Download failed with status ${response.status}`
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const blob = await response.blob();
|
|
33
|
+
return {
|
|
34
|
+
success: true,
|
|
35
|
+
objectKey: key,
|
|
36
|
+
blob,
|
|
37
|
+
status: response.status
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
objectKey: key,
|
|
44
|
+
status: 503,
|
|
45
|
+
error: error instanceof Error ? error.message : 'Download failed'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const results = await Promise.all(downloadPromises);
|
|
50
|
+
return results;
|
|
51
|
+
};
|
|
52
|
+
exports.download = download;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare type ObjectMetadata = {
|
|
2
|
+
length: number;
|
|
3
|
+
checksum: string;
|
|
4
|
+
checksumType: string;
|
|
5
|
+
};
|
|
6
|
+
export declare type FilterAndGenerateUrls = {
|
|
7
|
+
function: string;
|
|
8
|
+
};
|
|
9
|
+
export declare type FileMetadata = ObjectMetadata & {
|
|
10
|
+
key: string;
|
|
11
|
+
ttlSeconds?: number;
|
|
12
|
+
overwrite?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare type UploadResult = {
|
|
15
|
+
success: boolean;
|
|
16
|
+
objectKey: string;
|
|
17
|
+
status?: number;
|
|
18
|
+
error?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare type DownloadResult = {
|
|
21
|
+
success: boolean;
|
|
22
|
+
objectKey: string;
|
|
23
|
+
blob?: Blob;
|
|
24
|
+
status?: number;
|
|
25
|
+
error?: string;
|
|
26
|
+
};
|
|
27
|
+
export declare type PresignedURLMapping = {
|
|
28
|
+
[url: string]: FileMetadata;
|
|
29
|
+
};
|
|
30
|
+
export declare type DownloadURLMapping = {
|
|
31
|
+
[url: string]: string;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/object-store/types.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,oBAAY,YAAY,GAAG,cAAc,GAAG;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,cAAc,GAAG;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,mBAAmB,GAAG;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC;CAC7B,CAAC;AAEF,oBAAY,kBAAkB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FilterAndGenerateUrls, UploadResult } from './types';
|
|
2
|
+
export declare const upload: ({ filterAndGenerateUrls, objects }: {
|
|
3
|
+
filterAndGenerateUrls: FilterAndGenerateUrls;
|
|
4
|
+
objects: Blob[];
|
|
5
|
+
}) => Promise<UploadResult[]>;
|
|
6
|
+
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/object-store/upload.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuC,qBAAqB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA8BxG,eAAO,MAAM,MAAM;2BAIM,qBAAqB;aACnC,IAAI,EAAE;MACb,QAAQ,YAAY,EAAE,CAkEzB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.upload = void 0;
|
|
4
|
+
const invoke_1 = require("../invoke");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const getObjectMetadata = async (blob) => {
|
|
7
|
+
const length = blob.size;
|
|
8
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
9
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
|
|
10
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
11
|
+
const checksum = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
12
|
+
const checksumType = 'SHA-256';
|
|
13
|
+
return {
|
|
14
|
+
length,
|
|
15
|
+
checksum,
|
|
16
|
+
checksumType
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const upload = async ({ filterAndGenerateUrls, objects }) => {
|
|
20
|
+
if (!(filterAndGenerateUrls === null || filterAndGenerateUrls === void 0 ? void 0 : filterAndGenerateUrls.function)) {
|
|
21
|
+
throw new errors_1.BridgeAPIError('filterAndGenerateUrls.function is required');
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(objects) || objects.length === 0) {
|
|
24
|
+
throw new errors_1.BridgeAPIError('objects array is required and must not be empty');
|
|
25
|
+
}
|
|
26
|
+
const allObjectMetadata = await Promise.all(objects.map((obj) => getObjectMetadata(obj)));
|
|
27
|
+
const presignedURLsToObjectMetadata = (await (0, invoke_1.invoke)(filterAndGenerateUrls.function, {
|
|
28
|
+
allObjectMetadata
|
|
29
|
+
}));
|
|
30
|
+
if (!presignedURLsToObjectMetadata || typeof presignedURLsToObjectMetadata !== 'object') {
|
|
31
|
+
throw new errors_1.BridgeAPIError('Invalid response from filterAndGenerateUrls function');
|
|
32
|
+
}
|
|
33
|
+
const checksumToBlobMap = new Map();
|
|
34
|
+
objects.forEach((blob, index) => {
|
|
35
|
+
const metadata = allObjectMetadata[index];
|
|
36
|
+
checksumToBlobMap.set(metadata.checksum, blob);
|
|
37
|
+
});
|
|
38
|
+
const uploadPromises = Object.entries(presignedURLsToObjectMetadata).map(async ([presignedUrl, metadata]) => {
|
|
39
|
+
const { key, length, checksum } = metadata;
|
|
40
|
+
const object = checksumToBlobMap.get(checksum);
|
|
41
|
+
if (!object) {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
objectKey: key,
|
|
45
|
+
error: `Blob not found for checksum ${checksum}`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch(presignedUrl, {
|
|
50
|
+
method: 'PUT',
|
|
51
|
+
body: object,
|
|
52
|
+
headers: {
|
|
53
|
+
'Content-Type': object.type || 'application/octet-stream',
|
|
54
|
+
'Content-Length': length.toString()
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
success: response.ok,
|
|
59
|
+
objectKey: key,
|
|
60
|
+
status: response.status,
|
|
61
|
+
error: response.ok ? undefined : `Upload failed with status ${response.status}`
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
objectKey: key,
|
|
68
|
+
status: 503,
|
|
69
|
+
error: error instanceof Error ? error.message : 'Upload failed'
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
const results = await Promise.all(uploadPromises);
|
|
74
|
+
return results;
|
|
75
|
+
};
|
|
76
|
+
exports.upload = upload;
|