2020-03-12 10:26:31 +00:00
# [s3.js](https://git.rootprojects.org/root/s3.js) | a [Root](https://rootprojects.org) project
2020-12-17 20:50:30 +00:00
> Minimalist S3 client \
> (for AWS, Minio, Digital Ocean Spaces, etc)
2020-03-12 10:26:31 +00:00
2020-12-17 20:50:30 +00:00
A lightweight alternative to the S3 SDK that uses only @root/request and aws4.
2020-03-12 10:26:31 +00:00
2020-09-10 08:12:43 +00:00
- set()
- get()
- head()
- delete()
- sign()
2020-12-17 20:50:30 +00:00
### Download a file from S3
2020-09-10 08:12:43 +00:00
2021-01-26 23:57:20 +00:00
This library supports the same streaming options as [@root/request.js ](https://git.rootprojects.org/root/request.js ).
#### as a stream
```js
var resp = await s3.get({
accessKeyId, // 'AKIAXXXXXXXXXXXXXXXX'
secretAccessKey, // 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
region, // 'us-east-2'
bucket, // 'bucket-name'
prefix, // 'my-prefix/' (optional)
key, // 'data/stats.csv' (omits prefix, if any)
stream // fs.createWriteStream('./path/to/file.bin')
});
await resp.stream;
```
#### in-memory
2020-09-10 08:12:43 +00:00
```js
2021-01-26 23:57:20 +00:00
var resp = await s3.get({
2020-12-17 20:50:30 +00:00
accessKeyId, // 'AKIAXXXXXXXXXXXXXXXX'
secretAccessKey, // 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
region, // 'us-east-2'
bucket, // 'bucket-name'
prefix, // 'my-prefix/' (optional)
key // 'data/stats.csv' (omits prefix, if any)
2020-09-10 08:12:43 +00:00
});
2021-01-26 23:57:20 +00:00
fs.writeFile(resp.body, './path/to/file.bin');
2020-09-10 08:12:43 +00:00
```
2020-12-17 20:50:30 +00:00
### Upload a new file to S3
2020-03-12 10:26:31 +00:00
```js
2021-01-26 23:57:20 +00:00
await s3.set({
2020-03-12 10:26:31 +00:00
accessKeyId,
secretAccessKey,
region,
bucket,
prefix,
key,
2020-12-18 04:42:01 +00:00
body, // Buffer.from("hello, world")
2020-12-17 20:50:30 +00:00
// or fs.createReadStream("./file.txt")
2020-12-18 04:42:01 +00:00
size // (await fs.stat("./file.txt")).size (required for streams)
2020-09-10 08:12:43 +00:00
});
```
2021-01-26 23:57:20 +00:00
### Check that a file exists
```js
var resp = await s3.head({
accessKeyId, // 'AKIAXXXXXXXXXXXXXXXX'
secretAccessKey, // 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
region, // 'us-east-2'
bucket, // 'bucket-name'
prefix, // 'my-prefix/' (optional)
key // 'data/stats.csv' (omits prefix, if any)
});
console.log(resp.headers);
```
### Delete file
```js
var resp = await s3.delete({
accessKeyId, // 'AKIAXXXXXXXXXXXXXXXX'
secretAccessKey, // 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
region, // 'us-east-2'
bucket, // 'bucket-name'
prefix, // 'my-prefix/' (optional)
key // 'data/stats.csv' (omits prefix, if any)
});
console.log(resp.headers);
```
2020-12-17 20:50:30 +00:00
### Return signed URL without fetching.
2020-09-10 08:12:43 +00:00
```js
s3.sign({
method: 'get',
accessKeyId,
secretAccessKey,
region,
bucket,
prefix,
key
});
2021-01-26 23:57:20 +00:00
````
2020-03-17 01:58:31 +00:00
2020-12-17 20:50:30 +00:00
### A note on S3 terminology
| | |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `bucket` | most similar to what most people think of as a "**folder**"< br > **MUST NOT** contain a slash `/` |
| `key` < br > ("object key") | most similar to a "**file name**"< br > may contain "**/**"s as part of the name< br > **MUST NOT BEGIN** with a slash `/` |
| `prefix` | an informal term, refers to "**file path**"< br > what the AWS console uses for created virtual folder-like views and searches< br > **MUST END** with a slash `/` |
This library provides `prefix` (of `key` ) for convenience.
`s3://bucket-name/long/prefix/data/stats.csv` can be represented equally well by any of the following:
(no prefix)
```json
{
"bucket": "bucket-name",
"prefix": "",
"key": "long/prefix/data/stats.csv"
}
```
(with long prefix)
```json
{
"bucket": "bucket-name",
"prefix": "long/prefix/data/",
"key": "stats.csv"
}
```
(with short prefix)
```json
{
"bucket": "bucket-name",
"prefix": "long/",
"key": "prefix/data/stats.csv"
}
```
### Troubleshooting
2020-03-17 01:58:31 +00:00
If the body is a stream then `size` must be set to `fs.statSync(filePath).size` , or the request will fail:
```
501
< Code > NotImplemented< / Code > < Message > A header you provided implies functionality that is not implemented< / Message >
```