@ido_kawaz/storage-client 1.0.1 → 2.0.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.
- package/README.md +63 -46
- package/dist/__tests__/storageClient.test.d.ts +2 -0
- package/dist/__tests__/storageClient.test.d.ts.map +1 -0
- package/dist/__tests__/storageClient.test.js +163 -0
- package/dist/__tests__/storageClient.test.js.map +1 -0
- package/dist/storageClient.d.ts +1 -0
- package/dist/storageClient.d.ts.map +1 -1
- package/dist/storageClient.js +28 -13
- package/dist/storageClient.js.map +1 -1
- package/dist/types.d.ts +4 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,94 +1,111 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @ido_kawaz/storage-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Storage client library for S3-compatible object storage (AWS S3, MinIO, LocalStack) with multipart upload support.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @
|
|
8
|
+
npm install @ido_kawaz/storage-client
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
### Initialize StorageClient
|
|
11
|
+
## Quick Start
|
|
14
12
|
|
|
15
13
|
```typescript
|
|
16
|
-
import { StorageClient } from '@
|
|
17
|
-
import
|
|
14
|
+
import { StorageClient } from '@ido_kawaz/storage-client';
|
|
15
|
+
import fs from 'node:fs';
|
|
18
16
|
|
|
19
17
|
const client = new StorageClient({
|
|
20
18
|
region: 'us-east-1',
|
|
21
19
|
credentials: {
|
|
22
|
-
accessKeyId:
|
|
23
|
-
secretAccessKey:
|
|
20
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
21
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
24
22
|
},
|
|
25
|
-
partSize: 5 * 1024 * 1024,
|
|
26
|
-
maxConcurrency: 4
|
|
23
|
+
partSize: 5 * 1024 * 1024,
|
|
24
|
+
maxConcurrency: 4
|
|
27
25
|
});
|
|
26
|
+
|
|
27
|
+
await client.uploadObject(
|
|
28
|
+
'my-bucket',
|
|
29
|
+
'files/report.pdf',
|
|
30
|
+
fs.createReadStream('./report.pdf'),
|
|
31
|
+
{ ensureBucket: true }
|
|
32
|
+
);
|
|
28
33
|
```
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
## API
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
### `new StorageClient(config)`
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
await client.ensureBucket('my-bucket');
|
|
36
|
-
```
|
|
39
|
+
Creates a new client.
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
`StorageClientConfig` extends AWS `S3ClientConfig` and includes:
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
- `partSize: number` - multipart upload part size in bytes
|
|
44
|
+
- `maxConcurrency: number` - number of parts uploaded in parallel
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
const fileStream = fs.createReadStream('path/to/file');
|
|
46
|
+
### `ensureBucket(bucketName: string): Promise<void>`
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
ensureBucket: true // Automatically create bucket if it doesn't exist
|
|
47
|
-
});
|
|
48
|
-
```
|
|
48
|
+
Checks whether a bucket exists and creates it when it is missing.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
### `deleteBucket(bucketName: string): Promise<void>`
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Deletes a bucket. If the bucket does not exist, the operation is treated as successful.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
### `uploadObject(bucketName: string, objectKey: string, objectData: Readable, options?: UploadObjectOptions): Promise<void>`
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
await client.deleteBucket('my-bucket');
|
|
58
|
-
```
|
|
56
|
+
Uploads a stream to object storage.
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
- `objectData` must be a Node.js `Readable` stream.
|
|
59
|
+
- By default, uses a regular `PutObject` request.
|
|
60
|
+
- When multipart upload is enabled, upload progress is logged to the console.
|
|
61
|
+
- If `options?.ensureBucket` is `true`, the bucket is created automatically when missing.
|
|
62
|
+
- If `options?.multipartUpload` is `true`, upload is performed using multipart upload.
|
|
61
63
|
|
|
62
|
-
`
|
|
64
|
+
`UploadObjectOptions`:
|
|
63
65
|
|
|
64
|
-
- `
|
|
65
|
-
- `
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
- `ensureBucket: boolean`
|
|
67
|
+
- `multipartUpload: boolean`
|
|
68
|
+
|
|
69
|
+
### `downloadObject(bucketName: string, objectKey: string): Promise<Readable>`
|
|
70
|
+
|
|
71
|
+
Downloads an object and returns its body as a Node.js `Readable` stream.
|
|
72
|
+
|
|
73
|
+
- Throws `StorageError` when the object retrieval fails.
|
|
74
|
+
- Throws `StorageError` when the storage service returns an empty body.
|
|
69
75
|
|
|
70
76
|
## Error Handling
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
Storage operations can throw `StorageError` with operation context in the message.
|
|
73
79
|
|
|
74
80
|
```typescript
|
|
75
|
-
import { StorageError } from '@
|
|
81
|
+
import { StorageError } from '@ido_kawaz/storage-client';
|
|
76
82
|
|
|
77
83
|
try {
|
|
78
|
-
await client.uploadObject('bucket', '
|
|
84
|
+
await client.uploadObject('my-bucket', 'files/a.txt', fs.createReadStream('./a.txt'));
|
|
79
85
|
} catch (error) {
|
|
80
86
|
if (error instanceof StorageError) {
|
|
81
|
-
console.error(
|
|
87
|
+
console.error(error.message);
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
```
|
|
85
91
|
|
|
86
92
|
## Exports
|
|
87
93
|
|
|
88
|
-
- `StorageClient
|
|
89
|
-
- `StorageClientConfig
|
|
90
|
-
- `StorageError
|
|
91
|
-
- `UploadObjectOptions
|
|
94
|
+
- `StorageClient`
|
|
95
|
+
- `StorageClientConfig`
|
|
96
|
+
- `StorageError`
|
|
97
|
+
- `UploadObjectOptions`
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run build
|
|
103
|
+
npm test
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Useful test scripts:
|
|
107
|
+
|
|
108
|
+
- `npm test` - run tests once
|
|
92
109
|
|
|
93
110
|
## License
|
|
94
111
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageClient.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/storageClient.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const lib_storage_1 = require("@aws-sdk/lib-storage");
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
6
|
+
const storageClient_1 = require("../storageClient");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const sendMock = jest.fn();
|
|
9
|
+
jest.mock('@aws-sdk/client-s3', () => {
|
|
10
|
+
class MockHeadBucketCommand {
|
|
11
|
+
constructor(input) {
|
|
12
|
+
this.input = input;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class MockCreateBucketCommand {
|
|
16
|
+
constructor(input) {
|
|
17
|
+
this.input = input;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class MockDeleteBucketCommand {
|
|
21
|
+
constructor(input) {
|
|
22
|
+
this.input = input;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
class MockGetObjectCommand {
|
|
26
|
+
constructor(input) {
|
|
27
|
+
this.input = input;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
class MockPutObjectCommand {
|
|
31
|
+
constructor(input) {
|
|
32
|
+
this.input = input;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
S3Client: jest.fn().mockImplementation(() => ({
|
|
37
|
+
send: sendMock
|
|
38
|
+
})),
|
|
39
|
+
HeadBucketCommand: MockHeadBucketCommand,
|
|
40
|
+
CreateBucketCommand: MockCreateBucketCommand,
|
|
41
|
+
DeleteBucketCommand: MockDeleteBucketCommand,
|
|
42
|
+
GetObjectCommand: MockGetObjectCommand,
|
|
43
|
+
PutObjectCommand: MockPutObjectCommand
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
const uploadOnMock = jest.fn();
|
|
47
|
+
const uploadDoneMock = jest.fn();
|
|
48
|
+
jest.mock('@aws-sdk/lib-storage', () => ({
|
|
49
|
+
Upload: jest.fn().mockImplementation(() => ({
|
|
50
|
+
on: uploadOnMock,
|
|
51
|
+
done: uploadDoneMock
|
|
52
|
+
}))
|
|
53
|
+
}));
|
|
54
|
+
describe('StorageClient', () => {
|
|
55
|
+
const config = {
|
|
56
|
+
region: 'us-east-1',
|
|
57
|
+
partSize: 5 * 1024 * 1024,
|
|
58
|
+
maxConcurrency: 4
|
|
59
|
+
};
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
jest.clearAllMocks();
|
|
62
|
+
sendMock.mockReset();
|
|
63
|
+
uploadDoneMock.mockReset();
|
|
64
|
+
uploadOnMock.mockReset();
|
|
65
|
+
});
|
|
66
|
+
it('ensureBucket does nothing when bucket exists', async () => {
|
|
67
|
+
sendMock.mockResolvedValueOnce({});
|
|
68
|
+
const client = new storageClient_1.StorageClient(config);
|
|
69
|
+
await client.ensureBucket('existing-bucket');
|
|
70
|
+
expect(sendMock).toHaveBeenCalledTimes(1);
|
|
71
|
+
expect(sendMock.mock.calls[0][0]).toBeInstanceOf(client_s3_1.HeadBucketCommand);
|
|
72
|
+
});
|
|
73
|
+
it('ensureBucket creates bucket when missing', async () => {
|
|
74
|
+
sendMock
|
|
75
|
+
.mockRejectedValueOnce({ name: 'NotFound' })
|
|
76
|
+
.mockResolvedValueOnce({});
|
|
77
|
+
const client = new storageClient_1.StorageClient(config);
|
|
78
|
+
await client.ensureBucket('new-bucket');
|
|
79
|
+
expect(sendMock).toHaveBeenCalledTimes(2);
|
|
80
|
+
expect(sendMock.mock.calls[0][0]).toBeInstanceOf(client_s3_1.HeadBucketCommand);
|
|
81
|
+
expect(sendMock.mock.calls[1][0]).toBeInstanceOf(client_s3_1.CreateBucketCommand);
|
|
82
|
+
});
|
|
83
|
+
it('ensureBucket wraps non-NotFound errors', async () => {
|
|
84
|
+
sendMock.mockRejectedValueOnce({ name: 'Forbidden' });
|
|
85
|
+
const client = new storageClient_1.StorageClient(config);
|
|
86
|
+
await expect(client.ensureBucket('private-bucket')).rejects.toBeInstanceOf(types_1.StorageError);
|
|
87
|
+
});
|
|
88
|
+
it('deleteBucket ignores NoSuchBucket errors', async () => {
|
|
89
|
+
sendMock.mockRejectedValueOnce({ name: 'NoSuchBucket' });
|
|
90
|
+
const client = new storageClient_1.StorageClient(config);
|
|
91
|
+
await expect(client.deleteBucket('missing')).resolves.toBeUndefined();
|
|
92
|
+
expect(sendMock.mock.calls[0][0]).toBeInstanceOf(client_s3_1.DeleteBucketCommand);
|
|
93
|
+
});
|
|
94
|
+
it('deleteBucket wraps unexpected errors', async () => {
|
|
95
|
+
sendMock.mockRejectedValueOnce({ name: 'AccessDenied' });
|
|
96
|
+
const client = new storageClient_1.StorageClient(config);
|
|
97
|
+
await expect(client.deleteBucket('restricted')).rejects.toBeInstanceOf(types_1.StorageError);
|
|
98
|
+
});
|
|
99
|
+
it('uploadObject uses PutObject by default', async () => {
|
|
100
|
+
sendMock.mockResolvedValueOnce({});
|
|
101
|
+
const client = new storageClient_1.StorageClient(config);
|
|
102
|
+
const objectData = stream_1.Readable.from(['hello']);
|
|
103
|
+
await client.uploadObject('bucket-a', 'path/file.txt', objectData);
|
|
104
|
+
expect(sendMock).toHaveBeenCalledTimes(1);
|
|
105
|
+
expect(sendMock.mock.calls[0][0]).toBeInstanceOf(client_s3_1.PutObjectCommand);
|
|
106
|
+
expect(lib_storage_1.Upload).not.toHaveBeenCalled();
|
|
107
|
+
});
|
|
108
|
+
it('uploadObject runs Upload with config and object params when multipart enabled', async () => {
|
|
109
|
+
uploadDoneMock.mockResolvedValueOnce();
|
|
110
|
+
const client = new storageClient_1.StorageClient(config);
|
|
111
|
+
const objectData = stream_1.Readable.from(['hello']);
|
|
112
|
+
await client.uploadObject('bucket-a', 'path/file.txt', objectData, { multipartUpload: true });
|
|
113
|
+
expect(lib_storage_1.Upload).toHaveBeenCalledTimes(1);
|
|
114
|
+
expect(lib_storage_1.Upload).toHaveBeenCalledWith(expect.objectContaining({
|
|
115
|
+
params: expect.objectContaining({
|
|
116
|
+
Bucket: 'bucket-a',
|
|
117
|
+
Key: 'path/file.txt',
|
|
118
|
+
Body: objectData
|
|
119
|
+
}),
|
|
120
|
+
queueSize: config.maxConcurrency,
|
|
121
|
+
partSize: config.partSize
|
|
122
|
+
}));
|
|
123
|
+
expect(uploadOnMock).toHaveBeenCalledWith('httpUploadProgress', expect.any(Function));
|
|
124
|
+
});
|
|
125
|
+
it('uploadObject calls ensureBucket when requested', async () => {
|
|
126
|
+
uploadDoneMock.mockResolvedValueOnce();
|
|
127
|
+
const client = new storageClient_1.StorageClient(config);
|
|
128
|
+
const ensureBucketSpy = jest.spyOn(client, 'ensureBucket').mockResolvedValue();
|
|
129
|
+
await client.uploadObject('bucket-b', 'file.txt', stream_1.Readable.from(['x']), { ensureBucket: true });
|
|
130
|
+
expect(ensureBucketSpy).toHaveBeenCalledWith('bucket-b');
|
|
131
|
+
});
|
|
132
|
+
it('uploadObject wraps upload failures in StorageError', async () => {
|
|
133
|
+
uploadDoneMock.mockRejectedValueOnce(new Error('UploadDenied'));
|
|
134
|
+
const client = new storageClient_1.StorageClient(config);
|
|
135
|
+
await expect(client.uploadObject('bucket-c', 'file.txt', stream_1.Readable.from(['x']), { multipartUpload: true })).rejects.toBeInstanceOf(types_1.StorageError);
|
|
136
|
+
});
|
|
137
|
+
it('uploadObject includes operation and context in wrapped error message', async () => {
|
|
138
|
+
const error = new Error('unexpected');
|
|
139
|
+
uploadDoneMock.mockRejectedValueOnce(error);
|
|
140
|
+
const client = new storageClient_1.StorageClient(config);
|
|
141
|
+
await expect(client.uploadObject('bucket-d', 'file.txt', stream_1.Readable.from(['x']), { multipartUpload: true })).rejects.toThrow('Storage error: {"operation":"uploadObject","error":"unexpected","bucketName":"bucket-d","objectKey":"file.txt"}');
|
|
142
|
+
});
|
|
143
|
+
it('downloadObject returns readable stream body', async () => {
|
|
144
|
+
const body = stream_1.Readable.from(['hello']);
|
|
145
|
+
sendMock.mockResolvedValueOnce({ Body: body });
|
|
146
|
+
const client = new storageClient_1.StorageClient(config);
|
|
147
|
+
const result = await client.downloadObject('bucket-e', 'file.txt');
|
|
148
|
+
expect(result).toBe(body);
|
|
149
|
+
expect(sendMock).toHaveBeenCalledTimes(1);
|
|
150
|
+
expect(sendMock.mock.calls[0][0]).toBeInstanceOf(client_s3_1.GetObjectCommand);
|
|
151
|
+
});
|
|
152
|
+
it('downloadObject wraps get-object failures in StorageError', async () => {
|
|
153
|
+
sendMock.mockRejectedValueOnce(new Error('NoSuchKey'));
|
|
154
|
+
const client = new storageClient_1.StorageClient(config);
|
|
155
|
+
await expect(client.downloadObject('bucket-f', 'missing.txt')).rejects.toBeInstanceOf(types_1.StorageError);
|
|
156
|
+
});
|
|
157
|
+
it('downloadObject throws StorageError when body is empty', async () => {
|
|
158
|
+
sendMock.mockResolvedValueOnce({ Body: null });
|
|
159
|
+
const client = new storageClient_1.StorageClient(config);
|
|
160
|
+
await expect(client.downloadObject('bucket-g', 'empty.txt')).rejects.toThrow('Storage error: {"operation":"downloadObject","error":"Received empty body","bucketName":"bucket-g","objectKey":"empty.txt"}');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=storageClient.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storageClient.test.js","sourceRoot":"","sources":["../../src/__tests__/storageClient.test.ts"],"names":[],"mappings":"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"}
|
package/dist/storageClient.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export declare class StorageClient {
|
|
|
7
7
|
ensureBucket: (bucketName: string) => Promise<void>;
|
|
8
8
|
deleteBucket: (bucketName: string) => Promise<void>;
|
|
9
9
|
uploadObject: (bucketName: string, objectKey: string, objectData: Readable, options?: UploadObjectOptions) => Promise<void>;
|
|
10
|
+
downloadObject: (bucketName: string, objectKey: string) => Promise<Readable>;
|
|
10
11
|
}
|
|
11
12
|
//# sourceMappingURL=storageClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageClient.d.ts","sourceRoot":"","sources":["../src/storageClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"storageClient.d.ts","sourceRoot":"","sources":["../src/storageClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAgB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEjF,qBAAa,aAAa;IAEV,OAAO,CAAC,QAAQ,CAAC,MAAM;IADnC,OAAO,CAAC,MAAM,CAAW;gBACI,MAAM,EAAE,mBAAmB;IAGxD,YAAY,GAAU,YAAY,MAAM,mBAQtC;IACF,YAAY,GAAU,YAAY,MAAM,mBAMtC;IAEF,YAAY,GAAU,YAAY,MAAM,EAAE,WAAW,MAAM,EAAE,YAAY,QAAQ,EAAE,UAAU,mBAAmB,mBAsB/G;IAED,cAAc,GAAU,YAAY,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,QAAQ,CAAC,CAUhF;CACJ"}
|
package/dist/storageClient.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.StorageClient = void 0;
|
|
4
4
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
5
5
|
const lib_storage_1 = require("@aws-sdk/lib-storage");
|
|
6
|
+
const ramda_1 = require("ramda");
|
|
6
7
|
const types_1 = require("./types");
|
|
7
8
|
class StorageClient {
|
|
8
9
|
constructor(config) {
|
|
@@ -29,22 +30,36 @@ class StorageClient {
|
|
|
29
30
|
await this.ensureBucket(bucketName);
|
|
30
31
|
}
|
|
31
32
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
if (options?.multipartUpload) {
|
|
34
|
+
const upload = new lib_storage_1.Upload({
|
|
35
|
+
client: this.client,
|
|
36
|
+
params: { Bucket: bucketName, Key: objectKey, Body: objectData },
|
|
37
|
+
queueSize: this.config.maxConcurrency,
|
|
38
|
+
partSize: this.config.partSize
|
|
39
|
+
});
|
|
40
|
+
upload.on("httpUploadProgress", (progress) => {
|
|
41
|
+
console.log(`Upload progress for ${objectKey}: ${progress.loaded / progress.total * 100}%`);
|
|
42
|
+
});
|
|
43
|
+
await upload.done();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
await this.client.send(new client_s3_1.PutObjectCommand({ Bucket: bucketName, Key: objectKey, Body: objectData }));
|
|
47
|
+
}
|
|
42
48
|
}
|
|
43
49
|
catch (error) {
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
throw new types_1.StorageError("uploadObject", error, { bucketName, objectKey });
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
this.downloadObject = async (bucketName, objectKey) => {
|
|
54
|
+
try {
|
|
55
|
+
const { Body } = await this.client.send(new client_s3_1.GetObjectCommand({ Bucket: bucketName, Key: objectKey }));
|
|
56
|
+
if ((0, ramda_1.isNil)(Body)) {
|
|
57
|
+
throw new Error("Received empty body");
|
|
46
58
|
}
|
|
47
|
-
|
|
59
|
+
return Body;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
throw new types_1.StorageError("downloadObject", error, { bucketName, objectKey });
|
|
48
63
|
}
|
|
49
64
|
};
|
|
50
65
|
this.client = new client_s3_1.S3Client(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageClient.js","sourceRoot":"","sources":["../src/storageClient.ts"],"names":[],"mappings":";;;AAAA,kDAA+
|
|
1
|
+
{"version":3,"file":"storageClient.js","sourceRoot":"","sources":["../src/storageClient.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { S3ClientConfig
|
|
1
|
+
import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
2
2
|
export interface StorageClientConfig extends S3ClientConfig {
|
|
3
3
|
partSize: number;
|
|
4
4
|
maxConcurrency: number;
|
|
5
5
|
}
|
|
6
6
|
export declare class StorageError extends Error {
|
|
7
|
-
constructor(operation: string, error:
|
|
7
|
+
constructor(operation: string, error: Error, details: {});
|
|
8
8
|
}
|
|
9
9
|
export interface UploadObjectOptions {
|
|
10
|
-
ensureBucket
|
|
10
|
+
ensureBucket?: boolean;
|
|
11
|
+
multipartUpload?: boolean;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACvB,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;CAI3D;AAED,MAAM,WAAW,mBAAmB;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B"}
|
package/dist/types.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.StorageError = void 0;
|
|
4
4
|
class StorageError extends Error {
|
|
5
5
|
constructor(operation, error, details) {
|
|
6
|
-
const message = `Storage error: ${JSON.stringify({ operation, error: error.
|
|
6
|
+
const message = `Storage error: ${JSON.stringify({ operation, error: error.message, ...details })}`;
|
|
7
7
|
super(message);
|
|
8
8
|
}
|
|
9
9
|
}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAa,SAAQ,KAAK;IACnC,YAAY,SAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAa,SAAQ,KAAK;IACnC,YAAY,SAAiB,EAAE,KAAY,EAAE,OAAW;QACpD,MAAM,OAAO,GAAG,kBAAkB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC;QACpG,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;CACJ;AALD,oCAKC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ido_kawaz/storage-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Storage client library for Kawaz Plus services",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"build": "npm run clean && tsc",
|
|
12
12
|
"build:watch": "tsc --watch",
|
|
13
13
|
"build:advanced": "npm run clean:advanced && npm i && tsc",
|
|
14
|
+
"test": "npm run build && jest --runInBand",
|
|
14
15
|
"clean": "rimraf dist",
|
|
15
16
|
"clean:advanced": "rimraf dist node_modules package-lock.json",
|
|
16
17
|
"package": "npm run build:advanced && npm publish --access public"
|
|
@@ -24,11 +25,16 @@
|
|
|
24
25
|
"license": "MIT",
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@aws-sdk/client-s3": "^3.985.0",
|
|
27
|
-
"@aws-sdk/lib-storage": "^3.985.0"
|
|
28
|
+
"@aws-sdk/lib-storage": "^3.985.0",
|
|
29
|
+
"@types/ramda": "^0.31.1",
|
|
30
|
+
"ramda": "^0.32.0"
|
|
28
31
|
},
|
|
29
32
|
"devDependencies": {
|
|
33
|
+
"@types/jest": "^30.0.0",
|
|
30
34
|
"@types/node": "^25.2.3",
|
|
35
|
+
"jest": "^30.1.3",
|
|
31
36
|
"rimraf": "^6.0.0",
|
|
37
|
+
"ts-jest": "^29.4.1",
|
|
32
38
|
"typescript": "^5.9.3"
|
|
33
39
|
}
|
|
34
40
|
}
|