@directus/storage-driver-s3 9.22.0 → 9.22.3
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/index.js +14 -5
- package/dist/index.test.js +56 -3
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -10,12 +10,16 @@ export class DriverS3 {
|
|
|
10
10
|
acl;
|
|
11
11
|
serverSideEncryption;
|
|
12
12
|
constructor(config) {
|
|
13
|
-
const s3ClientConfig = {
|
|
14
|
-
|
|
13
|
+
const s3ClientConfig = {};
|
|
14
|
+
if ((config.key && !config.secret) || (config.secret && !config.key)) {
|
|
15
|
+
throw new Error('Both `key` and `secret` are required when defined');
|
|
16
|
+
}
|
|
17
|
+
if (config.key && config.secret) {
|
|
18
|
+
s3ClientConfig.credentials = {
|
|
15
19
|
accessKeyId: config.key,
|
|
16
20
|
secretAccessKey: config.secret,
|
|
17
|
-
}
|
|
18
|
-
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
19
23
|
if (config.endpoint) {
|
|
20
24
|
const protocol = config.endpoint.startsWith('https://') ? 'https:' : 'http:';
|
|
21
25
|
const hostname = config.endpoint.replace('https://', '').replace('http://', '');
|
|
@@ -24,7 +28,12 @@ export class DriverS3 {
|
|
|
24
28
|
protocol,
|
|
25
29
|
path: '/',
|
|
26
30
|
};
|
|
27
|
-
|
|
31
|
+
}
|
|
32
|
+
if (config.region) {
|
|
33
|
+
s3ClientConfig.region = config.region;
|
|
34
|
+
}
|
|
35
|
+
if (config.forcePathStyle !== undefined) {
|
|
36
|
+
s3ClientConfig.forcePathStyle = config.forcePathStyle;
|
|
28
37
|
}
|
|
29
38
|
this.client = new S3Client(s3ClientConfig);
|
|
30
39
|
this.bucket = config.bucket;
|
package/dist/index.test.js
CHANGED
|
@@ -2,7 +2,7 @@ import { CopyObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCom
|
|
|
2
2
|
import { Upload } from '@aws-sdk/lib-storage';
|
|
3
3
|
import { normalizePath } from '@directus/utils';
|
|
4
4
|
import { isReadableStream } from '@directus/utils/node';
|
|
5
|
-
import { randAlphaNumeric, randDirectoryPath, randDomainName, randFilePath, randFileType, randGitBranch as randBucket, randGitShortSha as randUnique, randNumber, randPastDate, randText, randWord, } from '@ngneat/falso';
|
|
5
|
+
import { randAlphaNumeric, randBoolean, randDirectoryPath, randDomainName, randFilePath, randFileType, randGitBranch as randBucket, randGitShortSha as randUnique, randNumber, randPastDate, randText, randWord, } from '@ngneat/falso';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { PassThrough, Readable } from 'node:stream';
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
@@ -24,6 +24,8 @@ beforeEach(() => {
|
|
|
24
24
|
serverSideEncryption: randWord(),
|
|
25
25
|
root: randDirectoryPath(),
|
|
26
26
|
endpoint: randDomainName(),
|
|
27
|
+
region: randWord(),
|
|
28
|
+
forcePathStyle: randBoolean(),
|
|
27
29
|
},
|
|
28
30
|
path: {
|
|
29
31
|
input: randUnique() + randFilePath(),
|
|
@@ -64,6 +66,29 @@ afterEach(() => {
|
|
|
64
66
|
vi.resetAllMocks();
|
|
65
67
|
});
|
|
66
68
|
describe('#constructor', () => {
|
|
69
|
+
test('Throws error if key defined but secret missing', () => {
|
|
70
|
+
try {
|
|
71
|
+
new DriverS3({ key: 'key', bucket: 'bucket' });
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
expect(err).toBeInstanceOf(Error);
|
|
75
|
+
expect(err.message).toBe('Both `key` and `secret` are required when defined');
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
test('Throws error if secret defined but key missing', () => {
|
|
79
|
+
try {
|
|
80
|
+
new DriverS3({ secret: 'secret', bucket: 'bucket' });
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
expect(err).toBeInstanceOf(Error);
|
|
84
|
+
expect(err.message).toBe('Both `key` and `secret` are required when defined');
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
test('Creates S3Client without key / secret (based on machine config)', () => {
|
|
88
|
+
const driver = new DriverS3({ bucket: 'bucket' });
|
|
89
|
+
expect(S3Client).toHaveBeenCalledWith({});
|
|
90
|
+
expect(driver['client']).toBeInstanceOf(S3Client);
|
|
91
|
+
});
|
|
67
92
|
test('Creates S3Client with key / secret configuration', () => {
|
|
68
93
|
expect(S3Client).toHaveBeenCalledWith({
|
|
69
94
|
credentials: {
|
|
@@ -107,7 +132,6 @@ describe('#constructor', () => {
|
|
|
107
132
|
endpoint: sampleHttpEndpoint,
|
|
108
133
|
});
|
|
109
134
|
expect(S3Client).toHaveBeenCalledWith({
|
|
110
|
-
forcePathStyle: true,
|
|
111
135
|
endpoint: {
|
|
112
136
|
hostname: sampleDomain,
|
|
113
137
|
protocol: 'http:',
|
|
@@ -129,7 +153,6 @@ describe('#constructor', () => {
|
|
|
129
153
|
endpoint: sampleHttpEndpoint,
|
|
130
154
|
});
|
|
131
155
|
expect(S3Client).toHaveBeenCalledWith({
|
|
132
|
-
forcePathStyle: true,
|
|
133
156
|
endpoint: {
|
|
134
157
|
hostname: sampleDomain,
|
|
135
158
|
protocol: 'https:',
|
|
@@ -141,6 +164,36 @@ describe('#constructor', () => {
|
|
|
141
164
|
},
|
|
142
165
|
});
|
|
143
166
|
});
|
|
167
|
+
test('Sets region', () => {
|
|
168
|
+
new DriverS3({
|
|
169
|
+
key: sample.config.key,
|
|
170
|
+
secret: sample.config.secret,
|
|
171
|
+
bucket: sample.config.bucket,
|
|
172
|
+
region: sample.config.region,
|
|
173
|
+
});
|
|
174
|
+
expect(S3Client).toHaveBeenCalledWith({
|
|
175
|
+
region: sample.config.region,
|
|
176
|
+
credentials: {
|
|
177
|
+
accessKeyId: sample.config.key,
|
|
178
|
+
secretAccessKey: sample.config.secret,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
test('Sets force path style', () => {
|
|
183
|
+
new DriverS3({
|
|
184
|
+
key: sample.config.key,
|
|
185
|
+
secret: sample.config.secret,
|
|
186
|
+
bucket: sample.config.bucket,
|
|
187
|
+
forcePathStyle: sample.config.forcePathStyle,
|
|
188
|
+
});
|
|
189
|
+
expect(S3Client).toHaveBeenCalledWith({
|
|
190
|
+
forcePathStyle: sample.config.forcePathStyle,
|
|
191
|
+
credentials: {
|
|
192
|
+
accessKeyId: sample.config.key,
|
|
193
|
+
secretAccessKey: sample.config.secret,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
});
|
|
144
197
|
test('Normalizes config path when root is given', () => {
|
|
145
198
|
const mockRoot = randDirectoryPath();
|
|
146
199
|
vi.mocked(normalizePath).mockReturnValue(mockRoot);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/storage-driver-s3",
|
|
3
|
-
"version": "9.22.
|
|
3
|
+
"version": "9.22.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "S3 file storage abstraction for `@directus/storage`",
|
|
6
6
|
"repository": {
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@aws-sdk/abort-controller": "3.226.0",
|
|
28
|
-
"@aws-sdk/client-s3": "3.
|
|
29
|
-
"@aws-sdk/lib-storage": "3.
|
|
30
|
-
"@directus/storage": "9.22.
|
|
31
|
-
"@directus/utils": "9.22.
|
|
28
|
+
"@aws-sdk/client-s3": "3.236.0",
|
|
29
|
+
"@aws-sdk/lib-storage": "3.236.0",
|
|
30
|
+
"@directus/storage": "9.22.3",
|
|
31
|
+
"@directus/utils": "9.22.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@directus/tsconfig": "0.0.6",
|
|
35
|
-
"@ngneat/falso": "6.3.
|
|
36
|
-
"@vitest/coverage-c8": "0.
|
|
37
|
-
"typescript": "4.9.
|
|
38
|
-
"vitest": "0.
|
|
35
|
+
"@ngneat/falso": "6.3.2",
|
|
36
|
+
"@vitest/coverage-c8": "0.26.2",
|
|
37
|
+
"typescript": "4.9.4",
|
|
38
|
+
"vitest": "0.26.2"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc --build",
|