-
Notifications
You must be signed in to change notification settings - Fork 1
/
S3.hx
118 lines (101 loc) · 4 KB
/
S3.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package why.fs;
import why.Fs;
import tink.http.Method;
#if nodejs
import js.node.Buffer;
import js.aws.s3.S3 as NativeS3;
#end
using tink.CoreApi;
using tink.io.Source;
using tink.io.Sink;
using StringTools;
using haxe.io.Path;
@:build(futurize.Futurize.build())
@:require('extern-js-aws-sdk')
class S3 implements Fs {
var bucket:String;
var s3:NativeS3;
public function new(bucket) {
this.bucket = bucket;
s3 = new NativeS3();
}
public function list(path:String):Promise<Array<String>> {
var prefix = sanitize(path).addTrailingSlash();
return @:futurize s3.listObjects({Bucket: bucket, Prefix: prefix}, $cb1)
.next(function(o):Array<String> return [for(obj in o.Contents) obj.Key.substr(prefix.length)]);
}
public function exists(path:String):Promise<Bool>
return @:futurize s3.headObject({Bucket: bucket, Key: sanitize(path)}, $cb1)
.next(function(_) return true)
.recover(function(_) return false);
public function move(from:String, to:String):Promise<Noise> {
var from = sanitize(from);
var to = sanitize(to);
// https://stackoverflow.com/a/38903136/3212365
return @:futurize s3.copyObject({Bucket: bucket, CopySource: '$bucket/$from', Key: to}, $cb1)
.next(function(_) return @:futurize s3.getObjectAcl({Bucket: bucket, Key: from}, $cb1))
.next(function(acl) return @:futurize s3.putObjectAcl({Bucket: bucket, Key: to, AccessControlPolicy: acl}, $cb1))
.next(function(_) return @:futurize s3.deleteObject({Bucket: bucket, Key: from}, $cb1));
}
public function read(path:String):RealSource {
return @:futurize s3.getObject({Bucket: bucket, Key: sanitize(path)}, $cb1)
.next(function(o):RealSource return (o.Body:Buffer).hxToBytes());
}
public function write(path:String, ?options:WriteOptions):RealSink {
var pass = new js.node.stream.PassThrough();
var buf = new Buffer(0);
pass.on('data', function(d) buf = Buffer.concat([buf, d]));
pass.on('end', function() @:futurize s3.putObject({
Bucket: bucket,
Key: sanitize(path),
Body: buf,
ACL: (options != null && options.isPublic) ? 'public-read' : 'private',
}, $cb1).eager());
var sink = Sink.ofNodeStream('Sink: $path', pass);
return sink;
}
public function delete(path:String):Promise<Noise> {
// TODO: delete folder
return @:futurize s3.deleteObject({Bucket: bucket, Key: sanitize(path)}, $cb1);
}
public function stat(path:String):Promise<Stat> {
return @:futurize s3.headObject({Bucket: bucket, Key: sanitize(path)}, $cb1)
.next(function(o):Stat return {
size: o.ContentLength,
mime: o.ContentType,
metadata: o.Metadata,
});
}
public function getDownloadUrl(path:String, ?options:DownloadOptions):Promise<UrlRequest> {
return if(options != null && options.isPublic && options.saveAsFilename == null)
{url: 'https://$bucket.s3.amazonaws.com/' + sanitize(path), method: GET}
else @:futurize s3.getSignedUrl('getObject', {
Bucket: bucket,
Key: sanitize(path),
ResponseContentDisposition: switch options {
case null | {saveAsFilename: null}: null;
case {saveAsFilename: filename}: 'attachment; filename="$filename"';
},
}, $cb1)
.next(function(url) return {url: url, method: GET});
}
public function getUploadUrl(path:String, ?options:UploadOptions):Promise<UrlRequest> {
if(options == null || options.mime == null) return new Error('Requires mime type');
return @:futurize s3.getSignedUrl('putObject', {
Bucket: bucket,
Key: sanitize(path),
ACL: (options != null && options.isPublic) ? 'public-read' : 'private',
ContentType: options.mime,
Metadata:
switch options {
case null | {metadata: null}: {}
case {metadata: obj}: obj;
}
}, $cb1)
.next(function(url) return {url: url, method: PUT});
}
static function sanitize(path:String) {
if(path.startsWith('/')) path = path.substr(1);
return path;
}
}