@spinajs/fs-s3 2.0.179 → 2.0.181
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/lib/cjs/config.d.ts +13 -0
- package/lib/cjs/config.d.ts.map +1 -0
- package/lib/cjs/config.js +26 -0
- package/lib/cjs/config.js.map +1 -0
- package/lib/cjs/index.d.ts +136 -110
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +381 -344
- package/lib/cjs/index.js.map +1 -1
- package/lib/mjs/config.d.ts +13 -0
- package/lib/mjs/config.d.ts.map +1 -0
- package/lib/mjs/config.js +24 -0
- package/lib/mjs/config.js.map +1 -0
- package/lib/mjs/index.d.ts +136 -110
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +352 -338
- package/lib/mjs/index.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +9 -8
package/lib/mjs/index.js
CHANGED
|
@@ -1,339 +1,353 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
-
};
|
|
10
|
-
import { Injectable, PerInstanceCheck } from '@spinajs/di';
|
|
11
|
-
import { Log, Logger } from '@spinajs/log-common';
|
|
12
|
-
import { fs, FileSystem } from '@spinajs/fs';
|
|
13
|
-
import { S3Client, HeadObjectCommand, CopyObjectCommand, DeleteObjectCommand, ListObjectsV2Command, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
14
|
-
import { Upload } from '@aws-sdk/lib-storage';
|
|
15
|
-
import { Config } from '@spinajs/configuration';
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
/**
|
|
23
|
-
* Abstract layer for file operations.
|
|
24
|
-
* Basic implementation is just wrapper for native node fs functions
|
|
25
|
-
*
|
|
26
|
-
* It allows to wrap other libs eg. aws s3, ftp
|
|
27
|
-
* and inject it into code without changing logic that use them.
|
|
28
|
-
*
|
|
29
|
-
* TODO: map errors to some kind of common errors shared with other implementations
|
|
30
|
-
*/
|
|
31
|
-
let fsS3 = class fsS3 extends fs {
|
|
32
|
-
/**
|
|
33
|
-
* Name of provider. We can have multiple providers of the same type but with different options.
|
|
34
|
-
* Also used in InjectService decorator for mapping
|
|
35
|
-
*/
|
|
36
|
-
get Name() {
|
|
37
|
-
return this.Options.name;
|
|
38
|
-
}
|
|
39
|
-
constructor(Options) {
|
|
40
|
-
super();
|
|
41
|
-
this.Options = Options;
|
|
42
|
-
}
|
|
43
|
-
async resolve() {
|
|
44
|
-
this.S3 = new S3Client(this.AwsConfig
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
*
|
|
182
|
-
* @param path
|
|
183
|
-
* @param
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Autoinject, Injectable, PerInstanceCheck } from '@spinajs/di';
|
|
11
|
+
import { Log, Logger } from '@spinajs/log-common';
|
|
12
|
+
import { fs, FileSystem, FileInfoService } from '@spinajs/fs';
|
|
13
|
+
import { S3Client, HeadObjectCommand, CopyObjectCommand, DeleteObjectCommand, ListObjectsV2Command, GetObjectCommand, } from '@aws-sdk/client-s3';
|
|
14
|
+
import { Upload } from '@aws-sdk/lib-storage';
|
|
15
|
+
import { Config } from '@spinajs/configuration';
|
|
16
|
+
import path, { basename } from 'path';
|
|
17
|
+
import { IOFail, MethodNotImplemented } from '@spinajs/exceptions';
|
|
18
|
+
import { createReadStream, existsSync } from 'fs';
|
|
19
|
+
import { DateTime } from 'luxon';
|
|
20
|
+
import { Readable } from 'stream';
|
|
21
|
+
import iconv from 'iconv-lite';
|
|
22
|
+
/**
|
|
23
|
+
* Abstract layer for file operations.
|
|
24
|
+
* Basic implementation is just wrapper for native node fs functions
|
|
25
|
+
*
|
|
26
|
+
* It allows to wrap other libs eg. aws s3, ftp
|
|
27
|
+
* and inject it into code without changing logic that use them.
|
|
28
|
+
*
|
|
29
|
+
* TODO: map errors to some kind of common errors shared with other implementations
|
|
30
|
+
*/
|
|
31
|
+
let fsS3 = class fsS3 extends fs {
|
|
32
|
+
/**
|
|
33
|
+
* Name of provider. We can have multiple providers of the same type but with different options.
|
|
34
|
+
* Also used in InjectService decorator for mapping
|
|
35
|
+
*/
|
|
36
|
+
get Name() {
|
|
37
|
+
return this.Options.name;
|
|
38
|
+
}
|
|
39
|
+
constructor(Options) {
|
|
40
|
+
super();
|
|
41
|
+
this.Options = Options;
|
|
42
|
+
}
|
|
43
|
+
async resolve() {
|
|
44
|
+
this.S3 = new S3Client(Object.assign({}, this.AwsConfig, {
|
|
45
|
+
endpoint: this.AwsConfig.endpoint ?? undefined,
|
|
46
|
+
logger: {
|
|
47
|
+
trace: (msg) => this.Logger.trace(msg),
|
|
48
|
+
debug: (msg) => this.Logger.debug(msg),
|
|
49
|
+
info: (msg) => this.Logger.info(msg),
|
|
50
|
+
warn: (msg) => this.Logger.warn(msg),
|
|
51
|
+
error: (msg) => this.Logger.error(msg),
|
|
52
|
+
},
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* Tries to download file to local filesystem, then returns local filesystem path.
|
|
58
|
+
* Native implementation simply returns local path and does nothing.
|
|
59
|
+
*
|
|
60
|
+
* @param path - file to download
|
|
61
|
+
*/
|
|
62
|
+
async download(path) {
|
|
63
|
+
const tmpName = this.TempFs.tmppath();
|
|
64
|
+
const wStream = await this.TempFs.writeStream(tmpName);
|
|
65
|
+
const command = new GetObjectCommand({
|
|
66
|
+
Bucket: this.Options.bucket,
|
|
67
|
+
Key: path,
|
|
68
|
+
});
|
|
69
|
+
const result = await this.S3.send(command);
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
if (result.Body instanceof Readable) {
|
|
72
|
+
result.Body.pipe(wStream)
|
|
73
|
+
.on('error', (err) => reject(err))
|
|
74
|
+
.on('close', () => resolve(tmpName));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
reject(new IOFail(`Cannot download file ${path}, empty response`));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* read all content of file
|
|
83
|
+
*/
|
|
84
|
+
async read(path, encoding) {
|
|
85
|
+
const fLocal = await this.download(path);
|
|
86
|
+
const content = await this.TempFs.read(fLocal, encoding);
|
|
87
|
+
await this.TempFs.rm(fLocal);
|
|
88
|
+
return content;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param path
|
|
93
|
+
* @param _encoding
|
|
94
|
+
* @returns
|
|
95
|
+
*/
|
|
96
|
+
async readStream(path, encoding) {
|
|
97
|
+
const command = new GetObjectCommand({
|
|
98
|
+
Bucket: this.Options.bucket,
|
|
99
|
+
Key: path,
|
|
100
|
+
});
|
|
101
|
+
const result = await this.S3.send(command);
|
|
102
|
+
const rStream = result.Body;
|
|
103
|
+
if (encoding) {
|
|
104
|
+
const encodedStream = rStream.pipe(iconv.decodeStream(encoding));
|
|
105
|
+
return encodedStream;
|
|
106
|
+
}
|
|
107
|
+
return rStream;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Write to file string or buffer
|
|
111
|
+
*/
|
|
112
|
+
async write(path, data, encoding) {
|
|
113
|
+
const upload = new Upload({
|
|
114
|
+
client: this.S3,
|
|
115
|
+
params: {
|
|
116
|
+
Bucket: this.Options.bucket,
|
|
117
|
+
Key: path,
|
|
118
|
+
Body: data,
|
|
119
|
+
ContentEncoding: encoding,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
await upload.done();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* NOTE: append on s3 downloads file, appends to it, then uploads it again
|
|
126
|
+
* so it can be slow on large files
|
|
127
|
+
*
|
|
128
|
+
* @param path
|
|
129
|
+
* @param data
|
|
130
|
+
* @param encoding
|
|
131
|
+
*/
|
|
132
|
+
async append(path, data, encoding) {
|
|
133
|
+
/**
|
|
134
|
+
* We cannot append to file in s3 directly,
|
|
135
|
+
* we have to download file first, append locally, then upload again new file
|
|
136
|
+
*/
|
|
137
|
+
const fLocal = await this.download(path);
|
|
138
|
+
await this.TempFs.append(fLocal, data, encoding);
|
|
139
|
+
await this.upload(fLocal, path);
|
|
140
|
+
}
|
|
141
|
+
async upload(srcPath, destPath) {
|
|
142
|
+
if (!existsSync(srcPath)) {
|
|
143
|
+
throw new IOFail(`file ${srcPath} does not exists`);
|
|
144
|
+
}
|
|
145
|
+
const dPath = destPath ?? basename(srcPath);
|
|
146
|
+
const rStream = createReadStream(srcPath);
|
|
147
|
+
const hash = await this.hash(srcPath, 'md5');
|
|
148
|
+
const fInfo = await this.FileInfo.getInfo(this.resolvePath(srcPath));
|
|
149
|
+
const upload = new Upload({
|
|
150
|
+
client: this.S3,
|
|
151
|
+
params: {
|
|
152
|
+
Bucket: this.Options.bucket,
|
|
153
|
+
Key: dPath,
|
|
154
|
+
Body: rStream,
|
|
155
|
+
// content md5 header is always base64 encoded
|
|
156
|
+
ContentMD5: Buffer.from(hash, 'hex').toString('base64'),
|
|
157
|
+
// convert all metadata values to string, and back to object with key-value pair of strings
|
|
158
|
+
Metadata: Object.fromEntries(Object.entries(fInfo).map(([key, value]) => [key, String(value)])),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
await upload.done();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
*
|
|
165
|
+
* Gets metadata of file in s3 bucket
|
|
166
|
+
*
|
|
167
|
+
* @param path path to file
|
|
168
|
+
* @returns
|
|
169
|
+
*/
|
|
170
|
+
async getMetadata(path) {
|
|
171
|
+
const command = new HeadObjectCommand({
|
|
172
|
+
Bucket: this.Options.bucket,
|
|
173
|
+
Key: path,
|
|
174
|
+
});
|
|
175
|
+
const result = await this.S3.send(command);
|
|
176
|
+
return result.Metadata;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
* Returns writable stream for given path
|
|
181
|
+
*
|
|
182
|
+
* @param path file path ( relative to base path of provider)
|
|
183
|
+
* @param rStream readable stream, must be provided beforehand
|
|
184
|
+
* @param encoding optional stream encoding
|
|
185
|
+
*/
|
|
186
|
+
async writeStream(_path, _encoding) {
|
|
187
|
+
throw new IOFail('Method not implemented, s3 does not support writable streams');
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Checks if file existst
|
|
191
|
+
* @param path - path to check
|
|
192
|
+
*/
|
|
193
|
+
async exists(path) {
|
|
194
|
+
try {
|
|
195
|
+
const command = new HeadObjectCommand({
|
|
196
|
+
Bucket: this.Options.bucket,
|
|
197
|
+
Key: path,
|
|
198
|
+
});
|
|
199
|
+
await this.S3.send(command);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (err.name === 'NotFound')
|
|
203
|
+
return false;
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
async dirExists() {
|
|
209
|
+
throw new IOFail('Method not implemented, s3 does not support directories');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Copy file to another location
|
|
213
|
+
* @param path - src path
|
|
214
|
+
* @param dest - dest path
|
|
215
|
+
*/
|
|
216
|
+
async copy(path, dest, dstFs) {
|
|
217
|
+
// if dest fs is set
|
|
218
|
+
// copy using it
|
|
219
|
+
if (dstFs) {
|
|
220
|
+
const file = await this.download(path);
|
|
221
|
+
await dstFs.upload(file, dest);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// we copy file in s3 by copying it to another location
|
|
225
|
+
const command = new CopyObjectCommand({
|
|
226
|
+
Bucket: this.Options.bucket,
|
|
227
|
+
CopySource: this.Options.bucket + '/' + path,
|
|
228
|
+
Key: dest,
|
|
229
|
+
});
|
|
230
|
+
await this.S3.send(command);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Copy file to another location and deletes src file
|
|
235
|
+
*/
|
|
236
|
+
async move(oldPath, newPath, dstFs) {
|
|
237
|
+
await this.copy(oldPath, newPath, dstFs);
|
|
238
|
+
await this.rm(oldPath);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Change name of a file
|
|
242
|
+
*/
|
|
243
|
+
async rename(oldPath, newPath) {
|
|
244
|
+
return this.move(oldPath, newPath);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
*
|
|
248
|
+
* Deletes dir recursively & all contents inside
|
|
249
|
+
*
|
|
250
|
+
* @param path - dir to remove
|
|
251
|
+
*/
|
|
252
|
+
async rm(_path) {
|
|
253
|
+
const command = new DeleteObjectCommand({
|
|
254
|
+
Bucket: this.Options.bucket,
|
|
255
|
+
Key: _path,
|
|
256
|
+
});
|
|
257
|
+
await this.S3.send(command);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
*
|
|
261
|
+
* Creates directory, recursively
|
|
262
|
+
*
|
|
263
|
+
*/
|
|
264
|
+
async mkdir() {
|
|
265
|
+
throw new IOFail('Method not implemented, s3 does not support directories');
|
|
266
|
+
}
|
|
267
|
+
async isDir(_path) {
|
|
268
|
+
throw new IOFail('Method not implemented, s3 does not support directories');
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Returns file statistics, not all fields may be accesible
|
|
272
|
+
*/
|
|
273
|
+
async stat(path) {
|
|
274
|
+
const command = new HeadObjectCommand({
|
|
275
|
+
Bucket: this.Options.bucket,
|
|
276
|
+
Key: path,
|
|
277
|
+
});
|
|
278
|
+
const result = await this.S3.send(command);
|
|
279
|
+
return {
|
|
280
|
+
// no directories in s3
|
|
281
|
+
IsDirectory: false,
|
|
282
|
+
// only files can be stored in s3
|
|
283
|
+
IsFile: true,
|
|
284
|
+
// no creation time
|
|
285
|
+
CreationTime: DateTime.min(),
|
|
286
|
+
ModifiedTime: DateTime.fromJSDate(result.LastModified),
|
|
287
|
+
// no access time in s3s
|
|
288
|
+
AccessTime: DateTime.min(),
|
|
289
|
+
Size: result.ContentLength,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
// protected async getSignedUrl(path: string) {
|
|
293
|
+
// return this.S3.getSignedUrlPromise('getObject', {
|
|
294
|
+
// Bucket: this.Options.bucket,
|
|
295
|
+
// Key: path,
|
|
296
|
+
// Expires: 24 * 60 * 60,
|
|
297
|
+
// });
|
|
298
|
+
// }
|
|
299
|
+
tmppath() {
|
|
300
|
+
throw new MethodNotImplemented('fs s3 does not support temporary paths');
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* List content of directory
|
|
304
|
+
*
|
|
305
|
+
* @param path - path to directory
|
|
306
|
+
*/
|
|
307
|
+
async list(path) {
|
|
308
|
+
const command = new ListObjectsV2Command({
|
|
309
|
+
Bucket: this.Options.bucket,
|
|
310
|
+
Delimiter: '/',
|
|
311
|
+
Prefix: path,
|
|
312
|
+
});
|
|
313
|
+
const result = await this.S3.send(command);
|
|
314
|
+
return result.Contents.map((x) => x.Key);
|
|
315
|
+
}
|
|
316
|
+
async unzip(_path, _destPath) {
|
|
317
|
+
throw new IOFail('Method not implemented, you should download zipped file first, then unzip it');
|
|
318
|
+
}
|
|
319
|
+
async zip(_path, _dstFs, _dstFile) {
|
|
320
|
+
throw new IOFail('Method not implemented, you should zip files locally, then upload it');
|
|
321
|
+
}
|
|
322
|
+
resolvePath(_path) {
|
|
323
|
+
// we checek if path is absolute
|
|
324
|
+
// for hash function
|
|
325
|
+
if (path.isAbsolute(_path)) {
|
|
326
|
+
return _path;
|
|
327
|
+
}
|
|
328
|
+
throw new MethodNotImplemented('fs s3 does not support path resolving');
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
__decorate([
|
|
332
|
+
Logger('fs'),
|
|
333
|
+
__metadata("design:type", Log)
|
|
334
|
+
], fsS3.prototype, "Logger", void 0);
|
|
335
|
+
__decorate([
|
|
336
|
+
Config('fs.s3.config'),
|
|
337
|
+
__metadata("design:type", Object)
|
|
338
|
+
], fsS3.prototype, "AwsConfig", void 0);
|
|
339
|
+
__decorate([
|
|
340
|
+
FileSystem('fs-temp-s3'),
|
|
341
|
+
__metadata("design:type", fs)
|
|
342
|
+
], fsS3.prototype, "TempFs", void 0);
|
|
343
|
+
__decorate([
|
|
344
|
+
Autoinject(),
|
|
345
|
+
__metadata("design:type", FileInfoService)
|
|
346
|
+
], fsS3.prototype, "FileInfo", void 0);
|
|
347
|
+
fsS3 = __decorate([
|
|
348
|
+
Injectable('fs'),
|
|
349
|
+
PerInstanceCheck(),
|
|
350
|
+
__metadata("design:paramtypes", [Object])
|
|
351
|
+
], fsS3);
|
|
352
|
+
export { fsS3 };
|
|
339
353
|
//# sourceMappingURL=index.js.map
|