@atproto/aws 0.1.5 → 0.1.7
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 +14 -0
- package/LICENSE.txt +1 -1
- package/dist/bunny.d.ts +1 -1
- package/dist/cloudfront.d.ts +1 -1
- package/dist/index.js +797 -41
- package/dist/index.js.map +3 -3
- package/dist/kms.d.ts +1 -1
- package/dist/s3.d.ts +8 -2
- package/package.json +3 -3
- package/src/s3.ts +53 -13
package/dist/kms.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as aws from '@aws-sdk/client-kms';
|
|
2
2
|
import * as crypto from '@atproto/crypto';
|
|
3
|
-
export
|
|
3
|
+
export type KmsConfig = {
|
|
4
4
|
keyId: string;
|
|
5
5
|
} & Omit<aws.KMSClientConfig, 'apiVersion'>;
|
|
6
6
|
export declare class KmsKeypair implements crypto.Keypair {
|
package/dist/s3.d.ts
CHANGED
|
@@ -3,13 +3,15 @@ import * as aws from '@aws-sdk/client-s3';
|
|
|
3
3
|
import { BlobStore } from '@atproto/repo';
|
|
4
4
|
import { CID } from 'multiformats/cid';
|
|
5
5
|
import stream from 'stream';
|
|
6
|
-
export
|
|
6
|
+
export type S3Config = {
|
|
7
7
|
bucket: string;
|
|
8
8
|
} & Omit<aws.S3ClientConfig, 'apiVersion'>;
|
|
9
9
|
export declare class S3BlobStore implements BlobStore {
|
|
10
|
+
did: string;
|
|
10
11
|
private client;
|
|
11
12
|
private bucket;
|
|
12
|
-
constructor(cfg: S3Config);
|
|
13
|
+
constructor(did: string, cfg: S3Config);
|
|
14
|
+
static creator(cfg: S3Config): (did: string) => S3BlobStore;
|
|
13
15
|
private genKey;
|
|
14
16
|
private getTmpPath;
|
|
15
17
|
private getStoredPath;
|
|
@@ -23,8 +25,12 @@ export declare class S3BlobStore implements BlobStore {
|
|
|
23
25
|
getBytes(cid: CID): Promise<Uint8Array>;
|
|
24
26
|
getStream(cid: CID): Promise<stream.Readable>;
|
|
25
27
|
delete(cid: CID): Promise<void>;
|
|
28
|
+
deleteMany(cids: CID[]): Promise<void>;
|
|
26
29
|
hasStored(cid: CID): Promise<boolean>;
|
|
30
|
+
hasTemp(key: string): Promise<boolean>;
|
|
31
|
+
private hasKey;
|
|
27
32
|
private deleteKey;
|
|
33
|
+
private deleteManyKeys;
|
|
28
34
|
private move;
|
|
29
35
|
}
|
|
30
36
|
export default S3BlobStore;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/aws",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Shared AWS cloud API helpers for atproto services",
|
|
6
6
|
"keywords": [
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"multiformats": "^9.9.0",
|
|
25
25
|
"uint8arrays": "3.0.0",
|
|
26
26
|
"@atproto/common": "^0.3.3",
|
|
27
|
-
"@atproto/
|
|
28
|
-
"@atproto/
|
|
27
|
+
"@atproto/repo": "^0.3.7",
|
|
28
|
+
"@atproto/crypto": "^0.3.0"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "node ./build.js",
|
package/src/s3.ts
CHANGED
|
@@ -17,7 +17,7 @@ export class S3BlobStore implements BlobStore {
|
|
|
17
17
|
private client: aws.S3
|
|
18
18
|
private bucket: string
|
|
19
19
|
|
|
20
|
-
constructor(cfg: S3Config) {
|
|
20
|
+
constructor(public did: string, cfg: S3Config) {
|
|
21
21
|
const { bucket, ...rest } = cfg
|
|
22
22
|
this.bucket = bucket
|
|
23
23
|
this.client = new aws.S3({
|
|
@@ -26,20 +26,26 @@ export class S3BlobStore implements BlobStore {
|
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
static creator(cfg: S3Config) {
|
|
30
|
+
return (did: string) => {
|
|
31
|
+
return new S3BlobStore(did, cfg)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
private genKey() {
|
|
30
36
|
return randomStr(32, 'base32')
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
private getTmpPath(key: string): string {
|
|
34
|
-
return `tmp/${key}`
|
|
40
|
+
return `tmp/${this.did}/${key}`
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
private getStoredPath(cid: CID): string {
|
|
38
|
-
return `blocks/${cid.toString()}`
|
|
44
|
+
return `blocks/${this.did}/${cid.toString()}`
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
private getQuarantinedPath(cid: CID): string {
|
|
42
|
-
return `quarantine/${cid.toString()}`
|
|
48
|
+
return `quarantine/${this.did}/${cid.toString()}`
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
async putTemp(bytes: Uint8Array | stream.Readable): Promise<string> {
|
|
@@ -122,11 +128,24 @@ export class S3BlobStore implements BlobStore {
|
|
|
122
128
|
await this.deleteKey(this.getStoredPath(cid))
|
|
123
129
|
}
|
|
124
130
|
|
|
131
|
+
async deleteMany(cids: CID[]): Promise<void> {
|
|
132
|
+
const keys = cids.map((cid) => this.getStoredPath(cid))
|
|
133
|
+
await this.deleteManyKeys(keys)
|
|
134
|
+
}
|
|
135
|
+
|
|
125
136
|
async hasStored(cid: CID): Promise<boolean> {
|
|
137
|
+
return this.hasKey(this.getStoredPath(cid))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async hasTemp(key: string): Promise<boolean> {
|
|
141
|
+
return this.hasKey(this.getTmpPath(key))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private async hasKey(key: string) {
|
|
126
145
|
try {
|
|
127
146
|
const res = await this.client.headObject({
|
|
128
147
|
Bucket: this.bucket,
|
|
129
|
-
Key:
|
|
148
|
+
Key: key,
|
|
130
149
|
})
|
|
131
150
|
return res.$metadata.httpStatusCode === 200
|
|
132
151
|
} catch (err) {
|
|
@@ -141,17 +160,38 @@ export class S3BlobStore implements BlobStore {
|
|
|
141
160
|
})
|
|
142
161
|
}
|
|
143
162
|
|
|
144
|
-
private async
|
|
145
|
-
await this.client.
|
|
146
|
-
Bucket: this.bucket,
|
|
147
|
-
CopySource: `${this.bucket}/${keys.from}`,
|
|
148
|
-
Key: keys.to,
|
|
149
|
-
})
|
|
150
|
-
await this.client.deleteObject({
|
|
163
|
+
private async deleteManyKeys(keys: string[]) {
|
|
164
|
+
await this.client.deleteObjects({
|
|
151
165
|
Bucket: this.bucket,
|
|
152
|
-
|
|
166
|
+
Delete: {
|
|
167
|
+
Objects: keys.map((k) => ({ Key: k })),
|
|
168
|
+
},
|
|
153
169
|
})
|
|
154
170
|
}
|
|
171
|
+
|
|
172
|
+
private async move(keys: { from: string; to: string }) {
|
|
173
|
+
try {
|
|
174
|
+
await this.client.copyObject({
|
|
175
|
+
Bucket: this.bucket,
|
|
176
|
+
CopySource: `${this.bucket}/${keys.from}`,
|
|
177
|
+
Key: keys.to,
|
|
178
|
+
})
|
|
179
|
+
await this.client.deleteObject({
|
|
180
|
+
Bucket: this.bucket,
|
|
181
|
+
Key: keys.from,
|
|
182
|
+
})
|
|
183
|
+
} catch (err) {
|
|
184
|
+
handleErr(err)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const handleErr = (err: unknown) => {
|
|
190
|
+
if (err?.['Code'] === 'NoSuchKey') {
|
|
191
|
+
throw new BlobNotFoundError()
|
|
192
|
+
} else {
|
|
193
|
+
throw err
|
|
194
|
+
}
|
|
155
195
|
}
|
|
156
196
|
|
|
157
197
|
export default S3BlobStore
|