@byline/storage-s3 3.18.0 → 3.20.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/dist/s3-storage-provider.js +44 -1
- package/package.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { Readable } from 'node:stream';
|
|
10
|
-
import { DeleteObjectCommand, S3Client, } from '@aws-sdk/client-s3';
|
|
10
|
+
import { CopyObjectCommand, DeleteObjectCommand, HeadObjectCommand, S3Client, } from '@aws-sdk/client-s3';
|
|
11
11
|
import { Upload } from '@aws-sdk/lib-storage';
|
|
12
12
|
import { v4 as uuidv4 } from 'uuid';
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
@@ -128,6 +128,49 @@ class S3StorageProvider {
|
|
|
128
128
|
Key: storagePath,
|
|
129
129
|
}));
|
|
130
130
|
}
|
|
131
|
+
async move(fromPath, toPath) {
|
|
132
|
+
// S3 has no native rename — copy to the new key, then delete the
|
|
133
|
+
// original. CopyObject throws NoSuchKey when the source is missing,
|
|
134
|
+
// satisfying the interface's "throws if the source does not exist".
|
|
135
|
+
// The default MetadataDirective (COPY) carries the source object's
|
|
136
|
+
// Content-Type, Cache-Control, and user metadata to the new key —
|
|
137
|
+
// exactly what a rename should do. ACLs are not copied by S3, so
|
|
138
|
+
// re-apply the configured canned ACL when one is set.
|
|
139
|
+
// Note: CopySource must be URL-encoded (keys may contain characters
|
|
140
|
+
// that are significant in the `<bucket>/<key>` source string).
|
|
141
|
+
await this.client.send(new CopyObjectCommand({
|
|
142
|
+
Bucket: this.bucket,
|
|
143
|
+
CopySource: encodeURIComponent(`${this.bucket}/${fromPath}`),
|
|
144
|
+
Key: toPath,
|
|
145
|
+
...(this.acl ? { ACL: this.acl } : {}),
|
|
146
|
+
}));
|
|
147
|
+
await this.client.send(new DeleteObjectCommand({
|
|
148
|
+
Bucket: this.bucket,
|
|
149
|
+
Key: fromPath,
|
|
150
|
+
}));
|
|
151
|
+
return {
|
|
152
|
+
storageProvider: this.providerName,
|
|
153
|
+
storagePath: toPath,
|
|
154
|
+
storageUrl: this.getUrl(toPath),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
async exists(storagePath) {
|
|
158
|
+
try {
|
|
159
|
+
await this.client.send(new HeadObjectCommand({
|
|
160
|
+
Bucket: this.bucket,
|
|
161
|
+
Key: storagePath,
|
|
162
|
+
}));
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const name = err.name;
|
|
167
|
+
const status = err.$metadata?.httpStatusCode;
|
|
168
|
+
if (name === 'NotFound' || name === 'NoSuchKey' || status === 404) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
131
174
|
getUrl(storagePath) {
|
|
132
175
|
return `${this.publicUrl}/${storagePath}`;
|
|
133
176
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/storage-s3",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.20.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@aws-sdk/client-s3": "^3.1081.0",
|
|
43
43
|
"@aws-sdk/lib-storage": "^3.1081.0",
|
|
44
44
|
"uuid": "^14.0.1",
|
|
45
|
-
"@byline/core": "3.
|
|
45
|
+
"@byline/core": "3.20.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@biomejs/biome": "2.5.2",
|