@qrvey/object-storage 0.0.1 → 0.0.2
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/README.md +1 -1
- package/dist/cjs/index.js +2 -282
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.mts +45 -0
- package/dist/esm/index.mjs +5 -55
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +4 -15
- package/dist/esm/blobStorage.service-Q2W6LO3S.mjs +0 -105
- package/dist/esm/blobStorage.service-Q2W6LO3S.mjs.map +0 -1
- package/dist/esm/chunk-JHXQKOVY.mjs +0 -10
- package/dist/esm/chunk-JHXQKOVY.mjs.map +0 -1
- package/dist/esm/s3Storage.service-OZGBAWBM.mjs +0 -100
- package/dist/esm/s3Storage.service-OZGBAWBM.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @qrvey/object-storage
|
|
2
2
|
|
|
3
3
|

|
|
4
|
-

|
|
5
5
|
|
|
6
6
|
The `@qrvey/object-storage` package provides a unified interface for ...
|
|
7
7
|
|
package/dist/cjs/index.js
CHANGED
|
@@ -4,288 +4,8 @@ var storageBlob = require('@azure/storage-blob');
|
|
|
4
4
|
var clientS3 = require('@aws-sdk/client-s3');
|
|
5
5
|
var s3RequestPresigner = require('@aws-sdk/s3-request-presigner');
|
|
6
6
|
|
|
7
|
-
var
|
|
8
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
-
var __knownSymbol = (name, symbol) => {
|
|
10
|
-
if (symbol = Symbol[name])
|
|
11
|
-
return symbol;
|
|
12
|
-
throw Error("Symbol." + name + " is not defined");
|
|
13
|
-
};
|
|
14
|
-
var __esm = (fn, res) => function __init() {
|
|
15
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
-
};
|
|
17
|
-
var __export = (target, all) => {
|
|
18
|
-
for (var name in all)
|
|
19
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
20
|
-
};
|
|
21
|
-
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
7
|
+
var C=(r,e)=>{if(e=Symbol[r])return e;throw Error("Symbol."+r+" is not defined")};var u=(r,e,t)=>(e=r[C("asyncIterator")])?e.call(r):(r=r[C("iterator")](),e={},t=(n,o)=>(o=r[n])&&(e[n]=s=>new Promise((a,i,c)=>(s=o.call(r,s),c=s.done,Promise.resolve(s.value).then(p=>a({value:p,done:c}),i)))),t("next"),t("return"),e);var l=class{constructor(e){this.containerName=e,this.blobServiceClient=storageBlob.BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING);}async list(){let e=[],t=this.blobServiceClient.getContainerClient(this.containerName);try{for(var n=u(t.listBlobsFlat()),o,s,a;o=!(s=await n.next()).done;o=!1){let i=s.value;e.push(i.name);}}catch(s){a=[s];}finally{try{o&&(s=n.return)&&await s.call(n);}finally{if(a)throw a[0]}}return new Promise(i=>i({keys:e}))}getObject(e){return new Promise((t,n)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).download(0).then(a=>t({body:a.readableStreamBody,metadata:{},contentType:"",contentLength:0}));}catch(o){return n(o)}})}async getSignedUrl(e,t){return new Promise((n,o)=>{try{let a=this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e),i=new Date,c=new Date(i);c.setMinutes(i.getMinutes()+t),a.generateSasUrl({permissions:storageBlob.BlobSASPermissions.parse("r"),startsOn:i,expiresOn:c}).then(p=>n(p));}catch(s){return o(s)}})}async upload(e,t,n){return new Promise((o,s)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).uploadStream(t).then(()=>o({key:e}));}catch(a){return s(a)}})}delete(e){return new Promise((t,n)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).delete().then(()=>t(!0));}catch(o){return n(o)}})}};var m=class{constructor(e){this.bucketName=e,this.s3Client=new clientS3.S3Client({});}async list(){let e=[],t;do{let n=new clientS3.ListObjectsV2Command({Bucket:this.bucketName,ContinuationToken:t}),o=await this.s3Client.send(n);if(o.Contents)for(let s of o.Contents)s.Key&&e.push(s.Key);t=o.NextContinuationToken;}while(t);return {keys:e}}async getObject(e){var o,s;let t=new clientS3.GetObjectCommand({Bucket:this.bucketName,Key:e}),n=await this.s3Client.send(t);return {body:n.Body,metadata:(o=n.Metadata)!=null?o:{},contentType:(s=n.ContentType)!=null?s:"",contentLength:n.ContentLength}}getSignedUrl(e,t=60){let n=t*60,o=new clientS3.GetObjectCommand({Bucket:this.bucketName,Key:e});return s3RequestPresigner.getSignedUrl(this.s3Client,o,{expiresIn:n})}async upload(e,t,n){let o=new clientS3.PutObjectCommand({Bucket:this.bucketName,Key:e,Body:t,Metadata:n});return await this.s3Client.send(o),{key:e}}async delete(e){let t=new clientS3.DeleteObjectCommand({Bucket:this.bucketName,Key:e});return await this.s3Client.send(t),!0}};var b=class{static async instance(e){var n;return ((n=process.env.OBJECT_STORAGE_SERVICE)==null?void 0:n.toLowerCase())==="azure_blob_storage"?new l(e):new m(e)}};var g=class r{constructor(e){r.bucketName=e;}static async getObjectStorageServiceInstance(e=r.bucketName){if(!e)throw new Error("Bucket name not provided or not valid value");return b.instance(e)}static async list(e){return r.getObjectStorageServiceInstance(e).then(t=>t.list())}static async getObject(e,t){return r.getObjectStorageServiceInstance(t).then(n=>n.getObject(e))}static async getSignedUrl(e,t,n){return r.getObjectStorageServiceInstance(n).then(o=>o.getSignedUrl(e,t))}static async upload(e,t,n,o){return r.getObjectStorageServiceInstance(o).then(s=>s.upload(e,t,n))}static async delete(e,t){return r.getObjectStorageServiceInstance(t).then(n=>n.delete(e))}};
|
|
22
8
|
|
|
23
|
-
|
|
24
|
-
var blobStorage_service_exports = {};
|
|
25
|
-
__export(blobStorage_service_exports, {
|
|
26
|
-
BlobStorageService: () => BlobStorageService
|
|
27
|
-
});
|
|
28
|
-
var BlobStorageService;
|
|
29
|
-
var init_blobStorage_service = __esm({
|
|
30
|
-
"src/services/storage/blob/blobStorage.service.ts"() {
|
|
31
|
-
BlobStorageService = class {
|
|
32
|
-
constructor(containerName) {
|
|
33
|
-
this.containerName = containerName;
|
|
34
|
-
this.blobServiceClient = storageBlob.BlobServiceClient.fromConnectionString(
|
|
35
|
-
process.env.AZURE_STORAGE_CONNECTION_STRING
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
async list() {
|
|
39
|
-
const list = [];
|
|
40
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
41
|
-
this.containerName
|
|
42
|
-
);
|
|
43
|
-
try {
|
|
44
|
-
for (var iter = __forAwait(containerClient.listBlobsFlat()), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
|
|
45
|
-
const containerItem = temp.value;
|
|
46
|
-
list.push(containerItem.name);
|
|
47
|
-
}
|
|
48
|
-
} catch (temp) {
|
|
49
|
-
error = [temp];
|
|
50
|
-
} finally {
|
|
51
|
-
try {
|
|
52
|
-
more && (temp = iter.return) && await temp.call(iter);
|
|
53
|
-
} finally {
|
|
54
|
-
if (error)
|
|
55
|
-
throw error[0];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return new Promise((resolve) => resolve({ keys: list }));
|
|
59
|
-
}
|
|
60
|
-
getObject(blobName) {
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
try {
|
|
63
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
64
|
-
this.containerName
|
|
65
|
-
);
|
|
66
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
67
|
-
blockBlobClient.download(0).then((downloadBlockBlobResponse) => {
|
|
68
|
-
return resolve({
|
|
69
|
-
body: downloadBlockBlobResponse.readableStreamBody,
|
|
70
|
-
metadata: {},
|
|
71
|
-
contentType: "",
|
|
72
|
-
contentLength: 0
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
} catch (error) {
|
|
76
|
-
return reject(error);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
async getSignedUrl(blobName, expiresInMinutes) {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
82
|
-
try {
|
|
83
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
84
|
-
this.containerName
|
|
85
|
-
);
|
|
86
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
87
|
-
const startDate = /* @__PURE__ */ new Date();
|
|
88
|
-
const expiryDate = new Date(startDate);
|
|
89
|
-
expiryDate.setMinutes(
|
|
90
|
-
startDate.getMinutes() + expiresInMinutes
|
|
91
|
-
);
|
|
92
|
-
blockBlobClient.generateSasUrl({
|
|
93
|
-
permissions: storageBlob.BlobSASPermissions.parse("r"),
|
|
94
|
-
startsOn: startDate,
|
|
95
|
-
expiresOn: expiryDate
|
|
96
|
-
}).then((sasUrl) => resolve(sasUrl));
|
|
97
|
-
} catch (error) {
|
|
98
|
-
return reject(error);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
async upload(blobName, body, metadata) {
|
|
103
|
-
return new Promise((resolve, reject) => {
|
|
104
|
-
try {
|
|
105
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
106
|
-
this.containerName
|
|
107
|
-
);
|
|
108
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
109
|
-
blockBlobClient.uploadStream(body).then(() => resolve({ key: blobName }));
|
|
110
|
-
} catch (error) {
|
|
111
|
-
return reject(error);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
delete(blobName) {
|
|
116
|
-
return new Promise((resolve, reject) => {
|
|
117
|
-
try {
|
|
118
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
119
|
-
this.containerName
|
|
120
|
-
);
|
|
121
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
122
|
-
blockBlobClient.delete().then(() => resolve(true));
|
|
123
|
-
} catch (error) {
|
|
124
|
-
return reject(error);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// src/services/storage/s3/s3Storage.service.ts
|
|
133
|
-
var s3Storage_service_exports = {};
|
|
134
|
-
__export(s3Storage_service_exports, {
|
|
135
|
-
S3StorageService: () => S3StorageService
|
|
136
|
-
});
|
|
137
|
-
var S3StorageService;
|
|
138
|
-
var init_s3Storage_service = __esm({
|
|
139
|
-
"src/services/storage/s3/s3Storage.service.ts"() {
|
|
140
|
-
S3StorageService = class {
|
|
141
|
-
constructor(bucketName) {
|
|
142
|
-
this.bucketName = bucketName;
|
|
143
|
-
this.s3Client = new clientS3.S3Client({});
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Lists all objects in the S3 bucket.
|
|
147
|
-
* @returns A promise that resolves to a list of object keys.
|
|
148
|
-
*/
|
|
149
|
-
async list() {
|
|
150
|
-
const allKeys = [];
|
|
151
|
-
let continuationToken = void 0;
|
|
152
|
-
do {
|
|
153
|
-
const command = new clientS3.ListObjectsV2Command({
|
|
154
|
-
Bucket: this.bucketName,
|
|
155
|
-
ContinuationToken: continuationToken
|
|
156
|
-
});
|
|
157
|
-
const response = await this.s3Client.send(command);
|
|
158
|
-
if (response.Contents) {
|
|
159
|
-
for (const item of response.Contents) {
|
|
160
|
-
if (item.Key)
|
|
161
|
-
allKeys.push(item.Key);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
continuationToken = response.NextContinuationToken;
|
|
165
|
-
} while (continuationToken);
|
|
166
|
-
return { keys: allKeys };
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Retrieves an object from the S3 bucket.
|
|
170
|
-
* @param key - The key of the object to retrieve.
|
|
171
|
-
* @returns A promise that resolves to the content of the file.
|
|
172
|
-
*/
|
|
173
|
-
async getObject(key) {
|
|
174
|
-
var _a, _b;
|
|
175
|
-
const command = new clientS3.GetObjectCommand({
|
|
176
|
-
Bucket: this.bucketName,
|
|
177
|
-
Key: key
|
|
178
|
-
});
|
|
179
|
-
const response = await this.s3Client.send(command);
|
|
180
|
-
return {
|
|
181
|
-
body: response.Body,
|
|
182
|
-
metadata: (_a = response.Metadata) != null ? _a : {},
|
|
183
|
-
contentType: (_b = response.ContentType) != null ? _b : "",
|
|
184
|
-
contentLength: response.ContentLength
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Generates a signed URL for accessing an object in the S3 bucket.
|
|
189
|
-
* @param key - The key of the object.
|
|
190
|
-
* @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.
|
|
191
|
-
* @returns A promise that resolves to the signed URL.
|
|
192
|
-
*/
|
|
193
|
-
getSignedUrl(key, expiresInMinutes = 60) {
|
|
194
|
-
const expiresIn = expiresInMinutes * 60;
|
|
195
|
-
const command = new clientS3.GetObjectCommand({
|
|
196
|
-
Bucket: this.bucketName,
|
|
197
|
-
Key: key
|
|
198
|
-
});
|
|
199
|
-
return s3RequestPresigner.getSignedUrl(this.s3Client, command, { expiresIn });
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Uploads an object to the S3 bucket.
|
|
203
|
-
* @param key - The key of the object to upload.
|
|
204
|
-
* @param body - The content of the object to upload.
|
|
205
|
-
* @param metadata - Optional metadata to associate with the object.
|
|
206
|
-
* @returns A promise that resolves to the response containing the key of the uploaded object.
|
|
207
|
-
*/
|
|
208
|
-
async upload(key, body, metadata) {
|
|
209
|
-
const command = new clientS3.PutObjectCommand({
|
|
210
|
-
Bucket: this.bucketName,
|
|
211
|
-
Key: key,
|
|
212
|
-
Body: body,
|
|
213
|
-
Metadata: metadata
|
|
214
|
-
});
|
|
215
|
-
await this.s3Client.send(command);
|
|
216
|
-
return { key };
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Deletes an object from the S3 bucket.
|
|
220
|
-
* @param key - The key of the object to delete.
|
|
221
|
-
* @returns A promise that resolves to true if the object was deleted successfully.
|
|
222
|
-
*/
|
|
223
|
-
async delete(key) {
|
|
224
|
-
const command = new clientS3.DeleteObjectCommand({
|
|
225
|
-
Bucket: this.bucketName,
|
|
226
|
-
Key: key
|
|
227
|
-
});
|
|
228
|
-
await this.s3Client.send(command);
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// src/services/objectStorageFactory.service.ts
|
|
236
|
-
var ObjectStorageFactory = class {
|
|
237
|
-
static async instance(bucketName) {
|
|
238
|
-
var _a;
|
|
239
|
-
const isBlobStorageService = ((_a = process.env.OBJECT_STORAGE_SERVICE) == null ? void 0 : _a.toLowerCase()) === "azure_blob_storage";
|
|
240
|
-
let ObjectStorageService2;
|
|
241
|
-
if (isBlobStorageService) {
|
|
242
|
-
const module = await Promise.resolve().then(() => (init_blobStorage_service(), blobStorage_service_exports));
|
|
243
|
-
ObjectStorageService2 = module.BlobStorageService;
|
|
244
|
-
} else {
|
|
245
|
-
const module = await Promise.resolve().then(() => (init_s3Storage_service(), s3Storage_service_exports));
|
|
246
|
-
ObjectStorageService2 = module.S3StorageService;
|
|
247
|
-
}
|
|
248
|
-
return new ObjectStorageService2(bucketName);
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// src/services/objectStorage.service.ts
|
|
253
|
-
var ObjectStorageService = class _ObjectStorageService {
|
|
254
|
-
constructor(bucketName) {
|
|
255
|
-
_ObjectStorageService.bucketName = bucketName;
|
|
256
|
-
}
|
|
257
|
-
static async getObjectStorageServiceInstance(bucketName = _ObjectStorageService.bucketName) {
|
|
258
|
-
if (!bucketName)
|
|
259
|
-
throw new Error("Bucket name not provided or not valid value");
|
|
260
|
-
return ObjectStorageFactory.instance(bucketName);
|
|
261
|
-
}
|
|
262
|
-
static async list(bucketName) {
|
|
263
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
264
|
-
bucketName
|
|
265
|
-
).then((instance) => instance.list());
|
|
266
|
-
}
|
|
267
|
-
static async getObject(key, bucketName) {
|
|
268
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
269
|
-
bucketName
|
|
270
|
-
).then((instance) => instance.getObject(key));
|
|
271
|
-
}
|
|
272
|
-
static async getSignedUrl(key, expiresInMinutes, bucketName) {
|
|
273
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
274
|
-
bucketName
|
|
275
|
-
).then((instance) => instance.getSignedUrl(key, expiresInMinutes));
|
|
276
|
-
}
|
|
277
|
-
static async upload(key, body, metadata, bucketName) {
|
|
278
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
279
|
-
bucketName
|
|
280
|
-
).then((instance) => instance.upload(key, body, metadata));
|
|
281
|
-
}
|
|
282
|
-
static async delete(key, bucketName) {
|
|
283
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
284
|
-
bucketName
|
|
285
|
-
).then((instance) => instance.delete(key));
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
exports.ObjectStorageService = ObjectStorageService;
|
|
9
|
+
exports.ObjectStorageService = g;
|
|
290
10
|
//# sourceMappingURL=out.js.map
|
|
291
11
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/storage/blob/blobStorage.service.ts","../../src/services/storage/s3/s3Storage.service.ts","../../src/services/objectStorageFactory.service.ts","../../src/services/objectStorage.service.ts"],"names":["ObjectStorageService"],"mappings":"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","sourcesContent":["import { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n ListResponse,\n UploadResponse,\n GetObjectResponse,\n} from '../../../types';\nimport { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';\n\nimport { Readable } from 'stream';\nexport class BlobStorageService implements IObjectStorage {\n private blobServiceClient: BlobServiceClient;\n private containerName: string;\n constructor(containerName: string) {\n this.containerName = containerName;\n this.blobServiceClient = BlobServiceClient.fromConnectionString(\n process.env.AZURE_STORAGE_CONNECTION_STRING!,\n );\n }\n async list(): Promise<ListResponse> {\n const list: string[] = [];\n const containerClient = this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n for await (const containerItem of containerClient.listBlobsFlat()) {\n list.push(containerItem.name);\n }\n return new Promise((resolve) => resolve({ keys: list }));\n }\n\n getObject(blobName: string): Promise<GetObjectResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .download(0)\n .then((downloadBlockBlobResponse) => {\n return resolve({\n body: downloadBlockBlobResponse.readableStreamBody as Readable,\n metadata: {},\n contentType: '',\n contentLength: 0,\n });\n });\n } catch (error) {\n return reject(error);\n }\n });\n }\n async getSignedUrl(\n blobName: string,\n expiresInMinutes: number,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n\n const startDate = new Date();\n const expiryDate = new Date(startDate);\n expiryDate.setMinutes(\n startDate.getMinutes() + expiresInMinutes,\n );\n\n blockBlobClient\n .generateSasUrl({\n permissions: BlobSASPermissions.parse('r'),\n startsOn: startDate,\n expiresOn: expiryDate,\n })\n .then((sasUrl) => resolve(sasUrl));\n } catch (error) {\n return reject(error);\n }\n });\n }\n async upload(\n blobName: string,\n body: FileContent,\n metadata?: { [key: string]: string } | undefined,\n ): Promise<UploadResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .uploadStream(body as Readable)\n .then(() => resolve({ key: blobName }));\n } catch (error) {\n return reject(error);\n }\n });\n }\n delete(blobName: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient.delete().then(() => resolve(true));\n } catch (error) {\n return reject(error);\n }\n });\n }\n}\n","import {\n DeleteObjectCommand,\n GetObjectCommand,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3';\nimport { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n GetObjectResponse,\n ListResponse,\n UploadResponse,\n} from '../../../types';\nimport { Readable } from 'stream';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nexport class S3StorageService implements IObjectStorage {\n private s3Client: S3Client;\n private bucketName: string;\n\n constructor(bucketName: string) {\n this.bucketName = bucketName;\n this.s3Client = new S3Client({});\n }\n\n /**\n * Lists all objects in the S3 bucket.\n * @returns A promise that resolves to a list of object keys.\n */\n\n async list(): Promise<ListResponse> {\n const allKeys: string[] = [];\n\n let continuationToken: string | undefined = undefined;\n do {\n const command: ListObjectsV2Command = new ListObjectsV2Command({\n Bucket: this.bucketName,\n ContinuationToken: continuationToken,\n });\n\n const response: ListObjectsV2CommandOutput =\n await this.s3Client.send(command);\n if (response.Contents) {\n for (const item of response.Contents) {\n if (item.Key) allKeys.push(item.Key);\n }\n }\n\n continuationToken = response.NextContinuationToken;\n } while (continuationToken);\n\n return { keys: allKeys };\n }\n\n /**\n * Retrieves an object from the S3 bucket.\n * @param key - The key of the object to retrieve.\n * @returns A promise that resolves to the content of the file.\n */\n async getObject(key: string): Promise<GetObjectResponse> {\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n const response = await this.s3Client.send(command);\n return {\n body: response.Body as Readable,\n metadata: response.Metadata ?? {},\n contentType: response.ContentType ?? '',\n contentLength: response.ContentLength as number,\n };\n }\n\n /**\n * Generates a signed URL for accessing an object in the S3 bucket.\n * @param key - The key of the object.\n * @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n * @returns A promise that resolves to the signed URL.\n */\n getSignedUrl(key: string, expiresInMinutes: number = 60): Promise<string> {\n const expiresIn = expiresInMinutes * 60;\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n return getSignedUrl(this.s3Client, command, { expiresIn });\n }\n\n /**\n * Uploads an object to the S3 bucket.\n * @param key - The key of the object to upload.\n * @param body - The content of the object to upload.\n * @param metadata - Optional metadata to associate with the object.\n * @returns A promise that resolves to the response containing the key of the uploaded object.\n */\n async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n ): Promise<UploadResponse> {\n const command = new PutObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n Body: body,\n Metadata: metadata,\n });\n await this.s3Client.send(command);\n return { key };\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param key - The key of the object to delete.\n * @returns A promise that resolves to true if the object was deleted successfully.\n */\n async delete(key: string): Promise<boolean> {\n const command = new DeleteObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n await this.s3Client.send(command);\n return true;\n }\n}\n","import { IObjectStorage } from '../interfaces';\nexport class ObjectStorageFactory {\n static async instance(bucketName: string): Promise<IObjectStorage> {\n const isBlobStorageService =\n process.env.OBJECT_STORAGE_SERVICE?.toLowerCase() ===\n 'azure_blob_storage';\n\n let ObjectStorageService: new (bucketName: string) => IObjectStorage;\n\n if (isBlobStorageService) {\n const module = await import('./storage/blob/blobStorage.service');\n ObjectStorageService = module.BlobStorageService;\n } else {\n const module = await import('./storage/s3/s3Storage.service');\n ObjectStorageService = module.S3StorageService;\n }\n\n return new ObjectStorageService(bucketName);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { IObjectStorage } from '../interfaces';\nimport {\n ListResponse,\n FileContent,\n UploadResponse,\n GetObjectResponse,\n} from '../types';\nimport { ObjectStorageFactory } from '../services/objectStorageFactory.service';\n\nexport default class ObjectStorageService {\n static bucketName: string;\n\n constructor(bucketName: string) {\n ObjectStorageService.bucketName = bucketName;\n }\n\n static async getObjectStorageServiceInstance(\n bucketName: string = ObjectStorageService.bucketName,\n ): Promise<IObjectStorage> {\n if (!bucketName)\n throw new Error('Bucket name not provided or not valid value');\n return ObjectStorageFactory.instance(bucketName);\n }\n\n static async list(bucketName?: string): Promise<ListResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.list());\n }\n\n static async getObject(\n key: string,\n bucketName?: string,\n ): Promise<GetObjectResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getObject(key));\n }\n\n static async getSignedUrl(\n key: string,\n expiresInMinutes: number,\n bucketName?: string,\n ): Promise<string> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getSignedUrl(key, expiresInMinutes));\n }\n\n static async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n bucketName?: string,\n ): Promise<UploadResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.upload(key, body, metadata));\n }\n\n static async delete(key: string, bucketName?: string): Promise<boolean> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.delete(key));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/services/storage/blob/blobStorage.service.ts","../../src/services/storage/s3/s3Storage.service.ts","../../src/services/objectStorageFactory.service.ts","../../src/services/objectStorage.service.ts"],"names":["BlobServiceClient","BlobSASPermissions","BlobStorageService","containerName","list","containerClient","iter","__forAwait","more","temp","error","containerItem","resolve","blobName","reject","downloadBlockBlobResponse","expiresInMinutes","blockBlobClient","startDate","expiryDate","sasUrl","body","metadata","DeleteObjectCommand","GetObjectCommand","ListObjectsV2Command","PutObjectCommand","S3Client","getSignedUrl","S3StorageService","bucketName","allKeys","continuationToken","command","response","item","key","_a","_b","expiresIn","ObjectStorageFactory","ObjectStorageService","_ObjectStorageService","instance"],"mappings":"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","sourcesContent":["import { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n ListResponse,\n UploadResponse,\n GetObjectResponse,\n} from '../../../types';\nimport { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';\n\nimport { Readable } from 'stream';\nexport class BlobStorageService implements IObjectStorage {\n private blobServiceClient: BlobServiceClient;\n private containerName: string;\n constructor(containerName: string) {\n this.containerName = containerName;\n this.blobServiceClient = BlobServiceClient.fromConnectionString(\n process.env.AZURE_STORAGE_CONNECTION_STRING!,\n );\n }\n async list(): Promise<ListResponse> {\n const list: string[] = [];\n const containerClient = this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n for await (const containerItem of containerClient.listBlobsFlat()) {\n list.push(containerItem.name);\n }\n return new Promise((resolve) => resolve({ keys: list }));\n }\n\n getObject(blobName: string): Promise<GetObjectResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .download(0)\n .then((downloadBlockBlobResponse) => {\n return resolve({\n body: downloadBlockBlobResponse.readableStreamBody as Readable,\n metadata: {},\n contentType: '',\n contentLength: 0,\n });\n });\n } catch (error) {\n return reject(error);\n }\n });\n }\n async getSignedUrl(\n blobName: string,\n expiresInMinutes: number,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n\n const startDate = new Date();\n const expiryDate = new Date(startDate);\n expiryDate.setMinutes(\n startDate.getMinutes() + expiresInMinutes,\n );\n\n blockBlobClient\n .generateSasUrl({\n permissions: BlobSASPermissions.parse('r'),\n startsOn: startDate,\n expiresOn: expiryDate,\n })\n .then((sasUrl) => resolve(sasUrl));\n } catch (error) {\n return reject(error);\n }\n });\n }\n async upload(\n blobName: string,\n body: FileContent,\n metadata?: { [key: string]: string } | undefined,\n ): Promise<UploadResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .uploadStream(body as Readable)\n .then(() => resolve({ key: blobName }));\n } catch (error) {\n return reject(error);\n }\n });\n }\n delete(blobName: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient.delete().then(() => resolve(true));\n } catch (error) {\n return reject(error);\n }\n });\n }\n}\n","import {\n DeleteObjectCommand,\n GetObjectCommand,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3';\nimport { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n GetObjectResponse,\n ListResponse,\n UploadResponse,\n} from '../../../types';\nimport { Readable } from 'stream';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nexport class S3StorageService implements IObjectStorage {\n private s3Client: S3Client;\n private bucketName: string;\n\n constructor(bucketName: string) {\n this.bucketName = bucketName;\n this.s3Client = new S3Client({});\n }\n\n /**\n * Lists all objects in the S3 bucket.\n * @returns A promise that resolves to a list of object keys.\n */\n\n async list(): Promise<ListResponse> {\n const allKeys: string[] = [];\n\n let continuationToken: string | undefined = undefined;\n do {\n const command: ListObjectsV2Command = new ListObjectsV2Command({\n Bucket: this.bucketName,\n ContinuationToken: continuationToken,\n });\n\n const response: ListObjectsV2CommandOutput =\n await this.s3Client.send(command);\n if (response.Contents) {\n for (const item of response.Contents) {\n if (item.Key) allKeys.push(item.Key);\n }\n }\n\n continuationToken = response.NextContinuationToken;\n } while (continuationToken);\n\n return { keys: allKeys };\n }\n\n /**\n * Retrieves an object from the S3 bucket.\n * @param key - The key of the object to retrieve.\n * @returns A promise that resolves to the content of the file.\n */\n async getObject(key: string): Promise<GetObjectResponse> {\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n const response = await this.s3Client.send(command);\n return {\n body: response.Body as Readable,\n metadata: response.Metadata ?? {},\n contentType: response.ContentType ?? '',\n contentLength: response.ContentLength as number,\n };\n }\n\n /**\n * Generates a signed URL for accessing an object in the S3 bucket.\n * @param key - The key of the object.\n * @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n * @returns A promise that resolves to the signed URL.\n */\n getSignedUrl(key: string, expiresInMinutes: number = 60): Promise<string> {\n const expiresIn = expiresInMinutes * 60;\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n return getSignedUrl(this.s3Client, command, { expiresIn });\n }\n\n /**\n * Uploads an object to the S3 bucket.\n * @param key - The key of the object to upload.\n * @param body - The content of the object to upload.\n * @param metadata - Optional metadata to associate with the object.\n * @returns A promise that resolves to the response containing the key of the uploaded object.\n */\n async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n ): Promise<UploadResponse> {\n const command = new PutObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n Body: body,\n Metadata: metadata,\n });\n await this.s3Client.send(command);\n return { key };\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param key - The key of the object to delete.\n * @returns A promise that resolves to true if the object was deleted successfully.\n */\n async delete(key: string): Promise<boolean> {\n const command = new DeleteObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n await this.s3Client.send(command);\n return true;\n }\n}\n","import { IObjectStorage } from '../interfaces';\nimport { S3StorageService, BlobStorageService } from './storage';\n\nexport class ObjectStorageFactory {\n static async instance(bucketName: string): Promise<IObjectStorage> {\n const isBlobStorageService =\n process.env.OBJECT_STORAGE_SERVICE?.toLowerCase() ===\n 'azure_blob_storage';\n\n if (isBlobStorageService) {\n return new BlobStorageService(bucketName);\n } else {\n return new S3StorageService(bucketName);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { IObjectStorage } from '../interfaces';\nimport {\n ListResponse,\n FileContent,\n UploadResponse,\n GetObjectResponse,\n} from '../types';\nimport { ObjectStorageFactory } from '../services/objectStorageFactory.service';\n\nexport default class ObjectStorageService {\n static bucketName: string;\n\n constructor(bucketName: string) {\n ObjectStorageService.bucketName = bucketName;\n }\n\n static async getObjectStorageServiceInstance(\n bucketName: string = ObjectStorageService.bucketName,\n ): Promise<IObjectStorage> {\n if (!bucketName)\n throw new Error('Bucket name not provided or not valid value');\n return ObjectStorageFactory.instance(bucketName);\n }\n\n static async list(bucketName?: string): Promise<ListResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.list());\n }\n\n static async getObject(\n key: string,\n bucketName?: string,\n ): Promise<GetObjectResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getObject(key));\n }\n\n static async getSignedUrl(\n key: string,\n expiresInMinutes: number,\n bucketName?: string,\n ): Promise<string> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getSignedUrl(key, expiresInMinutes));\n }\n\n static async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n bucketName?: string,\n ): Promise<UploadResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.upload(key, body, metadata));\n }\n\n static async delete(key: string, bucketName?: string): Promise<boolean> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.delete(key));\n }\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Readable } from 'stream';
|
|
2
|
+
|
|
3
|
+
type UploadResponse = {
|
|
4
|
+
key: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
type FileContent = Readable | ReadableStream | Blob;
|
|
8
|
+
|
|
9
|
+
type ListResponse = {
|
|
10
|
+
keys: string[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type GetObjectResponse = {
|
|
14
|
+
body: any;
|
|
15
|
+
contentType: string;
|
|
16
|
+
contentLength: number;
|
|
17
|
+
metadata: {
|
|
18
|
+
[key: string]: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
interface IObjectStorage {
|
|
23
|
+
list(): Promise<ListResponse>;
|
|
24
|
+
getObject(key: string): Promise<GetObjectResponse>;
|
|
25
|
+
getSignedUrl(key: string, expiresInMinutes: number): Promise<string>;
|
|
26
|
+
upload(key: string, body: FileContent, metadata?: {
|
|
27
|
+
[key: string]: string;
|
|
28
|
+
}): Promise<UploadResponse>;
|
|
29
|
+
delete(key: string): Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class ObjectStorageService {
|
|
33
|
+
static bucketName: string;
|
|
34
|
+
constructor(bucketName: string);
|
|
35
|
+
static getObjectStorageServiceInstance(bucketName?: string): Promise<IObjectStorage>;
|
|
36
|
+
static list(bucketName?: string): Promise<ListResponse>;
|
|
37
|
+
static getObject(key: string, bucketName?: string): Promise<GetObjectResponse>;
|
|
38
|
+
static getSignedUrl(key: string, expiresInMinutes: number, bucketName?: string): Promise<string>;
|
|
39
|
+
static upload(key: string, body: FileContent, metadata?: {
|
|
40
|
+
[key: string]: string;
|
|
41
|
+
}, bucketName?: string): Promise<UploadResponse>;
|
|
42
|
+
static delete(key: string, bucketName?: string): Promise<boolean>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { FileContent, GetObjectResponse, ListResponse, ObjectStorageService, UploadResponse };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
import '
|
|
1
|
+
import { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';
|
|
2
|
+
import { S3Client, ListObjectsV2Command, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
|
3
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
var ObjectStorageFactory = class {
|
|
5
|
-
static async instance(bucketName) {
|
|
6
|
-
var _a;
|
|
7
|
-
const isBlobStorageService = ((_a = process.env.OBJECT_STORAGE_SERVICE) == null ? void 0 : _a.toLowerCase()) === "azure_blob_storage";
|
|
8
|
-
let ObjectStorageService2;
|
|
9
|
-
if (isBlobStorageService) {
|
|
10
|
-
const module = await import('./blobStorage.service-Q2W6LO3S.mjs');
|
|
11
|
-
ObjectStorageService2 = module.BlobStorageService;
|
|
12
|
-
} else {
|
|
13
|
-
const module = await import('./s3Storage.service-OZGBAWBM.mjs');
|
|
14
|
-
ObjectStorageService2 = module.S3StorageService;
|
|
15
|
-
}
|
|
16
|
-
return new ObjectStorageService2(bucketName);
|
|
17
|
-
}
|
|
18
|
-
};
|
|
5
|
+
var C=(r,e)=>{if(e=Symbol[r])return e;throw Error("Symbol."+r+" is not defined")};var u=(r,e,t)=>(e=r[C("asyncIterator")])?e.call(r):(r=r[C("iterator")](),e={},t=(n,o)=>(o=r[n])&&(e[n]=s=>new Promise((a,i,c)=>(s=o.call(r,s),c=s.done,Promise.resolve(s.value).then(p=>a({value:p,done:c}),i)))),t("next"),t("return"),e);var l=class{constructor(e){this.containerName=e,this.blobServiceClient=BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING);}async list(){let e=[],t=this.blobServiceClient.getContainerClient(this.containerName);try{for(var n=u(t.listBlobsFlat()),o,s,a;o=!(s=await n.next()).done;o=!1){let i=s.value;e.push(i.name);}}catch(s){a=[s];}finally{try{o&&(s=n.return)&&await s.call(n);}finally{if(a)throw a[0]}}return new Promise(i=>i({keys:e}))}getObject(e){return new Promise((t,n)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).download(0).then(a=>t({body:a.readableStreamBody,metadata:{},contentType:"",contentLength:0}));}catch(o){return n(o)}})}async getSignedUrl(e,t){return new Promise((n,o)=>{try{let a=this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e),i=new Date,c=new Date(i);c.setMinutes(i.getMinutes()+t),a.generateSasUrl({permissions:BlobSASPermissions.parse("r"),startsOn:i,expiresOn:c}).then(p=>n(p));}catch(s){return o(s)}})}async upload(e,t,n){return new Promise((o,s)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).uploadStream(t).then(()=>o({key:e}));}catch(a){return s(a)}})}delete(e){return new Promise((t,n)=>{try{this.blobServiceClient.getContainerClient(this.containerName).getBlockBlobClient(e).delete().then(()=>t(!0));}catch(o){return n(o)}})}};var m=class{constructor(e){this.bucketName=e,this.s3Client=new S3Client({});}async list(){let e=[],t;do{let n=new ListObjectsV2Command({Bucket:this.bucketName,ContinuationToken:t}),o=await this.s3Client.send(n);if(o.Contents)for(let s of o.Contents)s.Key&&e.push(s.Key);t=o.NextContinuationToken;}while(t);return {keys:e}}async getObject(e){var o,s;let t=new GetObjectCommand({Bucket:this.bucketName,Key:e}),n=await this.s3Client.send(t);return {body:n.Body,metadata:(o=n.Metadata)!=null?o:{},contentType:(s=n.ContentType)!=null?s:"",contentLength:n.ContentLength}}getSignedUrl(e,t=60){let n=t*60,o=new GetObjectCommand({Bucket:this.bucketName,Key:e});return getSignedUrl(this.s3Client,o,{expiresIn:n})}async upload(e,t,n){let o=new PutObjectCommand({Bucket:this.bucketName,Key:e,Body:t,Metadata:n});return await this.s3Client.send(o),{key:e}}async delete(e){let t=new DeleteObjectCommand({Bucket:this.bucketName,Key:e});return await this.s3Client.send(t),!0}};var b=class{static async instance(e){var n;return ((n=process.env.OBJECT_STORAGE_SERVICE)==null?void 0:n.toLowerCase())==="azure_blob_storage"?new l(e):new m(e)}};var g=class r{constructor(e){r.bucketName=e;}static async getObjectStorageServiceInstance(e=r.bucketName){if(!e)throw new Error("Bucket name not provided or not valid value");return b.instance(e)}static async list(e){return r.getObjectStorageServiceInstance(e).then(t=>t.list())}static async getObject(e,t){return r.getObjectStorageServiceInstance(t).then(n=>n.getObject(e))}static async getSignedUrl(e,t,n){return r.getObjectStorageServiceInstance(n).then(o=>o.getSignedUrl(e,t))}static async upload(e,t,n,o){return r.getObjectStorageServiceInstance(o).then(s=>s.upload(e,t,n))}static async delete(e,t){return r.getObjectStorageServiceInstance(t).then(n=>n.delete(e))}};
|
|
19
6
|
|
|
20
|
-
|
|
21
|
-
var ObjectStorageService = class _ObjectStorageService {
|
|
22
|
-
constructor(bucketName) {
|
|
23
|
-
_ObjectStorageService.bucketName = bucketName;
|
|
24
|
-
}
|
|
25
|
-
static async getObjectStorageServiceInstance(bucketName = _ObjectStorageService.bucketName) {
|
|
26
|
-
if (!bucketName)
|
|
27
|
-
throw new Error("Bucket name not provided or not valid value");
|
|
28
|
-
return ObjectStorageFactory.instance(bucketName);
|
|
29
|
-
}
|
|
30
|
-
static async list(bucketName) {
|
|
31
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
32
|
-
bucketName
|
|
33
|
-
).then((instance) => instance.list());
|
|
34
|
-
}
|
|
35
|
-
static async getObject(key, bucketName) {
|
|
36
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
37
|
-
bucketName
|
|
38
|
-
).then((instance) => instance.getObject(key));
|
|
39
|
-
}
|
|
40
|
-
static async getSignedUrl(key, expiresInMinutes, bucketName) {
|
|
41
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
42
|
-
bucketName
|
|
43
|
-
).then((instance) => instance.getSignedUrl(key, expiresInMinutes));
|
|
44
|
-
}
|
|
45
|
-
static async upload(key, body, metadata, bucketName) {
|
|
46
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
47
|
-
bucketName
|
|
48
|
-
).then((instance) => instance.upload(key, body, metadata));
|
|
49
|
-
}
|
|
50
|
-
static async delete(key, bucketName) {
|
|
51
|
-
return _ObjectStorageService.getObjectStorageServiceInstance(
|
|
52
|
-
bucketName
|
|
53
|
-
).then((instance) => instance.delete(key));
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export { ObjectStorageService };
|
|
7
|
+
export { g as ObjectStorageService };
|
|
58
8
|
//# sourceMappingURL=out.js.map
|
|
59
9
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/objectStorageFactory.service.ts","../../src/services/objectStorage.service.ts"],"names":["ObjectStorageService"],"mappings":";;;AACO,IAAM,uBAAN,MAA2B;AAAA,EAC9B,aAAa,SAAS,YAA6C;AAFvE;AAGQ,UAAM,yBACF,aAAQ,IAAI,2BAAZ,mBAAoC,mBACpC;AAEJ,QAAIA;AAEJ,QAAI,sBAAsB;AACtB,YAAM,SAAS,MAAM,OAAO,oCAAoC;AAChE,MAAAA,wBAAuB,OAAO;AAAA,IAClC,OAAO;AACH,YAAM,SAAS,MAAM,OAAO,kCAAgC;AAC5D,MAAAA,wBAAuB,OAAO;AAAA,IAClC;AAEA,WAAO,IAAIA,sBAAqB,UAAU;AAAA,EAC9C;AACJ;;;ACRA,IAAqB,uBAArB,MAAqB,sBAAqB;AAAA,EAGtC,YAAY,YAAoB;AAC5B,0BAAqB,aAAa;AAAA,EACtC;AAAA,EAEA,aAAa,gCACT,aAAqB,sBAAqB,YACnB;AACvB,QAAI,CAAC;AACD,YAAM,IAAI,MAAM,6CAA6C;AACjE,WAAO,qBAAqB,SAAS,UAAU;AAAA,EACnD;AAAA,EAEA,aAAa,KAAK,YAA4C;AAC1D,WAAO,sBAAqB;AAAA,MACxB;AAAA,IACJ,EAAE,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,EACxC;AAAA,EAEA,aAAa,UACT,KACA,YAC0B;AAC1B,WAAO,sBAAqB;AAAA,MACxB;AAAA,IACJ,EAAE,KAAK,CAAC,aAAa,SAAS,UAAU,GAAG,CAAC;AAAA,EAChD;AAAA,EAEA,aAAa,aACT,KACA,kBACA,YACe;AACf,WAAO,sBAAqB;AAAA,MACxB;AAAA,IACJ,EAAE,KAAK,CAAC,aAAa,SAAS,aAAa,KAAK,gBAAgB,CAAC;AAAA,EACrE;AAAA,EAEA,aAAa,OACT,KACA,MACA,UACA,YACuB;AACvB,WAAO,sBAAqB;AAAA,MACxB;AAAA,IACJ,EAAE,KAAK,CAAC,aAAa,SAAS,OAAO,KAAK,MAAM,QAAQ,CAAC;AAAA,EAC7D;AAAA,EAEA,aAAa,OAAO,KAAa,YAAuC;AACpE,WAAO,sBAAqB;AAAA,MACxB;AAAA,IACJ,EAAE,KAAK,CAAC,aAAa,SAAS,OAAO,GAAG,CAAC;AAAA,EAC7C;AACJ","sourcesContent":["import { IObjectStorage } from '../interfaces';\nexport class ObjectStorageFactory {\n static async instance(bucketName: string): Promise<IObjectStorage> {\n const isBlobStorageService =\n process.env.OBJECT_STORAGE_SERVICE?.toLowerCase() ===\n 'azure_blob_storage';\n\n let ObjectStorageService: new (bucketName: string) => IObjectStorage;\n\n if (isBlobStorageService) {\n const module = await import('./storage/blob/blobStorage.service');\n ObjectStorageService = module.BlobStorageService;\n } else {\n const module = await import('./storage/s3/s3Storage.service');\n ObjectStorageService = module.S3StorageService;\n }\n\n return new ObjectStorageService(bucketName);\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { IObjectStorage } from '../interfaces';\nimport {\n ListResponse,\n FileContent,\n UploadResponse,\n GetObjectResponse,\n} from '../types';\nimport { ObjectStorageFactory } from '../services/objectStorageFactory.service';\n\nexport default class ObjectStorageService {\n static bucketName: string;\n\n constructor(bucketName: string) {\n ObjectStorageService.bucketName = bucketName;\n }\n\n static async getObjectStorageServiceInstance(\n bucketName: string = ObjectStorageService.bucketName,\n ): Promise<IObjectStorage> {\n if (!bucketName)\n throw new Error('Bucket name not provided or not valid value');\n return ObjectStorageFactory.instance(bucketName);\n }\n\n static async list(bucketName?: string): Promise<ListResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.list());\n }\n\n static async getObject(\n key: string,\n bucketName?: string,\n ): Promise<GetObjectResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getObject(key));\n }\n\n static async getSignedUrl(\n key: string,\n expiresInMinutes: number,\n bucketName?: string,\n ): Promise<string> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getSignedUrl(key, expiresInMinutes));\n }\n\n static async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n bucketName?: string,\n ): Promise<UploadResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.upload(key, body, metadata));\n }\n\n static async delete(key: string, bucketName?: string): Promise<boolean> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.delete(key));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/services/storage/blob/blobStorage.service.ts","../../src/services/storage/s3/s3Storage.service.ts","../../src/services/objectStorageFactory.service.ts","../../src/services/objectStorage.service.ts"],"names":["BlobServiceClient","BlobSASPermissions","BlobStorageService","containerName","list","containerClient","iter","__forAwait","more","temp","error","containerItem","resolve","blobName","reject","downloadBlockBlobResponse","expiresInMinutes","blockBlobClient","startDate","expiryDate","sasUrl","body","metadata","DeleteObjectCommand","GetObjectCommand","ListObjectsV2Command","PutObjectCommand","S3Client","getSignedUrl","S3StorageService","bucketName","allKeys","continuationToken","command","response","item","key","_a","_b","expiresIn","ObjectStorageFactory","ObjectStorageService","_ObjectStorageService","instance"],"mappings":"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","sourcesContent":["import { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n ListResponse,\n UploadResponse,\n GetObjectResponse,\n} from '../../../types';\nimport { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';\n\nimport { Readable } from 'stream';\nexport class BlobStorageService implements IObjectStorage {\n private blobServiceClient: BlobServiceClient;\n private containerName: string;\n constructor(containerName: string) {\n this.containerName = containerName;\n this.blobServiceClient = BlobServiceClient.fromConnectionString(\n process.env.AZURE_STORAGE_CONNECTION_STRING!,\n );\n }\n async list(): Promise<ListResponse> {\n const list: string[] = [];\n const containerClient = this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n for await (const containerItem of containerClient.listBlobsFlat()) {\n list.push(containerItem.name);\n }\n return new Promise((resolve) => resolve({ keys: list }));\n }\n\n getObject(blobName: string): Promise<GetObjectResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .download(0)\n .then((downloadBlockBlobResponse) => {\n return resolve({\n body: downloadBlockBlobResponse.readableStreamBody as Readable,\n metadata: {},\n contentType: '',\n contentLength: 0,\n });\n });\n } catch (error) {\n return reject(error);\n }\n });\n }\n async getSignedUrl(\n blobName: string,\n expiresInMinutes: number,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n\n const startDate = new Date();\n const expiryDate = new Date(startDate);\n expiryDate.setMinutes(\n startDate.getMinutes() + expiresInMinutes,\n );\n\n blockBlobClient\n .generateSasUrl({\n permissions: BlobSASPermissions.parse('r'),\n startsOn: startDate,\n expiresOn: expiryDate,\n })\n .then((sasUrl) => resolve(sasUrl));\n } catch (error) {\n return reject(error);\n }\n });\n }\n async upload(\n blobName: string,\n body: FileContent,\n metadata?: { [key: string]: string } | undefined,\n ): Promise<UploadResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .uploadStream(body as Readable)\n .then(() => resolve({ key: blobName }));\n } catch (error) {\n return reject(error);\n }\n });\n }\n delete(blobName: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient.delete().then(() => resolve(true));\n } catch (error) {\n return reject(error);\n }\n });\n }\n}\n","import {\n DeleteObjectCommand,\n GetObjectCommand,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3';\nimport { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n GetObjectResponse,\n ListResponse,\n UploadResponse,\n} from '../../../types';\nimport { Readable } from 'stream';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nexport class S3StorageService implements IObjectStorage {\n private s3Client: S3Client;\n private bucketName: string;\n\n constructor(bucketName: string) {\n this.bucketName = bucketName;\n this.s3Client = new S3Client({});\n }\n\n /**\n * Lists all objects in the S3 bucket.\n * @returns A promise that resolves to a list of object keys.\n */\n\n async list(): Promise<ListResponse> {\n const allKeys: string[] = [];\n\n let continuationToken: string | undefined = undefined;\n do {\n const command: ListObjectsV2Command = new ListObjectsV2Command({\n Bucket: this.bucketName,\n ContinuationToken: continuationToken,\n });\n\n const response: ListObjectsV2CommandOutput =\n await this.s3Client.send(command);\n if (response.Contents) {\n for (const item of response.Contents) {\n if (item.Key) allKeys.push(item.Key);\n }\n }\n\n continuationToken = response.NextContinuationToken;\n } while (continuationToken);\n\n return { keys: allKeys };\n }\n\n /**\n * Retrieves an object from the S3 bucket.\n * @param key - The key of the object to retrieve.\n * @returns A promise that resolves to the content of the file.\n */\n async getObject(key: string): Promise<GetObjectResponse> {\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n const response = await this.s3Client.send(command);\n return {\n body: response.Body as Readable,\n metadata: response.Metadata ?? {},\n contentType: response.ContentType ?? '',\n contentLength: response.ContentLength as number,\n };\n }\n\n /**\n * Generates a signed URL for accessing an object in the S3 bucket.\n * @param key - The key of the object.\n * @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n * @returns A promise that resolves to the signed URL.\n */\n getSignedUrl(key: string, expiresInMinutes: number = 60): Promise<string> {\n const expiresIn = expiresInMinutes * 60;\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n return getSignedUrl(this.s3Client, command, { expiresIn });\n }\n\n /**\n * Uploads an object to the S3 bucket.\n * @param key - The key of the object to upload.\n * @param body - The content of the object to upload.\n * @param metadata - Optional metadata to associate with the object.\n * @returns A promise that resolves to the response containing the key of the uploaded object.\n */\n async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n ): Promise<UploadResponse> {\n const command = new PutObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n Body: body,\n Metadata: metadata,\n });\n await this.s3Client.send(command);\n return { key };\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param key - The key of the object to delete.\n * @returns A promise that resolves to true if the object was deleted successfully.\n */\n async delete(key: string): Promise<boolean> {\n const command = new DeleteObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n await this.s3Client.send(command);\n return true;\n }\n}\n","import { IObjectStorage } from '../interfaces';\nimport { S3StorageService, BlobStorageService } from './storage';\n\nexport class ObjectStorageFactory {\n static async instance(bucketName: string): Promise<IObjectStorage> {\n const isBlobStorageService =\n process.env.OBJECT_STORAGE_SERVICE?.toLowerCase() ===\n 'azure_blob_storage';\n\n if (isBlobStorageService) {\n return new BlobStorageService(bucketName);\n } else {\n return new S3StorageService(bucketName);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { IObjectStorage } from '../interfaces';\nimport {\n ListResponse,\n FileContent,\n UploadResponse,\n GetObjectResponse,\n} from '../types';\nimport { ObjectStorageFactory } from '../services/objectStorageFactory.service';\n\nexport default class ObjectStorageService {\n static bucketName: string;\n\n constructor(bucketName: string) {\n ObjectStorageService.bucketName = bucketName;\n }\n\n static async getObjectStorageServiceInstance(\n bucketName: string = ObjectStorageService.bucketName,\n ): Promise<IObjectStorage> {\n if (!bucketName)\n throw new Error('Bucket name not provided or not valid value');\n return ObjectStorageFactory.instance(bucketName);\n }\n\n static async list(bucketName?: string): Promise<ListResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.list());\n }\n\n static async getObject(\n key: string,\n bucketName?: string,\n ): Promise<GetObjectResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getObject(key));\n }\n\n static async getSignedUrl(\n key: string,\n expiresInMinutes: number,\n bucketName?: string,\n ): Promise<string> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.getSignedUrl(key, expiresInMinutes));\n }\n\n static async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n bucketName?: string,\n ): Promise<UploadResponse> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.upload(key, body, metadata));\n }\n\n static async delete(key: string, bucketName?: string): Promise<boolean> {\n return ObjectStorageService.getObjectStorageServiceInstance(\n bucketName,\n ).then((instance) => instance.delete(key));\n }\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@qrvey/object-storage",
|
|
3
3
|
"types": "dist/types/index.d.ts",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.2",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
@@ -24,22 +24,11 @@
|
|
|
24
24
|
"prepare-publish": "yarn install && yarn test:cov && yarn build",
|
|
25
25
|
"publish-package": "yarn prepare-publish && npm publish"
|
|
26
26
|
},
|
|
27
|
-
"
|
|
28
|
-
"@aws-sdk/client-s3": "3.
|
|
29
|
-
"@aws-sdk/s3-request-presigner": "3.
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@aws-sdk/client-s3": "3.596.0",
|
|
29
|
+
"@aws-sdk/s3-request-presigner": "3.596.0",
|
|
30
30
|
"@azure/storage-blob": "12.23.0"
|
|
31
31
|
},
|
|
32
|
-
"peerDependenciesMeta": {
|
|
33
|
-
"@aws-sdk/client-s3": {
|
|
34
|
-
"optional": true
|
|
35
|
-
},
|
|
36
|
-
"@aws-sdk/s3-request-presigner": {
|
|
37
|
-
"optional": true
|
|
38
|
-
},
|
|
39
|
-
"@azure/storage-blob": {
|
|
40
|
-
"optional": true
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
32
|
"devDependencies": {
|
|
44
33
|
"@types/jest": "29.5.5",
|
|
45
34
|
"auto-version-js": "0.3.10",
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { __forAwait } from './chunk-JHXQKOVY.mjs';
|
|
2
|
-
import { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';
|
|
3
|
-
|
|
4
|
-
var BlobStorageService = class {
|
|
5
|
-
constructor(containerName) {
|
|
6
|
-
this.containerName = containerName;
|
|
7
|
-
this.blobServiceClient = BlobServiceClient.fromConnectionString(
|
|
8
|
-
process.env.AZURE_STORAGE_CONNECTION_STRING
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
async list() {
|
|
12
|
-
const list = [];
|
|
13
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
14
|
-
this.containerName
|
|
15
|
-
);
|
|
16
|
-
try {
|
|
17
|
-
for (var iter = __forAwait(containerClient.listBlobsFlat()), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
|
|
18
|
-
const containerItem = temp.value;
|
|
19
|
-
list.push(containerItem.name);
|
|
20
|
-
}
|
|
21
|
-
} catch (temp) {
|
|
22
|
-
error = [temp];
|
|
23
|
-
} finally {
|
|
24
|
-
try {
|
|
25
|
-
more && (temp = iter.return) && await temp.call(iter);
|
|
26
|
-
} finally {
|
|
27
|
-
if (error)
|
|
28
|
-
throw error[0];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return new Promise((resolve) => resolve({ keys: list }));
|
|
32
|
-
}
|
|
33
|
-
getObject(blobName) {
|
|
34
|
-
return new Promise((resolve, reject) => {
|
|
35
|
-
try {
|
|
36
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
37
|
-
this.containerName
|
|
38
|
-
);
|
|
39
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
40
|
-
blockBlobClient.download(0).then((downloadBlockBlobResponse) => {
|
|
41
|
-
return resolve({
|
|
42
|
-
body: downloadBlockBlobResponse.readableStreamBody,
|
|
43
|
-
metadata: {},
|
|
44
|
-
contentType: "",
|
|
45
|
-
contentLength: 0
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
} catch (error) {
|
|
49
|
-
return reject(error);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
async getSignedUrl(blobName, expiresInMinutes) {
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
try {
|
|
56
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
57
|
-
this.containerName
|
|
58
|
-
);
|
|
59
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
60
|
-
const startDate = /* @__PURE__ */ new Date();
|
|
61
|
-
const expiryDate = new Date(startDate);
|
|
62
|
-
expiryDate.setMinutes(
|
|
63
|
-
startDate.getMinutes() + expiresInMinutes
|
|
64
|
-
);
|
|
65
|
-
blockBlobClient.generateSasUrl({
|
|
66
|
-
permissions: BlobSASPermissions.parse("r"),
|
|
67
|
-
startsOn: startDate,
|
|
68
|
-
expiresOn: expiryDate
|
|
69
|
-
}).then((sasUrl) => resolve(sasUrl));
|
|
70
|
-
} catch (error) {
|
|
71
|
-
return reject(error);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
async upload(blobName, body, metadata) {
|
|
76
|
-
return new Promise((resolve, reject) => {
|
|
77
|
-
try {
|
|
78
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
79
|
-
this.containerName
|
|
80
|
-
);
|
|
81
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
82
|
-
blockBlobClient.uploadStream(body).then(() => resolve({ key: blobName }));
|
|
83
|
-
} catch (error) {
|
|
84
|
-
return reject(error);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
delete(blobName) {
|
|
89
|
-
return new Promise((resolve, reject) => {
|
|
90
|
-
try {
|
|
91
|
-
const containerClient = this.blobServiceClient.getContainerClient(
|
|
92
|
-
this.containerName
|
|
93
|
-
);
|
|
94
|
-
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
|
|
95
|
-
blockBlobClient.delete().then(() => resolve(true));
|
|
96
|
-
} catch (error) {
|
|
97
|
-
return reject(error);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export { BlobStorageService };
|
|
104
|
-
//# sourceMappingURL=out.js.map
|
|
105
|
-
//# sourceMappingURL=blobStorage.service-Q2W6LO3S.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/storage/blob/blobStorage.service.ts"],"names":[],"mappings":";;;;;AAOA,SAAS,mBAAmB,0BAA0B;AAG/C,IAAM,qBAAN,MAAmD;AAAA,EAGtD,YAAY,eAAuB;AAC/B,SAAK,gBAAgB;AACrB,SAAK,oBAAoB,kBAAkB;AAAA,MACvC,QAAQ,IAAI;AAAA,IAChB;AAAA,EACJ;AAAA,EACA,MAAM,OAA8B;AAChC,UAAM,OAAiB,CAAC;AACxB,UAAM,kBAAkB,KAAK,kBAAkB;AAAA,MAC3C,KAAK;AAAA,IACT;AACA;AAAA,iCAAkC,gBAAgB,cAAc,IAAhE,0EAAmE;AAAxD,cAAM,gBAAjB;AACI,aAAK,KAAK,cAAc,IAAI;AAAA,MAChC;AAAA,aAFA,MAxBR;AAwBQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,WAAO,IAAI,QAAQ,CAAC,YAAY,QAAQ,EAAE,MAAM,KAAK,CAAC,CAAC;AAAA,EAC3D;AAAA,EAEA,UAAU,UAA8C;AACpD,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI;AACA,cAAM,kBACF,KAAK,kBAAkB;AAAA,UACnB,KAAK;AAAA,QACT;AACJ,cAAM,kBACF,gBAAgB,mBAAmB,QAAQ;AAC/C,wBACK,SAAS,CAAC,EACV,KAAK,CAAC,8BAA8B;AACjC,iBAAO,QAAQ;AAAA,YACX,MAAM,0BAA0B;AAAA,YAChC,UAAU,CAAC;AAAA,YACX,aAAa;AAAA,YACb,eAAe;AAAA,UACnB,CAAC;AAAA,QACL,CAAC;AAAA,MACT,SAAS,OAAO;AACZ,eAAO,OAAO,KAAK;AAAA,MACvB;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EACA,MAAM,aACF,UACA,kBACe;AACf,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI;AACA,cAAM,kBACF,KAAK,kBAAkB;AAAA,UACnB,KAAK;AAAA,QACT;AACJ,cAAM,kBACF,gBAAgB,mBAAmB,QAAQ;AAE/C,cAAM,YAAY,oBAAI,KAAK;AAC3B,cAAM,aAAa,IAAI,KAAK,SAAS;AACrC,mBAAW;AAAA,UACP,UAAU,WAAW,IAAI;AAAA,QAC7B;AAEA,wBACK,eAAe;AAAA,UACZ,aAAa,mBAAmB,MAAM,GAAG;AAAA,UACzC,UAAU;AAAA,UACV,WAAW;AAAA,QACf,CAAC,EACA,KAAK,CAAC,WAAW,QAAQ,MAAM,CAAC;AAAA,MACzC,SAAS,OAAO;AACZ,eAAO,OAAO,KAAK;AAAA,MACvB;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EACA,MAAM,OACF,UACA,MACA,UACuB;AACvB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI;AACA,cAAM,kBACF,KAAK,kBAAkB;AAAA,UACnB,KAAK;AAAA,QACT;AACJ,cAAM,kBACF,gBAAgB,mBAAmB,QAAQ;AAC/C,wBACK,aAAa,IAAgB,EAC7B,KAAK,MAAM,QAAQ,EAAE,KAAK,SAAS,CAAC,CAAC;AAAA,MAC9C,SAAS,OAAO;AACZ,eAAO,OAAO,KAAK;AAAA,MACvB;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EACA,OAAO,UAAoC;AACvC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,UAAI;AACA,cAAM,kBACF,KAAK,kBAAkB;AAAA,UACnB,KAAK;AAAA,QACT;AACJ,cAAM,kBACF,gBAAgB,mBAAmB,QAAQ;AAC/C,wBAAgB,OAAO,EAAE,KAAK,MAAM,QAAQ,IAAI,CAAC;AAAA,MACrD,SAAS,OAAO;AACZ,eAAO,OAAO,KAAK;AAAA,MACvB;AAAA,IACJ,CAAC;AAAA,EACL;AACJ","sourcesContent":["import { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n ListResponse,\n UploadResponse,\n GetObjectResponse,\n} from '../../../types';\nimport { BlobServiceClient, BlobSASPermissions } from '@azure/storage-blob';\n\nimport { Readable } from 'stream';\nexport class BlobStorageService implements IObjectStorage {\n private blobServiceClient: BlobServiceClient;\n private containerName: string;\n constructor(containerName: string) {\n this.containerName = containerName;\n this.blobServiceClient = BlobServiceClient.fromConnectionString(\n process.env.AZURE_STORAGE_CONNECTION_STRING!,\n );\n }\n async list(): Promise<ListResponse> {\n const list: string[] = [];\n const containerClient = this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n for await (const containerItem of containerClient.listBlobsFlat()) {\n list.push(containerItem.name);\n }\n return new Promise((resolve) => resolve({ keys: list }));\n }\n\n getObject(blobName: string): Promise<GetObjectResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .download(0)\n .then((downloadBlockBlobResponse) => {\n return resolve({\n body: downloadBlockBlobResponse.readableStreamBody as Readable,\n metadata: {},\n contentType: '',\n contentLength: 0,\n });\n });\n } catch (error) {\n return reject(error);\n }\n });\n }\n async getSignedUrl(\n blobName: string,\n expiresInMinutes: number,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n\n const startDate = new Date();\n const expiryDate = new Date(startDate);\n expiryDate.setMinutes(\n startDate.getMinutes() + expiresInMinutes,\n );\n\n blockBlobClient\n .generateSasUrl({\n permissions: BlobSASPermissions.parse('r'),\n startsOn: startDate,\n expiresOn: expiryDate,\n })\n .then((sasUrl) => resolve(sasUrl));\n } catch (error) {\n return reject(error);\n }\n });\n }\n async upload(\n blobName: string,\n body: FileContent,\n metadata?: { [key: string]: string } | undefined,\n ): Promise<UploadResponse> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient\n .uploadStream(body as Readable)\n .then(() => resolve({ key: blobName }));\n } catch (error) {\n return reject(error);\n }\n });\n }\n delete(blobName: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const containerClient =\n this.blobServiceClient.getContainerClient(\n this.containerName,\n );\n const blockBlobClient =\n containerClient.getBlockBlobClient(blobName);\n blockBlobClient.delete().then(() => resolve(true));\n } catch (error) {\n return reject(error);\n }\n });\n }\n}\n"]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
var __knownSymbol = (name, symbol) => {
|
|
2
|
-
if (symbol = Symbol[name])
|
|
3
|
-
return symbol;
|
|
4
|
-
throw Error("Symbol." + name + " is not defined");
|
|
5
|
-
};
|
|
6
|
-
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
7
|
-
|
|
8
|
-
export { __forAwait };
|
|
9
|
-
//# sourceMappingURL=out.js.map
|
|
10
|
-
//# sourceMappingURL=chunk-JHXQKOVY.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","sourcesContent":[]}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import './chunk-JHXQKOVY.mjs';
|
|
2
|
-
import { S3Client, ListObjectsV2Command, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
|
3
|
-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
4
|
-
|
|
5
|
-
var S3StorageService = class {
|
|
6
|
-
constructor(bucketName) {
|
|
7
|
-
this.bucketName = bucketName;
|
|
8
|
-
this.s3Client = new S3Client({});
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Lists all objects in the S3 bucket.
|
|
12
|
-
* @returns A promise that resolves to a list of object keys.
|
|
13
|
-
*/
|
|
14
|
-
async list() {
|
|
15
|
-
const allKeys = [];
|
|
16
|
-
let continuationToken = void 0;
|
|
17
|
-
do {
|
|
18
|
-
const command = new ListObjectsV2Command({
|
|
19
|
-
Bucket: this.bucketName,
|
|
20
|
-
ContinuationToken: continuationToken
|
|
21
|
-
});
|
|
22
|
-
const response = await this.s3Client.send(command);
|
|
23
|
-
if (response.Contents) {
|
|
24
|
-
for (const item of response.Contents) {
|
|
25
|
-
if (item.Key)
|
|
26
|
-
allKeys.push(item.Key);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
continuationToken = response.NextContinuationToken;
|
|
30
|
-
} while (continuationToken);
|
|
31
|
-
return { keys: allKeys };
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Retrieves an object from the S3 bucket.
|
|
35
|
-
* @param key - The key of the object to retrieve.
|
|
36
|
-
* @returns A promise that resolves to the content of the file.
|
|
37
|
-
*/
|
|
38
|
-
async getObject(key) {
|
|
39
|
-
var _a, _b;
|
|
40
|
-
const command = new GetObjectCommand({
|
|
41
|
-
Bucket: this.bucketName,
|
|
42
|
-
Key: key
|
|
43
|
-
});
|
|
44
|
-
const response = await this.s3Client.send(command);
|
|
45
|
-
return {
|
|
46
|
-
body: response.Body,
|
|
47
|
-
metadata: (_a = response.Metadata) != null ? _a : {},
|
|
48
|
-
contentType: (_b = response.ContentType) != null ? _b : "",
|
|
49
|
-
contentLength: response.ContentLength
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Generates a signed URL for accessing an object in the S3 bucket.
|
|
54
|
-
* @param key - The key of the object.
|
|
55
|
-
* @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.
|
|
56
|
-
* @returns A promise that resolves to the signed URL.
|
|
57
|
-
*/
|
|
58
|
-
getSignedUrl(key, expiresInMinutes = 60) {
|
|
59
|
-
const expiresIn = expiresInMinutes * 60;
|
|
60
|
-
const command = new GetObjectCommand({
|
|
61
|
-
Bucket: this.bucketName,
|
|
62
|
-
Key: key
|
|
63
|
-
});
|
|
64
|
-
return getSignedUrl(this.s3Client, command, { expiresIn });
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Uploads an object to the S3 bucket.
|
|
68
|
-
* @param key - The key of the object to upload.
|
|
69
|
-
* @param body - The content of the object to upload.
|
|
70
|
-
* @param metadata - Optional metadata to associate with the object.
|
|
71
|
-
* @returns A promise that resolves to the response containing the key of the uploaded object.
|
|
72
|
-
*/
|
|
73
|
-
async upload(key, body, metadata) {
|
|
74
|
-
const command = new PutObjectCommand({
|
|
75
|
-
Bucket: this.bucketName,
|
|
76
|
-
Key: key,
|
|
77
|
-
Body: body,
|
|
78
|
-
Metadata: metadata
|
|
79
|
-
});
|
|
80
|
-
await this.s3Client.send(command);
|
|
81
|
-
return { key };
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Deletes an object from the S3 bucket.
|
|
85
|
-
* @param key - The key of the object to delete.
|
|
86
|
-
* @returns A promise that resolves to true if the object was deleted successfully.
|
|
87
|
-
*/
|
|
88
|
-
async delete(key) {
|
|
89
|
-
const command = new DeleteObjectCommand({
|
|
90
|
-
Bucket: this.bucketName,
|
|
91
|
-
Key: key
|
|
92
|
-
});
|
|
93
|
-
await this.s3Client.send(command);
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export { S3StorageService };
|
|
99
|
-
//# sourceMappingURL=out.js.map
|
|
100
|
-
//# sourceMappingURL=s3Storage.service-OZGBAWBM.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/storage/s3/s3Storage.service.ts"],"names":[],"mappings":";;;AAAA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACG;AASP,SAAS,oBAAoB;AAEtB,IAAM,mBAAN,MAAiD;AAAA,EAIpD,YAAY,YAAoB;AAC5B,SAAK,aAAa;AAClB,SAAK,WAAW,IAAI,SAAS,CAAC,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAA8B;AAChC,UAAM,UAAoB,CAAC;AAE3B,QAAI,oBAAwC;AAC5C,OAAG;AACC,YAAM,UAAgC,IAAI,qBAAqB;AAAA,QAC3D,QAAQ,KAAK;AAAA,QACb,mBAAmB;AAAA,MACvB,CAAC;AAED,YAAM,WACF,MAAM,KAAK,SAAS,KAAK,OAAO;AACpC,UAAI,SAAS,UAAU;AACnB,mBAAW,QAAQ,SAAS,UAAU;AAClC,cAAI,KAAK;AAAK,oBAAQ,KAAK,KAAK,GAAG;AAAA,QACvC;AAAA,MACJ;AAEA,0BAAoB,SAAS;AAAA,IACjC,SAAS;AAET,WAAO,EAAE,MAAM,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,KAAyC;AA7D7D;AA8DQ,UAAM,UAAU,IAAI,iBAAiB;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,IACT,CAAC;AACD,UAAM,WAAW,MAAM,KAAK,SAAS,KAAK,OAAO;AACjD,WAAO;AAAA,MACH,MAAM,SAAS;AAAA,MACf,WAAU,cAAS,aAAT,YAAqB,CAAC;AAAA,MAChC,cAAa,cAAS,gBAAT,YAAwB;AAAA,MACrC,eAAe,SAAS;AAAA,IAC5B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,KAAa,mBAA2B,IAAqB;AACtE,UAAM,YAAY,mBAAmB;AACrC,UAAM,UAAU,IAAI,iBAAiB;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,IACT,CAAC;AACD,WAAO,aAAa,KAAK,UAAU,SAAS,EAAE,UAAU,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACF,KACA,MACA,UACuB;AACvB,UAAM,UAAU,IAAI,iBAAiB;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,IACd,CAAC;AACD,UAAM,KAAK,SAAS,KAAK,OAAO;AAChC,WAAO,EAAE,IAAI;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,KAA+B;AACxC,UAAM,UAAU,IAAI,oBAAoB;AAAA,MACpC,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,IACT,CAAC;AACD,UAAM,KAAK,SAAS,KAAK,OAAO;AAChC,WAAO;AAAA,EACX;AACJ","sourcesContent":["import {\n DeleteObjectCommand,\n GetObjectCommand,\n ListObjectsV2Command,\n ListObjectsV2CommandOutput,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3';\nimport { IObjectStorage } from '../../../interfaces';\nimport {\n FileContent,\n GetObjectResponse,\n ListResponse,\n UploadResponse,\n} from '../../../types';\nimport { Readable } from 'stream';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nexport class S3StorageService implements IObjectStorage {\n private s3Client: S3Client;\n private bucketName: string;\n\n constructor(bucketName: string) {\n this.bucketName = bucketName;\n this.s3Client = new S3Client({});\n }\n\n /**\n * Lists all objects in the S3 bucket.\n * @returns A promise that resolves to a list of object keys.\n */\n\n async list(): Promise<ListResponse> {\n const allKeys: string[] = [];\n\n let continuationToken: string | undefined = undefined;\n do {\n const command: ListObjectsV2Command = new ListObjectsV2Command({\n Bucket: this.bucketName,\n ContinuationToken: continuationToken,\n });\n\n const response: ListObjectsV2CommandOutput =\n await this.s3Client.send(command);\n if (response.Contents) {\n for (const item of response.Contents) {\n if (item.Key) allKeys.push(item.Key);\n }\n }\n\n continuationToken = response.NextContinuationToken;\n } while (continuationToken);\n\n return { keys: allKeys };\n }\n\n /**\n * Retrieves an object from the S3 bucket.\n * @param key - The key of the object to retrieve.\n * @returns A promise that resolves to the content of the file.\n */\n async getObject(key: string): Promise<GetObjectResponse> {\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n const response = await this.s3Client.send(command);\n return {\n body: response.Body as Readable,\n metadata: response.Metadata ?? {},\n contentType: response.ContentType ?? '',\n contentLength: response.ContentLength as number,\n };\n }\n\n /**\n * Generates a signed URL for accessing an object in the S3 bucket.\n * @param key - The key of the object.\n * @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n * @returns A promise that resolves to the signed URL.\n */\n getSignedUrl(key: string, expiresInMinutes: number = 60): Promise<string> {\n const expiresIn = expiresInMinutes * 60;\n const command = new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n return getSignedUrl(this.s3Client, command, { expiresIn });\n }\n\n /**\n * Uploads an object to the S3 bucket.\n * @param key - The key of the object to upload.\n * @param body - The content of the object to upload.\n * @param metadata - Optional metadata to associate with the object.\n * @returns A promise that resolves to the response containing the key of the uploaded object.\n */\n async upload(\n key: string,\n body: FileContent,\n metadata?: { [key: string]: string },\n ): Promise<UploadResponse> {\n const command = new PutObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n Body: body,\n Metadata: metadata,\n });\n await this.s3Client.send(command);\n return { key };\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param key - The key of the object to delete.\n * @returns A promise that resolves to true if the object was deleted successfully.\n */\n async delete(key: string): Promise<boolean> {\n const command = new DeleteObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n });\n await this.s3Client.send(command);\n return true;\n }\n}\n"]}
|