@devbro/neko-storage 0.1.10 → 0.1.12
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/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +69 -25
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/helper.d.mts +3 -0
- package/dist/esm/helper.mjs +19 -0
- package/dist/esm/helper.mjs.map +1 -0
- package/dist/esm/providers/AWSS3StorageProvider.d.mts +1 -0
- package/dist/esm/providers/AWSS3StorageProvider.mjs +14 -8
- package/dist/esm/providers/AWSS3StorageProvider.mjs.map +1 -1
- package/dist/esm/providers/AzureBlobStorageProvider.d.mts +1 -0
- package/dist/esm/providers/AzureBlobStorageProvider.mjs +6 -1
- package/dist/esm/providers/AzureBlobStorageProvider.mjs.map +1 -1
- package/dist/esm/providers/FTPStorageProvider.d.mts +1 -0
- package/dist/esm/providers/FTPStorageProvider.mjs +7 -2
- package/dist/esm/providers/FTPStorageProvider.mjs.map +1 -1
- package/dist/esm/providers/GCPStorageProvider.d.mts +1 -0
- package/dist/esm/providers/GCPStorageProvider.mjs +6 -1
- package/dist/esm/providers/GCPStorageProvider.mjs.map +1 -1
- package/dist/esm/providers/SFTPStorageProvider.d.mts +1 -0
- package/dist/esm/providers/SFTPStorageProvider.mjs +6 -2
- package/dist/esm/providers/SFTPStorageProvider.mjs.map +1 -1
- package/package.json +29 -5
package/dist/cjs/index.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ declare class Storage {
|
|
|
67
67
|
declare class AWSS3StorageProvider implements StorageProviderInterface {
|
|
68
68
|
protected config: AWSS3StorageProviderConfig;
|
|
69
69
|
private s3;
|
|
70
|
+
private static awsS3Module;
|
|
70
71
|
constructor(config: AWSS3StorageProviderConfig);
|
|
71
72
|
exists(path: string): Promise<boolean>;
|
|
72
73
|
put(path: string, content: string | object | Stream$1 | Buffer): Promise<boolean>;
|
|
@@ -96,6 +97,7 @@ declare class LocalStorageProvider implements StorageProviderInterface {
|
|
|
96
97
|
declare class GCPStorageProvider implements StorageProviderInterface {
|
|
97
98
|
protected config: GCPStorageProviderConfig;
|
|
98
99
|
private storage;
|
|
100
|
+
private static gcpModule;
|
|
99
101
|
constructor(config: GCPStorageProviderConfig);
|
|
100
102
|
exists(path: string): Promise<boolean>;
|
|
101
103
|
put(path: string, content: string | object | Stream$1 | Buffer): Promise<boolean>;
|
|
@@ -110,6 +112,7 @@ declare class GCPStorageProvider implements StorageProviderInterface {
|
|
|
110
112
|
declare class AzureBlobStorageProvider implements StorageProviderInterface {
|
|
111
113
|
protected config: AzureBlobStorageProviderConfig;
|
|
112
114
|
private blobServiceClient;
|
|
115
|
+
private static azureModule;
|
|
113
116
|
constructor(config: AzureBlobStorageProviderConfig);
|
|
114
117
|
exists(path: string): Promise<boolean>;
|
|
115
118
|
put(path: string, content: string | object | Stream$1 | Buffer): Promise<boolean>;
|
|
@@ -124,6 +127,7 @@ declare class AzureBlobStorageProvider implements StorageProviderInterface {
|
|
|
124
127
|
|
|
125
128
|
declare class FTPStorageProvider implements StorageProviderInterface {
|
|
126
129
|
private config;
|
|
130
|
+
private static ftpModule;
|
|
127
131
|
constructor(config: FTPStorageProviderConfig);
|
|
128
132
|
private getClient;
|
|
129
133
|
exists(path: string): Promise<boolean>;
|
|
@@ -138,6 +142,7 @@ declare class FTPStorageProvider implements StorageProviderInterface {
|
|
|
138
142
|
|
|
139
143
|
declare class SFTPStorageProvider implements StorageProviderInterface {
|
|
140
144
|
private config;
|
|
145
|
+
private static sftpModule;
|
|
141
146
|
constructor(config: SFTPStorageProviderConfig);
|
|
142
147
|
private getClient;
|
|
143
148
|
exists(path: string): Promise<boolean>;
|
package/dist/cjs/index.js
CHANGED
|
@@ -77,20 +77,42 @@ var Storage = class {
|
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
// src/providers/AWSS3StorageProvider.mts
|
|
80
|
-
var import_client_s3 = require("@aws-sdk/client-s3");
|
|
81
80
|
var import_stream = __toESM(require("stream"), 1);
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
// src/helper.mts
|
|
83
|
+
var import_module = require("module");
|
|
84
|
+
var import_meta = {};
|
|
85
|
+
var req = (0, import_module.createRequire)(import_meta.url);
|
|
86
|
+
function loadPackage(name) {
|
|
87
|
+
try {
|
|
88
|
+
return req(name);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (Error.isError(error) && error.code === "MODULE_NOT_FOUND") {
|
|
91
|
+
error.message = `Package "${name}" is not installed. Please install the proper storage provider package to use this storage provider.`;
|
|
92
|
+
}
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
__name(loadPackage, "loadPackage");
|
|
97
|
+
|
|
98
|
+
// src/providers/AWSS3StorageProvider.mts
|
|
99
|
+
var AWSS3StorageProvider = class _AWSS3StorageProvider {
|
|
83
100
|
constructor(config) {
|
|
84
101
|
this.config = config;
|
|
85
|
-
|
|
102
|
+
if (!_AWSS3StorageProvider.awsS3Module) {
|
|
103
|
+
_AWSS3StorageProvider.awsS3Module = loadPackage("@aws-sdk/client-s3");
|
|
104
|
+
}
|
|
105
|
+
this.s3 = new _AWSS3StorageProvider.awsS3Module.S3Client(this.config);
|
|
86
106
|
}
|
|
87
107
|
static {
|
|
88
108
|
__name(this, "AWSS3StorageProvider");
|
|
89
109
|
}
|
|
90
110
|
s3;
|
|
111
|
+
static awsS3Module;
|
|
91
112
|
async exists(path2) {
|
|
113
|
+
const { HeadObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
92
114
|
try {
|
|
93
|
-
await this.s3.send(new
|
|
115
|
+
await this.s3.send(new HeadObjectCommand({ Bucket: this.config.bucket, Key: path2 }));
|
|
94
116
|
return true;
|
|
95
117
|
} catch (error) {
|
|
96
118
|
if (error.name === "NotFound") {
|
|
@@ -100,6 +122,7 @@ var AWSS3StorageProvider = class {
|
|
|
100
122
|
}
|
|
101
123
|
}
|
|
102
124
|
async put(path2, content) {
|
|
125
|
+
const { PutObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
103
126
|
let body;
|
|
104
127
|
if (typeof content === "string" || content instanceof Buffer) {
|
|
105
128
|
body = content;
|
|
@@ -111,7 +134,7 @@ var AWSS3StorageProvider = class {
|
|
|
111
134
|
throw new Error("Unsupported content type");
|
|
112
135
|
}
|
|
113
136
|
await this.s3.send(
|
|
114
|
-
new
|
|
137
|
+
new PutObjectCommand({
|
|
115
138
|
Bucket: this.config.bucket,
|
|
116
139
|
Key: path2,
|
|
117
140
|
Body: body
|
|
@@ -120,20 +143,23 @@ var AWSS3StorageProvider = class {
|
|
|
120
143
|
return true;
|
|
121
144
|
}
|
|
122
145
|
async getJson(path2) {
|
|
146
|
+
const { GetObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
123
147
|
const data = await this.s3.send(
|
|
124
|
-
new
|
|
148
|
+
new GetObjectCommand({ Bucket: this.config.bucket, Key: path2 })
|
|
125
149
|
);
|
|
126
150
|
const body = await this.streamToString(data.Body);
|
|
127
151
|
return JSON.parse(body);
|
|
128
152
|
}
|
|
129
153
|
async getString(path2) {
|
|
154
|
+
const { GetObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
130
155
|
const data = await this.s3.send(
|
|
131
|
-
new
|
|
156
|
+
new GetObjectCommand({ Bucket: this.config.bucket, Key: path2 })
|
|
132
157
|
);
|
|
133
158
|
return await this.streamToString(data.Body);
|
|
134
159
|
}
|
|
135
160
|
async delete(path2) {
|
|
136
|
-
|
|
161
|
+
const { DeleteObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
162
|
+
await this.s3.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path2 }));
|
|
137
163
|
return true;
|
|
138
164
|
}
|
|
139
165
|
async streamToString(stream) {
|
|
@@ -145,8 +171,9 @@ var AWSS3StorageProvider = class {
|
|
|
145
171
|
});
|
|
146
172
|
}
|
|
147
173
|
async getBuffer(path2) {
|
|
174
|
+
const { GetObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
148
175
|
const data = await this.s3.send(
|
|
149
|
-
new
|
|
176
|
+
new GetObjectCommand({ Bucket: this.config.bucket, Key: path2 })
|
|
150
177
|
);
|
|
151
178
|
const chunks = [];
|
|
152
179
|
const stream = data.Body;
|
|
@@ -157,14 +184,16 @@ var AWSS3StorageProvider = class {
|
|
|
157
184
|
});
|
|
158
185
|
}
|
|
159
186
|
async getStream(path2) {
|
|
187
|
+
const { GetObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
160
188
|
const data = await this.s3.send(
|
|
161
|
-
new
|
|
189
|
+
new GetObjectCommand({ Bucket: this.config.bucket, Key: path2 })
|
|
162
190
|
);
|
|
163
191
|
return data.Body;
|
|
164
192
|
}
|
|
165
193
|
async metadata(path2) {
|
|
194
|
+
const { HeadObjectCommand } = _AWSS3StorageProvider.awsS3Module;
|
|
166
195
|
const metadata = await this.s3.send(
|
|
167
|
-
new
|
|
196
|
+
new HeadObjectCommand({ Bucket: this.config.bucket, Key: path2 })
|
|
168
197
|
);
|
|
169
198
|
return {
|
|
170
199
|
size: metadata.ContentLength || 0,
|
|
@@ -255,19 +284,23 @@ var LocalStorageProvider = class {
|
|
|
255
284
|
};
|
|
256
285
|
|
|
257
286
|
// src/providers/GCPStorageProvider.mts
|
|
258
|
-
var import_storage = require("@google-cloud/storage");
|
|
259
287
|
var import_stream3 = __toESM(require("stream"), 1);
|
|
260
288
|
var mime2 = __toESM(require("mime-types"), 1);
|
|
261
|
-
var GCPStorageProvider = class {
|
|
289
|
+
var GCPStorageProvider = class _GCPStorageProvider {
|
|
262
290
|
constructor(config) {
|
|
263
291
|
this.config = config;
|
|
292
|
+
if (!_GCPStorageProvider.gcpModule) {
|
|
293
|
+
_GCPStorageProvider.gcpModule = loadPackage("@google-cloud/storage");
|
|
294
|
+
}
|
|
295
|
+
const { Storage: GCPStorage } = _GCPStorageProvider.gcpModule;
|
|
264
296
|
const { bucket, ...gcpOptions } = config;
|
|
265
|
-
this.storage = new
|
|
297
|
+
this.storage = new GCPStorage(gcpOptions);
|
|
266
298
|
}
|
|
267
299
|
static {
|
|
268
300
|
__name(this, "GCPStorageProvider");
|
|
269
301
|
}
|
|
270
302
|
storage;
|
|
303
|
+
static gcpModule;
|
|
271
304
|
async exists(path2) {
|
|
272
305
|
try {
|
|
273
306
|
const file = this.storage.bucket(this.config.bucket).file(path2);
|
|
@@ -333,21 +366,24 @@ var GCPStorageProvider = class {
|
|
|
333
366
|
};
|
|
334
367
|
|
|
335
368
|
// src/providers/AzureBlobStorageProvider.mts
|
|
336
|
-
var import_storage_blob = require("@azure/storage-blob");
|
|
337
369
|
var import_stream4 = __toESM(require("stream"), 1);
|
|
338
370
|
var mime3 = __toESM(require("mime-types"), 1);
|
|
339
|
-
var AzureBlobStorageProvider = class {
|
|
371
|
+
var AzureBlobStorageProvider = class _AzureBlobStorageProvider {
|
|
340
372
|
constructor(config) {
|
|
341
373
|
this.config = config;
|
|
374
|
+
if (!_AzureBlobStorageProvider.azureModule) {
|
|
375
|
+
_AzureBlobStorageProvider.azureModule = loadPackage("@azure/storage-blob");
|
|
376
|
+
}
|
|
377
|
+
const { BlobServiceClient, StorageSharedKeyCredential } = _AzureBlobStorageProvider.azureModule;
|
|
342
378
|
const { accountName, accountKey, sasToken } = config;
|
|
343
379
|
if (accountKey) {
|
|
344
|
-
const sharedKeyCredential = new
|
|
345
|
-
this.blobServiceClient = new
|
|
380
|
+
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
|
|
381
|
+
this.blobServiceClient = new BlobServiceClient(
|
|
346
382
|
`https://${accountName}.blob.core.windows.net`,
|
|
347
383
|
sharedKeyCredential
|
|
348
384
|
);
|
|
349
385
|
} else if (sasToken) {
|
|
350
|
-
this.blobServiceClient = new
|
|
386
|
+
this.blobServiceClient = new BlobServiceClient(
|
|
351
387
|
`https://${accountName}.blob.core.windows.net?${sasToken}`
|
|
352
388
|
);
|
|
353
389
|
} else {
|
|
@@ -358,6 +394,7 @@ var AzureBlobStorageProvider = class {
|
|
|
358
394
|
__name(this, "AzureBlobStorageProvider");
|
|
359
395
|
}
|
|
360
396
|
blobServiceClient;
|
|
397
|
+
static azureModule;
|
|
361
398
|
async exists(path2) {
|
|
362
399
|
try {
|
|
363
400
|
const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);
|
|
@@ -445,18 +482,22 @@ var AzureBlobStorageProvider = class {
|
|
|
445
482
|
};
|
|
446
483
|
|
|
447
484
|
// src/providers/FTPStorageProvider.mts
|
|
448
|
-
var import_basic_ftp = require("basic-ftp");
|
|
449
485
|
var import_stream5 = __toESM(require("stream"), 1);
|
|
450
486
|
var mime4 = __toESM(require("mime-types"), 1);
|
|
451
|
-
var FTPStorageProvider = class {
|
|
487
|
+
var FTPStorageProvider = class _FTPStorageProvider {
|
|
452
488
|
constructor(config) {
|
|
453
489
|
this.config = config;
|
|
490
|
+
if (!_FTPStorageProvider.ftpModule) {
|
|
491
|
+
_FTPStorageProvider.ftpModule = loadPackage("basic-ftp");
|
|
492
|
+
}
|
|
454
493
|
}
|
|
455
494
|
static {
|
|
456
495
|
__name(this, "FTPStorageProvider");
|
|
457
496
|
}
|
|
497
|
+
static ftpModule;
|
|
458
498
|
async getClient() {
|
|
459
|
-
const
|
|
499
|
+
const { Client } = _FTPStorageProvider.ftpModule;
|
|
500
|
+
const client = new Client();
|
|
460
501
|
await client.access({
|
|
461
502
|
host: this.config.host,
|
|
462
503
|
port: this.config.port || 21,
|
|
@@ -565,18 +606,21 @@ var FTPStorageProvider = class {
|
|
|
565
606
|
};
|
|
566
607
|
|
|
567
608
|
// src/providers/SFTPStorageProvider.mts
|
|
568
|
-
var import_ssh2_sftp_client = __toESM(require("ssh2-sftp-client"), 1);
|
|
569
609
|
var import_stream6 = __toESM(require("stream"), 1);
|
|
570
610
|
var mime5 = __toESM(require("mime-types"), 1);
|
|
571
|
-
var SFTPStorageProvider = class {
|
|
611
|
+
var SFTPStorageProvider = class _SFTPStorageProvider {
|
|
572
612
|
constructor(config) {
|
|
573
613
|
this.config = config;
|
|
614
|
+
if (!_SFTPStorageProvider.sftpModule) {
|
|
615
|
+
_SFTPStorageProvider.sftpModule = loadPackage("ssh2-sftp-client");
|
|
616
|
+
}
|
|
574
617
|
}
|
|
575
618
|
static {
|
|
576
619
|
__name(this, "SFTPStorageProvider");
|
|
577
620
|
}
|
|
621
|
+
static sftpModule;
|
|
578
622
|
async getClient() {
|
|
579
|
-
const client = new
|
|
623
|
+
const client = new _SFTPStorageProvider.sftpModule();
|
|
580
624
|
await client.connect({
|
|
581
625
|
host: this.config.host,
|
|
582
626
|
port: this.config.port || 22,
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Storage.mts","../../src/providers/AWSS3StorageProvider.mts","../../src/providers/LocalStorageProvider.mts","../../src/providers/GCPStorageProvider.mts","../../src/providers/AzureBlobStorageProvider.mts","../../src/providers/FTPStorageProvider.mts","../../src/providers/SFTPStorageProvider.mts","../../src/StorageProviderFactory.mts"],"sourcesContent":["export * from './types.mjs';\nexport * from './Storage.mjs';\nexport * from './providers/AWSS3StorageProvider.mjs';\nexport * from './providers/LocalStorageProvider.mjs';\nexport * from './providers/GCPStorageProvider.mjs';\nexport * from './providers/AzureBlobStorageProvider.mjs';\nexport * from './providers/FTPStorageProvider.mjs';\nexport * from './providers/SFTPStorageProvider.mjs';\nexport * from './StorageProviderFactory.mjs';\nexport * from './StorageProviderInterface.mjs';\n","import { ReadStream } from 'fs';\nimport { Stream } from 'stream';\nimport { Metadata } from './types.mjs';\nimport { StorageProviderInterface } from './StorageProviderInterface.mjs';\n\nexport class Storage {\n constructor(protected provider: StorageProviderInterface) {}\n\n exists(path: string): Promise<boolean> {\n return this.provider.exists(path);\n }\n\n put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n return this.provider.put(path, content);\n }\n\n getJson(path: string): Promise<object> {\n return this.provider.getJson(path);\n }\n\n getString(path: string): Promise<string> {\n return this.provider.getString(path);\n }\n\n getBuffer(path: string): Promise<Buffer> {\n return this.provider.getBuffer(path);\n }\n\n getStream(path: string): Promise<ReadStream> {\n return this.provider.getStream(path);\n }\n\n delete(path: string): Promise<boolean> {\n return this.provider.delete(path);\n }\n\n metadata(path: string): Promise<Metadata> {\n return this.provider.metadata(path);\n }\n}\n","import { Metadata, AWSS3StorageProviderConfig } from '../types.mjs';\nimport {\n S3Client,\n HeadObjectCommand,\n PutObjectCommand,\n GetObjectCommand,\n DeleteObjectCommand,\n} from '@aws-sdk/client-s3';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\n\nexport class AWSS3StorageProvider implements StorageProviderInterface {\n private s3: S3Client;\n\n constructor(protected config: AWSS3StorageProviderConfig) {\n this.s3 = new S3Client(this.config);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await this.s3.send(new HeadObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n } catch (error: any) {\n if (error.name === 'NotFound') {\n return false;\n }\n throw error;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n let body: any;\n if (typeof content === 'string' || content instanceof Buffer) {\n body = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n body = JSON.stringify(content);\n } else if (content instanceof Stream) {\n body = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.config.bucket,\n Key: path,\n Body: body,\n })\n );\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const body = await this.streamToString(data.Body as Stream);\n return JSON.parse(body);\n }\n\n async getString(path: string): Promise<string> {\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return await this.streamToString(data.Body as Stream);\n }\n\n async delete(path: string): Promise<boolean> {\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n }\n\n private async streamToString(stream: Stream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Uint8Array[] = [];\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n stream.on('error', reject);\n });\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const chunks: Uint8Array[] = [];\n const stream = data.Body as Readable;\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return data.Body as unknown as ReadStream;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const metadata = await this.s3.send(\n new HeadObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return {\n size: metadata.ContentLength || 0,\n mimeType: metadata.ContentType || 'unknown',\n lastModifiedDate: (metadata.LastModified || new Date(0)).toISOString(),\n };\n }\n}\n","import Stream from 'stream';\nimport * as fs from 'fs/promises';\nimport { createWriteStream, createReadStream, ReadStream } from 'fs';\nimport * as path from 'path';\nimport * as mime from 'mime-types';\nimport { Metadata, LocalStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\n\nexport class LocalStorageProvider implements StorageProviderInterface {\n constructor(private config: LocalStorageProviderConfig) {\n // Ensure the base folder exists\n fs.mkdir(this.config.basePath, { recursive: true }).catch((error) => {\n throw error;\n });\n }\n\n async metadata(path: string): Promise<Metadata> {\n const fullPath = this.getFullPath(path);\n const stats = await fs.stat(fullPath);\n return {\n size: stats.size,\n mimeType: mime.lookup(fullPath) || 'unknown',\n lastModifiedDate: stats.mtime.toISOString(),\n };\n }\n\n getFullPath(filePath: string) {\n return path.join(this.config.basePath, filePath);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await fs.access(this.getFullPath(path));\n return true;\n } catch {\n return false;\n }\n }\n\n async put(filepath: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const fullPath = this.getFullPath(filepath);\n\n const dir = path.dirname(fullPath);\n await fs.mkdir(dir, { recursive: true });\n\n if (typeof content === 'string' || content instanceof Buffer) {\n await fs.writeFile(fullPath, content);\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n await fs.writeFile(fullPath, JSON.stringify(content, null, 2));\n } else if (typeof content === 'object' && content instanceof Stream) {\n const writeStream = createWriteStream(fullPath);\n await new Promise((resolve, reject) => {\n (content as Stream).pipe(writeStream);\n (content as Stream).on('end', resolve);\n (content as Stream).on('error', reject);\n });\n } else {\n throw new Error('Unsupported content type');\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const fullPath = this.getFullPath(path);\n const content = await fs.readFile(fullPath, 'utf-8');\n return JSON.parse(content);\n }\n\n async getString(path: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {\n const fullPath = this.getFullPath(path);\n return await fs.readFile(fullPath, encoding);\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const fullPath = this.getFullPath(path);\n return await fs.readFile(fullPath);\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const fullPath = this.getFullPath(path);\n return createReadStream(fullPath);\n }\n\n async delete(path: string): Promise<boolean> {\n const fullPath = this.getFullPath(path);\n await fs.unlink(fullPath);\n return true;\n }\n}\n","import { Storage as GCPStorage } from '@google-cloud/storage';\nimport { Metadata, GCPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream from 'stream';\nimport * as mime from 'mime-types';\n\nexport class GCPStorageProvider implements StorageProviderInterface {\n private storage: GCPStorage;\n\n constructor(protected config: GCPStorageProviderConfig) {\n const { bucket, ...gcpOptions } = config;\n this.storage = new GCPStorage(gcpOptions);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [exists] = await file.exists();\n return exists;\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await new Promise<void>((resolve, reject) => {\n data\n .pipe(file.createWriteStream())\n .on('finish', () => resolve())\n .on('error', reject);\n });\n } else {\n await file.save(data);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content;\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n return file.createReadStream() as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n await file.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [metadata] = await file.getMetadata();\n\n return {\n size: typeof metadata.size === 'number' ? metadata.size : parseInt(metadata.size || '0', 10),\n mimeType: metadata.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: metadata.updated || new Date(0).toISOString(),\n };\n }\n}\n","import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob';\nimport { Metadata, AzureBlobStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport * as mime from 'mime-types';\n\nexport class AzureBlobStorageProvider implements StorageProviderInterface {\n private blobServiceClient: BlobServiceClient;\n\n constructor(protected config: AzureBlobStorageProviderConfig) {\n const { accountName, accountKey, sasToken } = config;\n\n if (accountKey) {\n const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net`,\n sharedKeyCredential\n );\n } else if (sasToken) {\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net?${sasToken}`\n );\n } else {\n throw new Error('Either accountKey or sasToken is required for Azure Blob Storage');\n }\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n return await blobClient.exists();\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blockBlobClient = containerClient.getBlockBlobClient(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await blockBlobClient.uploadStream(data as Readable);\n } else {\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n await blockBlobClient.upload(buffer, buffer.length);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return await this.streamToBuffer(downloadResponse.readableStreamBody);\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return downloadResponse.readableStreamBody as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n await blobClient.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const properties = await blobClient.getProperties();\n\n return {\n size: properties.contentLength || 0,\n mimeType: properties.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: properties.lastModified?.toISOString() || new Date(0).toISOString(),\n };\n }\n\n private async streamToBuffer(readableStream: NodeJS.ReadableStream): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n readableStream.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n readableStream.on('end', () => {\n resolve(Buffer.concat(chunks));\n });\n readableStream.on('error', reject);\n });\n }\n}\n","import { Client as FTPClient } from 'basic-ftp';\nimport { Metadata, FTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\n\nexport class FTPStorageProvider implements StorageProviderInterface {\n constructor(private config: FTPStorageProviderConfig) {}\n\n private async getClient(): Promise<FTPClient> {\n const client = new FTPClient();\n await client.access({\n host: this.config.host,\n port: this.config.port || 21,\n user: this.config.user || 'anonymous',\n password: this.config.password || '',\n secure: this.config.secure || false,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.size(path);\n return true;\n } catch (error) {\n return false;\n } finally {\n client.close();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let stream: Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n const readable = new Readable();\n readable.push(typeof content === 'string' ? Buffer.from(content) : content);\n readable.push(null);\n stream = readable;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n const readable = new Readable();\n readable.push(Buffer.from(JSON.stringify(content)));\n readable.push(null);\n stream = readable;\n } else if (content instanceof Stream) {\n stream = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.uploadFrom(stream as Readable, path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const chunks: Buffer[] = [];\n const writable = new PassThrough();\n\n writable.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n\n await client.downloadTo(writable, path);\n\n return Buffer.concat(chunks);\n } finally {\n client.close();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Download to stream and close client when done\n client\n .downloadTo(passThrough, path)\n .then(() => client.close())\n .catch((error) => {\n client.close();\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n try {\n client.close();\n } catch {\n // Ignore errors if already closed\n }\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.remove(path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const size = await client.size(path);\n const lastMod = await client.lastMod(path);\n\n return {\n size: size,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: lastMod?.toISOString() || new Date(0).toISOString(),\n };\n } finally {\n client.close();\n }\n }\n}\n","import SFTPClient from 'ssh2-sftp-client';\nimport { Metadata, SFTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\n\nexport class SFTPStorageProvider implements StorageProviderInterface {\n constructor(private config: SFTPStorageProviderConfig) {}\n\n private async getClient(): Promise<SFTPClient> {\n const client = new SFTPClient();\n await client.connect({\n host: this.config.host,\n port: this.config.port || 22,\n username: this.config.username,\n password: this.config.password,\n privateKey: this.config.privateKey,\n passphrase: this.config.passphrase,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n const result = await client.exists(path);\n return result !== false;\n } catch (error) {\n return false;\n } finally {\n await client.end();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let data: string | Buffer | Readable;\n if (typeof content === 'string') {\n data = content;\n } else if (content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = Buffer.from(JSON.stringify(content));\n } else if (content instanceof Stream) {\n data = content as Readable;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.put(data, path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const buffer = await client.get(path);\n return buffer as Buffer;\n } finally {\n await client.end();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Get the file as a stream and close client when done\n client\n .get(path)\n .then((data) => {\n if (data instanceof Buffer) {\n const readable = new Readable();\n readable.push(data);\n readable.push(null);\n readable.pipe(passThrough);\n } else if (data instanceof Stream) {\n (data as Stream).pipe(passThrough);\n }\n return client.end();\n })\n .catch((error) => {\n client.end().catch(() => {\n // Ignore errors when closing client during error handling\n });\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n client.end().catch(() => {\n // Ignore errors if already closed\n });\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.delete(path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const stats = await client.stat(path);\n\n return {\n size: stats.size || 0,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: new Date((stats.modifyTime || 0) * 1000).toISOString(),\n };\n } finally {\n await client.end();\n }\n }\n}\n","import { FlexibleFactory } from '@devbro/neko-helper';\nimport { StorageProviderInterface } from './StorageProviderInterface.mjs';\n\nexport class StorageProviderFactory {\n static instance: FlexibleFactory<StorageProviderInterface> =\n new FlexibleFactory<StorageProviderInterface>();\n\n static register(key: string, factory: (...args: any[]) => StorageProviderInterface): void {\n StorageProviderFactory.instance.register(key, factory);\n }\n\n static create(key: string, ...args: any[]): StorageProviderInterface {\n return StorageProviderFactory.instance.create(key, ...args);\n }\n}\n"],"mappings":"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","names":["path","path","Stream","import_stream","path","Stream","import_stream","mime","GCPStorage","path","Stream","import_stream","mime","path","Stream","import_stream","mime","FTPClient","path","Stream","import_stream","mime","SFTPClient","path","Stream"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Storage.mts","../../src/providers/AWSS3StorageProvider.mts","../../src/helper.mts","../../src/providers/LocalStorageProvider.mts","../../src/providers/GCPStorageProvider.mts","../../src/providers/AzureBlobStorageProvider.mts","../../src/providers/FTPStorageProvider.mts","../../src/providers/SFTPStorageProvider.mts","../../src/StorageProviderFactory.mts"],"sourcesContent":["export * from './types.mjs';\nexport * from './Storage.mjs';\nexport * from './providers/AWSS3StorageProvider.mjs';\nexport * from './providers/LocalStorageProvider.mjs';\nexport * from './providers/GCPStorageProvider.mjs';\nexport * from './providers/AzureBlobStorageProvider.mjs';\nexport * from './providers/FTPStorageProvider.mjs';\nexport * from './providers/SFTPStorageProvider.mjs';\nexport * from './StorageProviderFactory.mjs';\nexport * from './StorageProviderInterface.mjs';\n","import { ReadStream } from 'fs';\nimport { Stream } from 'stream';\nimport { Metadata } from './types.mjs';\nimport { StorageProviderInterface } from './StorageProviderInterface.mjs';\n\nexport class Storage {\n constructor(protected provider: StorageProviderInterface) {}\n\n exists(path: string): Promise<boolean> {\n return this.provider.exists(path);\n }\n\n put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n return this.provider.put(path, content);\n }\n\n getJson(path: string): Promise<object> {\n return this.provider.getJson(path);\n }\n\n getString(path: string): Promise<string> {\n return this.provider.getString(path);\n }\n\n getBuffer(path: string): Promise<Buffer> {\n return this.provider.getBuffer(path);\n }\n\n getStream(path: string): Promise<ReadStream> {\n return this.provider.getStream(path);\n }\n\n delete(path: string): Promise<boolean> {\n return this.provider.delete(path);\n }\n\n metadata(path: string): Promise<Metadata> {\n return this.provider.metadata(path);\n }\n}\n","import { Metadata, AWSS3StorageProviderConfig } from '../types.mjs';\nimport type * as AwsS3 from '@aws-sdk/client-s3';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { loadPackage } from '../helper.mjs';\n\nexport class AWSS3StorageProvider implements StorageProviderInterface {\n private s3!: AwsS3.S3Client;\n private static awsS3Module: typeof AwsS3;\n\n constructor(protected config: AWSS3StorageProviderConfig) {\n if (!AWSS3StorageProvider.awsS3Module) {\n AWSS3StorageProvider.awsS3Module = loadPackage('@aws-sdk/client-s3');\n }\n this.s3 = new AWSS3StorageProvider.awsS3Module.S3Client(this.config);\n }\n\n async exists(path: string): Promise<boolean> {\n const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;\n try {\n await this.s3.send(new HeadObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n } catch (error: any) {\n if (error.name === 'NotFound') {\n return false;\n }\n throw error;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const { PutObjectCommand } = AWSS3StorageProvider.awsS3Module;\n let body: any;\n if (typeof content === 'string' || content instanceof Buffer) {\n body = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n body = JSON.stringify(content);\n } else if (content instanceof Stream) {\n body = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.config.bucket,\n Key: path,\n Body: body,\n })\n );\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const body = await this.streamToString(data.Body as Stream);\n return JSON.parse(body);\n }\n\n async getString(path: string): Promise<string> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return await this.streamToString(data.Body as Stream);\n }\n\n async delete(path: string): Promise<boolean> {\n const { DeleteObjectCommand } = AWSS3StorageProvider.awsS3Module;\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n }\n\n private async streamToString(stream: Stream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Uint8Array[] = [];\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n stream.on('error', reject);\n });\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const chunks: Uint8Array[] = [];\n const stream = data.Body as Readable;\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return data.Body as unknown as ReadStream;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const metadata = await this.s3.send(\n new HeadObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return {\n size: metadata.ContentLength || 0,\n mimeType: metadata.ContentType || 'unknown',\n lastModifiedDate: (metadata.LastModified || new Date(0)).toISOString(),\n };\n }\n}\n","import { createRequire } from 'module';\n\n// When bundled to CJS, tsup will handle import.meta.url appropriately\nconst req = createRequire(import.meta.url);\n\nexport function loadPackage(name: string) {\n try {\n return req(name);\n } catch (error: any) {\n // @ts-ignore\n if (Error.isError(error) && error.code === 'MODULE_NOT_FOUND') {\n error.message = `Package \"${name}\" is not installed. Please install the proper storage provider package to use this storage provider.`;\n }\n\n throw error;\n }\n}\n","import Stream from 'stream';\nimport * as fs from 'fs/promises';\nimport { createWriteStream, createReadStream, ReadStream } from 'fs';\nimport * as path from 'path';\nimport * as mime from 'mime-types';\nimport { Metadata, LocalStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\n\nexport class LocalStorageProvider implements StorageProviderInterface {\n constructor(private config: LocalStorageProviderConfig) {\n // Ensure the base folder exists\n fs.mkdir(this.config.basePath, { recursive: true }).catch((error) => {\n throw error;\n });\n }\n\n async metadata(path: string): Promise<Metadata> {\n const fullPath = this.getFullPath(path);\n const stats = await fs.stat(fullPath);\n return {\n size: stats.size,\n mimeType: mime.lookup(fullPath) || 'unknown',\n lastModifiedDate: stats.mtime.toISOString(),\n };\n }\n\n getFullPath(filePath: string) {\n return path.join(this.config.basePath, filePath);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await fs.access(this.getFullPath(path));\n return true;\n } catch {\n return false;\n }\n }\n\n async put(filepath: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const fullPath = this.getFullPath(filepath);\n\n const dir = path.dirname(fullPath);\n await fs.mkdir(dir, { recursive: true });\n\n if (typeof content === 'string' || content instanceof Buffer) {\n await fs.writeFile(fullPath, content);\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n await fs.writeFile(fullPath, JSON.stringify(content, null, 2));\n } else if (typeof content === 'object' && content instanceof Stream) {\n const writeStream = createWriteStream(fullPath);\n await new Promise((resolve, reject) => {\n (content as Stream).pipe(writeStream);\n (content as Stream).on('end', resolve);\n (content as Stream).on('error', reject);\n });\n } else {\n throw new Error('Unsupported content type');\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const fullPath = this.getFullPath(path);\n const content = await fs.readFile(fullPath, 'utf-8');\n return JSON.parse(content);\n }\n\n async getString(path: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {\n const fullPath = this.getFullPath(path);\n return await fs.readFile(fullPath, encoding);\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const fullPath = this.getFullPath(path);\n return await fs.readFile(fullPath);\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const fullPath = this.getFullPath(path);\n return createReadStream(fullPath);\n }\n\n async delete(path: string): Promise<boolean> {\n const fullPath = this.getFullPath(path);\n await fs.unlink(fullPath);\n return true;\n }\n}\n","import type * as GCPStorageModule from '@google-cloud/storage';\nimport { Metadata, GCPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class GCPStorageProvider implements StorageProviderInterface {\n private storage!: GCPStorageModule.Storage;\n private static gcpModule: typeof GCPStorageModule;\n\n constructor(protected config: GCPStorageProviderConfig) {\n if (!GCPStorageProvider.gcpModule) {\n GCPStorageProvider.gcpModule = loadPackage('@google-cloud/storage');\n }\n const { Storage: GCPStorage } = GCPStorageProvider.gcpModule;\n const { bucket, ...gcpOptions } = config;\n this.storage = new GCPStorage(gcpOptions);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [exists] = await file.exists();\n return exists;\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await new Promise<void>((resolve, reject) => {\n data\n .pipe(file.createWriteStream())\n .on('finish', () => resolve())\n .on('error', reject);\n });\n } else {\n await file.save(data);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content;\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n return file.createReadStream() as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n await file.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [metadata] = await file.getMetadata();\n\n return {\n size: typeof metadata.size === 'number' ? metadata.size : parseInt(metadata.size || '0', 10),\n mimeType: metadata.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: metadata.updated || new Date(0).toISOString(),\n };\n }\n}\n","import type * as AzureStorageBlob from '@azure/storage-blob';\nimport { Metadata, AzureBlobStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class AzureBlobStorageProvider implements StorageProviderInterface {\n private blobServiceClient!: AzureStorageBlob.BlobServiceClient;\n private static azureModule: typeof AzureStorageBlob;\n\n constructor(protected config: AzureBlobStorageProviderConfig) {\n if (!AzureBlobStorageProvider.azureModule) {\n AzureBlobStorageProvider.azureModule = loadPackage('@azure/storage-blob');\n }\n const { BlobServiceClient, StorageSharedKeyCredential } = AzureBlobStorageProvider.azureModule;\n const { accountName, accountKey, sasToken } = config;\n\n if (accountKey) {\n const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net`,\n sharedKeyCredential\n );\n } else if (sasToken) {\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net?${sasToken}`\n );\n } else {\n throw new Error('Either accountKey or sasToken is required for Azure Blob Storage');\n }\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n return await blobClient.exists();\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blockBlobClient = containerClient.getBlockBlobClient(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await blockBlobClient.uploadStream(data as Readable);\n } else {\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n await blockBlobClient.upload(buffer, buffer.length);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return await this.streamToBuffer(downloadResponse.readableStreamBody);\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return downloadResponse.readableStreamBody as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n await blobClient.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const properties = await blobClient.getProperties();\n\n return {\n size: properties.contentLength || 0,\n mimeType: properties.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: properties.lastModified?.toISOString() || new Date(0).toISOString(),\n };\n }\n\n private async streamToBuffer(readableStream: NodeJS.ReadableStream): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n readableStream.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n readableStream.on('end', () => {\n resolve(Buffer.concat(chunks));\n });\n readableStream.on('error', reject);\n });\n }\n}\n","import type * as BasicFtp from 'basic-ftp';\nimport { Metadata, FTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class FTPStorageProvider implements StorageProviderInterface {\n private static ftpModule: typeof BasicFtp;\n\n constructor(private config: FTPStorageProviderConfig) {\n if (!FTPStorageProvider.ftpModule) {\n FTPStorageProvider.ftpModule = loadPackage('basic-ftp');\n }\n }\n\n private async getClient(): Promise<BasicFtp.Client> {\n const { Client } = FTPStorageProvider.ftpModule;\n const client = new Client();\n await client.access({\n host: this.config.host,\n port: this.config.port || 21,\n user: this.config.user || 'anonymous',\n password: this.config.password || '',\n secure: this.config.secure || false,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.size(path);\n return true;\n } catch (error) {\n return false;\n } finally {\n client.close();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let stream: Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n const readable = new Readable();\n readable.push(typeof content === 'string' ? Buffer.from(content) : content);\n readable.push(null);\n stream = readable;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n const readable = new Readable();\n readable.push(Buffer.from(JSON.stringify(content)));\n readable.push(null);\n stream = readable;\n } else if (content instanceof Stream) {\n stream = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.uploadFrom(stream as Readable, path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const chunks: Buffer[] = [];\n const writable = new PassThrough();\n\n writable.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n\n await client.downloadTo(writable, path);\n\n return Buffer.concat(chunks);\n } finally {\n client.close();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Download to stream and close client when done\n client\n .downloadTo(passThrough, path)\n .then(() => client.close())\n .catch((error) => {\n client.close();\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n try {\n client.close();\n } catch {\n // Ignore errors if already closed\n }\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.remove(path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const size = await client.size(path);\n const lastMod = await client.lastMod(path);\n\n return {\n size: size,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: lastMod?.toISOString() || new Date(0).toISOString(),\n };\n } finally {\n client.close();\n }\n }\n}\n","import type SFTPClientType from 'ssh2-sftp-client';\nimport { Metadata, SFTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class SFTPStorageProvider implements StorageProviderInterface {\n private static sftpModule: typeof SFTPClientType;\n\n constructor(private config: SFTPStorageProviderConfig) {\n if (!SFTPStorageProvider.sftpModule) {\n SFTPStorageProvider.sftpModule = loadPackage('ssh2-sftp-client');\n }\n }\n\n private async getClient(): Promise<SFTPClientType> {\n const client = new SFTPStorageProvider.sftpModule();\n await client.connect({\n host: this.config.host,\n port: this.config.port || 22,\n username: this.config.username,\n password: this.config.password,\n privateKey: this.config.privateKey,\n passphrase: this.config.passphrase,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n const result = await client.exists(path);\n return result !== false;\n } catch (error) {\n return false;\n } finally {\n await client.end();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let data: string | Buffer | Readable;\n if (typeof content === 'string') {\n data = content;\n } else if (content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = Buffer.from(JSON.stringify(content));\n } else if (content instanceof Stream) {\n data = content as Readable;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.put(data, path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const buffer = await client.get(path);\n return buffer as Buffer;\n } finally {\n await client.end();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Get the file as a stream and close client when done\n client\n .get(path)\n .then((data) => {\n if (data instanceof Buffer) {\n const readable = new Readable();\n readable.push(data);\n readable.push(null);\n readable.pipe(passThrough);\n } else if (data instanceof Stream) {\n (data as Stream).pipe(passThrough);\n }\n return client.end();\n })\n .catch((error) => {\n client.end().catch(() => {\n // Ignore errors when closing client during error handling\n });\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n client.end().catch(() => {\n // Ignore errors if already closed\n });\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.delete(path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const stats = await client.stat(path);\n\n return {\n size: stats.size || 0,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: new Date((stats.modifyTime || 0) * 1000).toISOString(),\n };\n } finally {\n await client.end();\n }\n }\n}\n","import { FlexibleFactory } from '@devbro/neko-helper';\nimport { StorageProviderInterface } from './StorageProviderInterface.mjs';\n\nexport class StorageProviderFactory {\n static instance: FlexibleFactory<StorageProviderInterface> =\n new FlexibleFactory<StorageProviderInterface>();\n\n static register(key: string, factory: (...args: any[]) => StorageProviderInterface): void {\n StorageProviderFactory.instance.register(key, factory);\n }\n\n static create(key: string, ...args: any[]): StorageProviderInterface {\n return StorageProviderFactory.instance.create(key, ...args);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;ACKO,IAAM,UAAN,MAAc;AAAA,EACnB,YAAsB,UAAoC;AAApC;AAAA,EAAqC;AAAA,EAN7D,OAKqB;AAAA;AAAA;AAAA,EAGnB,OAAOA,OAAgC;AACrC,WAAO,KAAK,SAAS,OAAOA,KAAI;AAAA,EAClC;AAAA,EAEA,IAAIA,OAAc,SAA8D;AAC9E,WAAO,KAAK,SAAS,IAAIA,OAAM,OAAO;AAAA,EACxC;AAAA,EAEA,QAAQA,OAA+B;AACrC,WAAO,KAAK,SAAS,QAAQA,KAAI;AAAA,EACnC;AAAA,EAEA,UAAUA,OAA+B;AACvC,WAAO,KAAK,SAAS,UAAUA,KAAI;AAAA,EACrC;AAAA,EAEA,UAAUA,OAA+B;AACvC,WAAO,KAAK,SAAS,UAAUA,KAAI;AAAA,EACrC;AAAA,EAEA,UAAUA,OAAmC;AAC3C,WAAO,KAAK,SAAS,UAAUA,KAAI;AAAA,EACrC;AAAA,EAEA,OAAOA,OAAgC;AACrC,WAAO,KAAK,SAAS,OAAOA,KAAI;AAAA,EAClC;AAAA,EAEA,SAASA,OAAiC;AACxC,WAAO,KAAK,SAAS,SAASA,KAAI;AAAA,EACpC;AACF;;;ACpCA,oBAAiC;;;ACHjC,oBAA8B;AAA9B;AAGA,IAAM,UAAM,6BAAc,YAAY,GAAG;AAElC,SAAS,YAAY,MAAc;AACxC,MAAI;AACF,WAAO,IAAI,IAAI;AAAA,EACjB,SAAS,OAAY;AAEnB,QAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,oBAAoB;AAC7D,YAAM,UAAU,YAAY,IAAI;AAAA,IAClC;AAEA,UAAM;AAAA,EACR;AACF;AAXgB;;;ADET,IAAM,uBAAN,MAAM,sBAAyD;AAAA,EAIpE,YAAsB,QAAoC;AAApC;AACpB,QAAI,CAAC,sBAAqB,aAAa;AACrC,4BAAqB,cAAc,YAAY,oBAAoB;AAAA,IACrE;AACA,SAAK,KAAK,IAAI,sBAAqB,YAAY,SAAS,KAAK,MAAM;AAAA,EACrE;AAAA,EAhBF,OAOsE;AAAA;AAAA;AAAA,EAC5D;AAAA,EACR,OAAe;AAAA,EASf,MAAM,OAAOC,OAAgC;AAC3C,UAAM,EAAE,kBAAkB,IAAI,sBAAqB;AACnD,QAAI;AACF,YAAM,KAAK,GAAG,KAAK,IAAI,kBAAkB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC,CAAC;AACnF,aAAO;AAAA,IACT,SAAS,OAAY;AACnB,UAAI,MAAM,SAAS,YAAY;AAC7B,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,IAAIA,OAAc,SAA8D;AACpF,UAAM,EAAE,iBAAiB,IAAI,sBAAqB;AAClD,QAAI;AACJ,QAAI,OAAO,YAAY,YAAY,mBAAmB,QAAQ;AAC5D,aAAO;AAAA,IACT,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,cAAAC,UAAS;AACtE,aAAO,KAAK,UAAU,OAAO;AAAA,IAC/B,WAAW,mBAAmB,cAAAA,SAAQ;AACpC,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAEA,UAAM,KAAK,GAAG;AAAA,MACZ,IAAI,iBAAiB;AAAA,QACnB,QAAQ,KAAK,OAAO;AAAA,QACpB,KAAKD;AAAA,QACL,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQA,OAA+B;AAC3C,UAAM,EAAE,iBAAiB,IAAI,sBAAqB;AAClD,UAAM,OAAO,MAAM,KAAK,GAAG;AAAA,MACzB,IAAI,iBAAiB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC;AAAA,IAChE;AACA,UAAM,OAAO,MAAM,KAAK,eAAe,KAAK,IAAc;AAC1D,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,EAAE,iBAAiB,IAAI,sBAAqB;AAClD,UAAM,OAAO,MAAM,KAAK,GAAG;AAAA,MACzB,IAAI,iBAAiB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC;AAAA,IAChE;AACA,WAAO,MAAM,KAAK,eAAe,KAAK,IAAc;AAAA,EACtD;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,UAAM,EAAE,oBAAoB,IAAI,sBAAqB;AACrD,UAAM,KAAK,GAAG,KAAK,IAAI,oBAAoB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC,CAAC;AACrF,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,QAAiC;AAC5D,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAuB,CAAC;AAC9B,aAAO,GAAG,QAAQ,CAAC,UAAU,OAAO,KAAK,KAAK,CAAC;AAC/C,aAAO,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC;AACvE,aAAO,GAAG,SAAS,MAAM;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,EAAE,iBAAiB,IAAI,sBAAqB;AAClD,UAAM,OAAO,MAAM,KAAK,GAAG;AAAA,MACzB,IAAI,iBAAiB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC;AAAA,IAChE;AACA,UAAM,SAAuB,CAAC;AAC9B,UAAM,SAAS,KAAK;AAEpB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,aAAO,GAAG,QAAQ,CAAC,UAAU,OAAO,KAAK,KAAK,CAAC;AAC/C,aAAO,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AACrD,aAAO,GAAG,SAAS,MAAM;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,EAAE,iBAAiB,IAAI,sBAAqB;AAClD,UAAM,OAAO,MAAM,KAAK,GAAG;AAAA,MACzB,IAAI,iBAAiB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC;AAAA,IAChE;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,SAASA,OAAiC;AAC9C,UAAM,EAAE,kBAAkB,IAAI,sBAAqB;AACnD,UAAM,WAAW,MAAM,KAAK,GAAG;AAAA,MAC7B,IAAI,kBAAkB,EAAE,QAAQ,KAAK,OAAO,QAAQ,KAAKA,MAAK,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,MACL,MAAM,SAAS,iBAAiB;AAAA,MAChC,UAAU,SAAS,eAAe;AAAA,MAClC,mBAAmB,SAAS,gBAAgB,oBAAI,KAAK,CAAC,GAAG,YAAY;AAAA,IACvE;AAAA,EACF;AACF;;;AEzHA,IAAAE,iBAAmB;AACnB,SAAoB;AACpB,gBAAgE;AAChE,WAAsB;AACtB,WAAsB;AAIf,IAAM,uBAAN,MAA+D;AAAA,EACpE,YAAoB,QAAoC;AAApC;AAElB,IAAG,SAAM,KAAK,OAAO,UAAU,EAAE,WAAW,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU;AACnE,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAdF,OAQsE;AAAA;AAAA;AAAA,EAQpE,MAAM,SAASC,OAAiC;AAC9C,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,UAAM,QAAQ,MAAS,QAAK,QAAQ;AACpC,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,UAAe,YAAO,QAAQ,KAAK;AAAA,MACnC,kBAAkB,MAAM,MAAM,YAAY;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,YAAY,UAAkB;AAC5B,WAAY,UAAK,KAAK,OAAO,UAAU,QAAQ;AAAA,EACjD;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,QAAI;AACF,YAAS,UAAO,KAAK,YAAYA,KAAI,CAAC;AACtC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,UAAkB,SAA8D;AACxF,UAAM,WAAW,KAAK,YAAY,QAAQ;AAE1C,UAAM,MAAW,aAAQ,QAAQ;AACjC,UAAS,SAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEvC,QAAI,OAAO,YAAY,YAAY,mBAAmB,QAAQ;AAC5D,YAAS,aAAU,UAAU,OAAO;AAAA,IACtC,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,eAAAC,UAAS;AACtE,YAAS,aAAU,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,IAC/D,WAAW,OAAO,YAAY,YAAY,mBAAmB,eAAAA,SAAQ;AACnE,YAAM,kBAAc,6BAAkB,QAAQ;AAC9C,YAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,QAAC,QAAmB,KAAK,WAAW;AACpC,QAAC,QAAmB,GAAG,OAAO,OAAO;AACrC,QAAC,QAAmB,GAAG,SAAS,MAAM;AAAA,MACxC,CAAC;AAAA,IACH,OAAO;AACL,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQD,OAA+B;AAC3C,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,UAAM,UAAU,MAAS,YAAS,UAAU,OAAO;AACnD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAM,UAAUA,OAAc,WAA2B,SAA0B;AACjF,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,WAAO,MAAS,YAAS,UAAU,QAAQ;AAAA,EAC7C;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,WAAO,MAAS,YAAS,QAAQ;AAAA,EACnC;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,eAAO,4BAAiB,QAAQ;AAAA,EAClC;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,UAAM,WAAW,KAAK,YAAYA,KAAI;AACtC,UAAS,UAAO,QAAQ;AACxB,WAAO;AAAA,EACT;AACF;;;ACrFA,IAAAE,iBAAmB;AACnB,IAAAC,QAAsB;AAGf,IAAM,qBAAN,MAAM,oBAAuD;AAAA,EAIlE,YAAsB,QAAkC;AAAlC;AACpB,QAAI,CAAC,oBAAmB,WAAW;AACjC,0BAAmB,YAAY,YAAY,uBAAuB;AAAA,IACpE;AACA,UAAM,EAAE,SAAS,WAAW,IAAI,oBAAmB;AACnD,UAAM,EAAE,QAAQ,GAAG,WAAW,IAAI;AAClC,SAAK,UAAU,IAAI,WAAW,UAAU;AAAA,EAC1C;AAAA,EAnBF,OAQoE;AAAA;AAAA;AAAA,EAC1D;AAAA,EACR,OAAe;AAAA,EAWf,MAAM,OAAOC,OAAgC;AAC3C,QAAI;AACF,YAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,YAAM,CAAC,MAAM,IAAI,MAAM,KAAK,OAAO;AACnC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAIA,OAAc,SAA8D;AACpF,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAE9D,QAAI;AACJ,QAAI,OAAO,YAAY,YAAY,mBAAmB,QAAQ;AAC5D,aAAO;AAAA,IACT,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,eAAAC,UAAS;AACtE,aAAO,KAAK,UAAU,OAAO;AAAA,IAC/B,WAAW,mBAAmB,eAAAA,SAAQ;AACpC,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAEA,QAAI,gBAAgB,eAAAA,SAAQ;AAC1B,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,aACG,KAAK,KAAK,kBAAkB,CAAC,EAC7B,GAAG,UAAU,MAAM,QAAQ,CAAC,EAC5B,GAAG,SAAS,MAAM;AAAA,MACvB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,KAAK,IAAI;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQD,OAA+B;AAC3C,UAAM,OAAO,MAAM,KAAK,UAAUA,KAAI;AACtC,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,UAAM,CAAC,OAAO,IAAI,MAAM,KAAK,SAAS;AACtC,WAAO,QAAQ,SAAS,OAAO;AAAA,EACjC;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,UAAM,CAAC,OAAO,IAAI,MAAM,KAAK,SAAS;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,UAAM,KAAK,OAAO;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAASA,OAAiC;AAC9C,UAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO,MAAM,EAAE,KAAKA,KAAI;AAC9D,UAAM,CAAC,QAAQ,IAAI,MAAM,KAAK,YAAY;AAE1C,WAAO;AAAA,MACL,MAAM,OAAO,SAAS,SAAS,WAAW,SAAS,OAAO,SAAS,SAAS,QAAQ,KAAK,EAAE;AAAA,MAC3F,UAAU,SAAS,eAAoB,aAAOA,KAAI,KAAK;AAAA,MACvD,kBAAkB,SAAS,YAAW,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,IAChE;AAAA,EACF;AACF;;;AC7FA,IAAAE,iBAAiC;AACjC,IAAAC,QAAsB;AAGf,IAAM,2BAAN,MAAM,0BAA6D;AAAA,EAIxE,YAAsB,QAAwC;AAAxC;AACpB,QAAI,CAAC,0BAAyB,aAAa;AACzC,gCAAyB,cAAc,YAAY,qBAAqB;AAAA,IAC1E;AACA,UAAM,EAAE,mBAAmB,2BAA2B,IAAI,0BAAyB;AACnF,UAAM,EAAE,aAAa,YAAY,SAAS,IAAI;AAE9C,QAAI,YAAY;AACd,YAAM,sBAAsB,IAAI,2BAA2B,aAAa,UAAU;AAClF,WAAK,oBAAoB,IAAI;AAAA,QAC3B,WAAW,WAAW;AAAA,QACtB;AAAA,MACF;AAAA,IACF,WAAW,UAAU;AACnB,WAAK,oBAAoB,IAAI;AAAA,QAC3B,WAAW,WAAW,0BAA0B,QAAQ;AAAA,MAC1D;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AAAA,EACF;AAAA,EAhCF,OAQ0E;AAAA;AAAA;AAAA,EAChE;AAAA,EACR,OAAe;AAAA,EAwBf,MAAM,OAAOC,OAAgC;AAC3C,QAAI;AACF,YAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,YAAM,aAAa,gBAAgB,cAAcA,KAAI;AACrD,aAAO,MAAM,WAAW,OAAO;AAAA,IACjC,SAAS,OAAO;AACd,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAIA,OAAc,SAA8D;AACpF,UAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,UAAM,kBAAkB,gBAAgB,mBAAmBA,KAAI;AAE/D,QAAI;AACJ,QAAI,OAAO,YAAY,YAAY,mBAAmB,QAAQ;AAC5D,aAAO;AAAA,IACT,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,eAAAC,UAAS;AACtE,aAAO,KAAK,UAAU,OAAO;AAAA,IAC/B,WAAW,mBAAmB,eAAAA,SAAQ;AACpC,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAEA,QAAI,gBAAgB,eAAAA,SAAQ;AAC1B,YAAM,gBAAgB,aAAa,IAAgB;AAAA,IACrD,OAAO;AACL,YAAM,SAAS,OAAO,SAAS,WAAW,OAAO,KAAK,IAAI,IAAI;AAC9D,YAAM,gBAAgB,OAAO,QAAQ,OAAO,MAAM;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQD,OAA+B;AAC3C,UAAM,OAAO,MAAM,KAAK,UAAUA,KAAI;AACtC,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,SAAS,MAAM,KAAK,UAAUA,KAAI;AACxC,WAAO,OAAO,SAAS,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,UAAM,aAAa,gBAAgB,cAAcA,KAAI;AACrD,UAAM,mBAAmB,MAAM,WAAW,SAAS;AAEnD,QAAI,CAAC,iBAAiB,oBAAoB;AACxC,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,WAAO,MAAM,KAAK,eAAe,iBAAiB,kBAAkB;AAAA,EACtE;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,UAAM,aAAa,gBAAgB,cAAcA,KAAI;AACrD,UAAM,mBAAmB,MAAM,WAAW,SAAS;AAEnD,QAAI,CAAC,iBAAiB,oBAAoB;AACxC,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,WAAO,iBAAiB;AAAA,EAC1B;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,UAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,UAAM,aAAa,gBAAgB,cAAcA,KAAI;AACrD,UAAM,WAAW,OAAO;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAASA,OAAiC;AAC9C,UAAM,kBAAkB,KAAK,kBAAkB,mBAAmB,KAAK,OAAO,aAAa;AAC3F,UAAM,aAAa,gBAAgB,cAAcA,KAAI;AACrD,UAAM,aAAa,MAAM,WAAW,cAAc;AAElD,WAAO;AAAA,MACL,MAAM,WAAW,iBAAiB;AAAA,MAClC,UAAU,WAAW,eAAoB,aAAOA,KAAI,KAAK;AAAA,MACzD,kBAAkB,WAAW,cAAc,YAAY,MAAK,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,IACtF;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,gBAAwD;AACnF,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAmB,CAAC;AAC1B,qBAAe,GAAG,QAAQ,CAAC,UAAU;AACnC,eAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,MACjE,CAAC;AACD,qBAAe,GAAG,OAAO,MAAM;AAC7B,gBAAQ,OAAO,OAAO,MAAM,CAAC;AAAA,MAC/B,CAAC;AACD,qBAAe,GAAG,SAAS,MAAM;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;AClIA,IAAAE,iBAA8C;AAC9C,IAAAC,QAAsB;AAGf,IAAM,qBAAN,MAAM,oBAAuD;AAAA,EAGlE,YAAoB,QAAkC;AAAlC;AAClB,QAAI,CAAC,oBAAmB,WAAW;AACjC,0BAAmB,YAAY,YAAY,WAAW;AAAA,IACxD;AAAA,EACF;AAAA,EAfF,OAQoE;AAAA;AAAA;AAAA,EAClE,OAAe;AAAA,EAQf,MAAc,YAAsC;AAClD,UAAM,EAAE,OAAO,IAAI,oBAAmB;AACtC,UAAM,SAAS,IAAI,OAAO;AAC1B,UAAM,OAAO,OAAO;AAAA,MAClB,MAAM,KAAK,OAAO;AAAA,MAClB,MAAM,KAAK,OAAO,QAAQ;AAAA,MAC1B,MAAM,KAAK,OAAO,QAAQ;AAAA,MAC1B,UAAU,KAAK,OAAO,YAAY;AAAA,MAClC,QAAQ,KAAK,OAAO,UAAU;AAAA,IAChC,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAOC,OAAgC;AAC3C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,OAAO,KAAKA,KAAI;AACtB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO;AAAA,IACT,UAAE;AACA,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,IAAIA,OAAc,SAA8D;AACpF,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,UAAI;AACJ,UAAI,OAAO,YAAY,YAAY,mBAAmB,QAAQ;AAC5D,cAAM,WAAW,IAAI,wBAAS;AAC9B,iBAAS,KAAK,OAAO,YAAY,WAAW,OAAO,KAAK,OAAO,IAAI,OAAO;AAC1E,iBAAS,KAAK,IAAI;AAClB,iBAAS;AAAA,MACX,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,eAAAC,UAAS;AACtE,cAAM,WAAW,IAAI,wBAAS;AAC9B,iBAAS,KAAK,OAAO,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC;AAClD,iBAAS,KAAK,IAAI;AAClB,iBAAS;AAAA,MACX,WAAW,mBAAmB,eAAAA,SAAQ;AACpC,iBAAS;AAAA,MACX,OAAO;AACL,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,YAAM,OAAO,WAAW,QAAoBD,KAAI;AAChD,aAAO;AAAA,IACT,UAAE;AACA,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,QAAQA,OAA+B;AAC3C,UAAM,OAAO,MAAM,KAAK,UAAUA,KAAI;AACtC,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,SAAS,MAAM,KAAK,UAAUA,KAAI;AACxC,WAAO,OAAO,SAAS,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,SAAmB,CAAC;AAC1B,YAAM,WAAW,IAAI,2BAAY;AAEjC,eAAS,GAAG,QAAQ,CAAC,UAAU;AAC7B,eAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,MACjE,CAAC;AAED,YAAM,OAAO,WAAW,UAAUA,KAAI;AAEtC,aAAO,OAAO,OAAO,MAAM;AAAA,IAC7B,UAAE;AACA,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,UAAM,cAAc,IAAI,2BAAY;AAGpC,WACG,WAAW,aAAaA,KAAI,EAC5B,KAAK,MAAM,OAAO,MAAM,CAAC,EACzB,MAAM,CAAC,UAAU;AAChB,aAAO,MAAM;AACb,kBAAY,QAAQ,KAAK;AAAA,IAC3B,CAAC;AAGH,gBAAY,GAAG,SAAS,MAAM;AAC5B,UAAI;AACF,eAAO,MAAM;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,OAAO,OAAOA,KAAI;AACxB,aAAO;AAAA,IACT,UAAE;AACA,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,SAASA,OAAiC;AAC9C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,OAAO,MAAM,OAAO,KAAKA,KAAI;AACnC,YAAM,UAAU,MAAM,OAAO,QAAQA,KAAI;AAEzC,aAAO;AAAA,QACL;AAAA,QACA,UAAe,aAAOA,KAAI,KAAK;AAAA,QAC/B,kBAAkB,SAAS,YAAY,MAAK,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,MACtE;AAAA,IACF,UAAE;AACA,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACF;;;AC/IA,IAAAE,iBAA8C;AAC9C,IAAAC,QAAsB;AAGf,IAAM,sBAAN,MAAM,qBAAwD;AAAA,EAGnE,YAAoB,QAAmC;AAAnC;AAClB,QAAI,CAAC,qBAAoB,YAAY;AACnC,2BAAoB,aAAa,YAAY,kBAAkB;AAAA,IACjE;AAAA,EACF;AAAA,EAfF,OAQqE;AAAA;AAAA;AAAA,EACnE,OAAe;AAAA,EAQf,MAAc,YAAqC;AACjD,UAAM,SAAS,IAAI,qBAAoB,WAAW;AAClD,UAAM,OAAO,QAAQ;AAAA,MACnB,MAAM,KAAK,OAAO;AAAA,MAClB,MAAM,KAAK,OAAO,QAAQ;AAAA,MAC1B,UAAU,KAAK,OAAO;AAAA,MACtB,UAAU,KAAK,OAAO;AAAA,MACtB,YAAY,KAAK,OAAO;AAAA,MACxB,YAAY,KAAK,OAAO;AAAA,IAC1B,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAOC,OAAgC;AAC3C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,OAAOA,KAAI;AACvC,aAAO,WAAW;AAAA,IACpB,SAAS,OAAO;AACd,aAAO;AAAA,IACT,UAAE;AACA,YAAM,OAAO,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,IAAIA,OAAc,SAA8D;AACpF,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,UAAI;AACJ,UAAI,OAAO,YAAY,UAAU;AAC/B,eAAO;AAAA,MACT,WAAW,mBAAmB,QAAQ;AACpC,eAAO;AAAA,MACT,WAAW,OAAO,YAAY,YAAY,EAAE,mBAAmB,eAAAC,UAAS;AACtE,eAAO,OAAO,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,MAC5C,WAAW,mBAAmB,eAAAA,SAAQ;AACpC,eAAO;AAAA,MACT,OAAO;AACL,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,YAAM,OAAO,IAAI,MAAMD,KAAI;AAC3B,aAAO;AAAA,IACT,UAAE;AACA,YAAM,OAAO,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,QAAQA,OAA+B;AAC3C,UAAM,OAAO,MAAM,KAAK,UAAUA,KAAI;AACtC,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,SAAS,MAAM,KAAK,UAAUA,KAAI;AACxC,WAAO,OAAO,SAAS,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,UAAUA,OAA+B;AAC7C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,IAAIA,KAAI;AACpC,aAAO;AAAA,IACT,UAAE;AACA,YAAM,OAAO,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,UAAUA,OAAmC;AACjD,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,UAAM,cAAc,IAAI,2BAAY;AAGpC,WACG,IAAIA,KAAI,EACR,KAAK,CAAC,SAAS;AACd,UAAI,gBAAgB,QAAQ;AAC1B,cAAM,WAAW,IAAI,wBAAS;AAC9B,iBAAS,KAAK,IAAI;AAClB,iBAAS,KAAK,IAAI;AAClB,iBAAS,KAAK,WAAW;AAAA,MAC3B,WAAW,gBAAgB,eAAAC,SAAQ;AACjC,QAAC,KAAgB,KAAK,WAAW;AAAA,MACnC;AACA,aAAO,OAAO,IAAI;AAAA,IACpB,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,aAAO,IAAI,EAAE,MAAM,MAAM;AAAA,MAEzB,CAAC;AACD,kBAAY,QAAQ,KAAK;AAAA,IAC3B,CAAC;AAGH,gBAAY,GAAG,SAAS,MAAM;AAC5B,aAAO,IAAI,EAAE,MAAM,MAAM;AAAA,MAEzB,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAOD,OAAgC;AAC3C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,OAAO,OAAOA,KAAI;AACxB,aAAO;AAAA,IACT,UAAE;AACA,YAAM,OAAO,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,SAASA,OAAiC;AAC9C,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,KAAKA,KAAI;AAEpC,aAAO;AAAA,QACL,MAAM,MAAM,QAAQ;AAAA,QACpB,UAAe,aAAOA,KAAI,KAAK;AAAA,QAC/B,kBAAkB,IAAI,MAAM,MAAM,cAAc,KAAK,GAAI,EAAE,YAAY;AAAA,MACzE;AAAA,IACF,UAAE;AACA,YAAM,OAAO,IAAI;AAAA,IACnB;AAAA,EACF;AACF;;;AChJA,yBAAgC;AAGzB,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EAHpC,OAGoC;AAAA;AAAA;AAAA,EAClC,OAAO,WACL,IAAI,mCAA0C;AAAA,EAEhD,OAAO,SAAS,KAAa,SAA6D;AACxF,4BAAuB,SAAS,SAAS,KAAK,OAAO;AAAA,EACvD;AAAA,EAEA,OAAO,OAAO,QAAgB,MAAuC;AACnE,WAAO,wBAAuB,SAAS,OAAO,KAAK,GAAG,IAAI;AAAA,EAC5D;AACF;","names":["path","path","Stream","import_stream","path","Stream","import_stream","mime","path","Stream","import_stream","mime","path","Stream","import_stream","mime","path","Stream","import_stream","mime","path","Stream"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
const req = createRequire(import.meta.url);
|
|
5
|
+
function loadPackage(name) {
|
|
6
|
+
try {
|
|
7
|
+
return req(name);
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (Error.isError(error) && error.code === "MODULE_NOT_FOUND") {
|
|
10
|
+
error.message = `Package "${name}" is not installed. Please install the proper storage provider package to use this storage provider.`;
|
|
11
|
+
}
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
__name(loadPackage, "loadPackage");
|
|
16
|
+
export {
|
|
17
|
+
loadPackage
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=helper.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helper.mts"],"sourcesContent":["import { createRequire } from 'module';\n\n// When bundled to CJS, tsup will handle import.meta.url appropriately\nconst req = createRequire(import.meta.url);\n\nexport function loadPackage(name: string) {\n try {\n return req(name);\n } catch (error: any) {\n // @ts-ignore\n if (Error.isError(error) && error.code === 'MODULE_NOT_FOUND') {\n error.message = `Package \"${name}\" is not installed. Please install the proper storage provider package to use this storage provider.`;\n }\n\n throw error;\n }\n}\n"],"mappings":";;AAAA,SAAS,qBAAqB;AAG9B,MAAM,MAAM,cAAc,YAAY,GAAG;AAElC,SAAS,YAAY,MAAc;AACxC,MAAI;AACF,WAAO,IAAI,IAAI;AAAA,EACjB,SAAS,OAAY;AAEnB,QAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,oBAAoB;AAC7D,YAAM,UAAU,YAAY,IAAI;AAAA,IAClC;AAEA,UAAM;AAAA,EACR;AACF;AAXgB;","names":[]}
|
|
@@ -8,6 +8,7 @@ import '@google-cloud/storage';
|
|
|
8
8
|
declare class AWSS3StorageProvider implements StorageProviderInterface {
|
|
9
9
|
protected config: AWSS3StorageProviderConfig;
|
|
10
10
|
private s3;
|
|
11
|
+
private static awsS3Module;
|
|
11
12
|
constructor(config: AWSS3StorageProviderConfig);
|
|
12
13
|
exists(path: string): Promise<boolean>;
|
|
13
14
|
put(path: string, content: string | object | Stream | Buffer): Promise<boolean>;
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import {
|
|
4
|
-
S3Client,
|
|
5
|
-
HeadObjectCommand,
|
|
6
|
-
PutObjectCommand,
|
|
7
|
-
GetObjectCommand,
|
|
8
|
-
DeleteObjectCommand
|
|
9
|
-
} from "@aws-sdk/client-s3";
|
|
10
3
|
import Stream from "stream";
|
|
4
|
+
import { loadPackage } from "../helper.mjs";
|
|
11
5
|
class AWSS3StorageProvider {
|
|
12
6
|
constructor(config) {
|
|
13
7
|
this.config = config;
|
|
14
|
-
|
|
8
|
+
if (!AWSS3StorageProvider.awsS3Module) {
|
|
9
|
+
AWSS3StorageProvider.awsS3Module = loadPackage("@aws-sdk/client-s3");
|
|
10
|
+
}
|
|
11
|
+
this.s3 = new AWSS3StorageProvider.awsS3Module.S3Client(this.config);
|
|
15
12
|
}
|
|
16
13
|
static {
|
|
17
14
|
__name(this, "AWSS3StorageProvider");
|
|
18
15
|
}
|
|
19
16
|
s3;
|
|
17
|
+
static awsS3Module;
|
|
20
18
|
async exists(path) {
|
|
19
|
+
const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
21
20
|
try {
|
|
22
21
|
await this.s3.send(new HeadObjectCommand({ Bucket: this.config.bucket, Key: path }));
|
|
23
22
|
return true;
|
|
@@ -29,6 +28,7 @@ class AWSS3StorageProvider {
|
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
async put(path, content) {
|
|
31
|
+
const { PutObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
32
32
|
let body;
|
|
33
33
|
if (typeof content === "string" || content instanceof Buffer) {
|
|
34
34
|
body = content;
|
|
@@ -49,6 +49,7 @@ class AWSS3StorageProvider {
|
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
51
|
async getJson(path) {
|
|
52
|
+
const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
52
53
|
const data = await this.s3.send(
|
|
53
54
|
new GetObjectCommand({ Bucket: this.config.bucket, Key: path })
|
|
54
55
|
);
|
|
@@ -56,12 +57,14 @@ class AWSS3StorageProvider {
|
|
|
56
57
|
return JSON.parse(body);
|
|
57
58
|
}
|
|
58
59
|
async getString(path) {
|
|
60
|
+
const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
59
61
|
const data = await this.s3.send(
|
|
60
62
|
new GetObjectCommand({ Bucket: this.config.bucket, Key: path })
|
|
61
63
|
);
|
|
62
64
|
return await this.streamToString(data.Body);
|
|
63
65
|
}
|
|
64
66
|
async delete(path) {
|
|
67
|
+
const { DeleteObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
65
68
|
await this.s3.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path }));
|
|
66
69
|
return true;
|
|
67
70
|
}
|
|
@@ -74,6 +77,7 @@ class AWSS3StorageProvider {
|
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
async getBuffer(path) {
|
|
80
|
+
const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
77
81
|
const data = await this.s3.send(
|
|
78
82
|
new GetObjectCommand({ Bucket: this.config.bucket, Key: path })
|
|
79
83
|
);
|
|
@@ -86,12 +90,14 @@ class AWSS3StorageProvider {
|
|
|
86
90
|
});
|
|
87
91
|
}
|
|
88
92
|
async getStream(path) {
|
|
93
|
+
const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
89
94
|
const data = await this.s3.send(
|
|
90
95
|
new GetObjectCommand({ Bucket: this.config.bucket, Key: path })
|
|
91
96
|
);
|
|
92
97
|
return data.Body;
|
|
93
98
|
}
|
|
94
99
|
async metadata(path) {
|
|
100
|
+
const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;
|
|
95
101
|
const metadata = await this.s3.send(
|
|
96
102
|
new HeadObjectCommand({ Bucket: this.config.bucket, Key: path })
|
|
97
103
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/AWSS3StorageProvider.mts"],"sourcesContent":["import { Metadata, AWSS3StorageProviderConfig } from '../types.mjs';\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/AWSS3StorageProvider.mts"],"sourcesContent":["import { Metadata, AWSS3StorageProviderConfig } from '../types.mjs';\nimport type * as AwsS3 from '@aws-sdk/client-s3';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { loadPackage } from '../helper.mjs';\n\nexport class AWSS3StorageProvider implements StorageProviderInterface {\n private s3!: AwsS3.S3Client;\n private static awsS3Module: typeof AwsS3;\n\n constructor(protected config: AWSS3StorageProviderConfig) {\n if (!AWSS3StorageProvider.awsS3Module) {\n AWSS3StorageProvider.awsS3Module = loadPackage('@aws-sdk/client-s3');\n }\n this.s3 = new AWSS3StorageProvider.awsS3Module.S3Client(this.config);\n }\n\n async exists(path: string): Promise<boolean> {\n const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;\n try {\n await this.s3.send(new HeadObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n } catch (error: any) {\n if (error.name === 'NotFound') {\n return false;\n }\n throw error;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const { PutObjectCommand } = AWSS3StorageProvider.awsS3Module;\n let body: any;\n if (typeof content === 'string' || content instanceof Buffer) {\n body = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n body = JSON.stringify(content);\n } else if (content instanceof Stream) {\n body = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.config.bucket,\n Key: path,\n Body: body,\n })\n );\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const body = await this.streamToString(data.Body as Stream);\n return JSON.parse(body);\n }\n\n async getString(path: string): Promise<string> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return await this.streamToString(data.Body as Stream);\n }\n\n async delete(path: string): Promise<boolean> {\n const { DeleteObjectCommand } = AWSS3StorageProvider.awsS3Module;\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path }));\n return true;\n }\n\n private async streamToString(stream: Stream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Uint8Array[] = [];\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n stream.on('error', reject);\n });\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n const chunks: Uint8Array[] = [];\n const stream = data.Body as Readable;\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const { GetObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const data = await this.s3.send(\n new GetObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return data.Body as unknown as ReadStream;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const { HeadObjectCommand } = AWSS3StorageProvider.awsS3Module;\n const metadata = await this.s3.send(\n new HeadObjectCommand({ Bucket: this.config.bucket, Key: path })\n );\n return {\n size: metadata.ContentLength || 0,\n mimeType: metadata.ContentType || 'unknown',\n lastModifiedDate: (metadata.LastModified || new Date(0)).toISOString(),\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,6 +8,7 @@ import '@google-cloud/storage';
|
|
|
8
8
|
declare class AzureBlobStorageProvider implements StorageProviderInterface {
|
|
9
9
|
protected config: AzureBlobStorageProviderConfig;
|
|
10
10
|
private blobServiceClient;
|
|
11
|
+
private static azureModule;
|
|
11
12
|
constructor(config: AzureBlobStorageProviderConfig);
|
|
12
13
|
exists(path: string): Promise<boolean>;
|
|
13
14
|
put(path: string, content: string | object | Stream | Buffer): Promise<boolean>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob";
|
|
4
3
|
import Stream from "stream";
|
|
5
4
|
import * as mime from "mime-types";
|
|
5
|
+
import { loadPackage } from "../helper.mjs";
|
|
6
6
|
class AzureBlobStorageProvider {
|
|
7
7
|
constructor(config) {
|
|
8
8
|
this.config = config;
|
|
9
|
+
if (!AzureBlobStorageProvider.azureModule) {
|
|
10
|
+
AzureBlobStorageProvider.azureModule = loadPackage("@azure/storage-blob");
|
|
11
|
+
}
|
|
12
|
+
const { BlobServiceClient, StorageSharedKeyCredential } = AzureBlobStorageProvider.azureModule;
|
|
9
13
|
const { accountName, accountKey, sasToken } = config;
|
|
10
14
|
if (accountKey) {
|
|
11
15
|
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
|
|
@@ -25,6 +29,7 @@ class AzureBlobStorageProvider {
|
|
|
25
29
|
__name(this, "AzureBlobStorageProvider");
|
|
26
30
|
}
|
|
27
31
|
blobServiceClient;
|
|
32
|
+
static azureModule;
|
|
28
33
|
async exists(path) {
|
|
29
34
|
try {
|
|
30
35
|
const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/AzureBlobStorageProvider.mts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/AzureBlobStorageProvider.mts"],"sourcesContent":["import type * as AzureStorageBlob from '@azure/storage-blob';\nimport { Metadata, AzureBlobStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class AzureBlobStorageProvider implements StorageProviderInterface {\n private blobServiceClient!: AzureStorageBlob.BlobServiceClient;\n private static azureModule: typeof AzureStorageBlob;\n\n constructor(protected config: AzureBlobStorageProviderConfig) {\n if (!AzureBlobStorageProvider.azureModule) {\n AzureBlobStorageProvider.azureModule = loadPackage('@azure/storage-blob');\n }\n const { BlobServiceClient, StorageSharedKeyCredential } = AzureBlobStorageProvider.azureModule;\n const { accountName, accountKey, sasToken } = config;\n\n if (accountKey) {\n const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net`,\n sharedKeyCredential\n );\n } else if (sasToken) {\n this.blobServiceClient = new BlobServiceClient(\n `https://${accountName}.blob.core.windows.net?${sasToken}`\n );\n } else {\n throw new Error('Either accountKey or sasToken is required for Azure Blob Storage');\n }\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n return await blobClient.exists();\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blockBlobClient = containerClient.getBlockBlobClient(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await blockBlobClient.uploadStream(data as Readable);\n } else {\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n await blockBlobClient.upload(buffer, buffer.length);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return await this.streamToBuffer(downloadResponse.readableStreamBody);\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const downloadResponse = await blobClient.download();\n\n if (!downloadResponse.readableStreamBody) {\n throw new Error('Failed to download blob');\n }\n\n return downloadResponse.readableStreamBody as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n await blobClient.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const containerClient = this.blobServiceClient.getContainerClient(this.config.containerName);\n const blobClient = containerClient.getBlobClient(path);\n const properties = await blobClient.getProperties();\n\n return {\n size: properties.contentLength || 0,\n mimeType: properties.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: properties.lastModified?.toISOString() || new Date(0).toISOString(),\n };\n }\n\n private async streamToBuffer(readableStream: NodeJS.ReadableStream): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n readableStream.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n readableStream.on('end', () => {\n resolve(Buffer.concat(chunks));\n });\n readableStream.on('error', reject);\n });\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,6 +7,7 @@ import '@google-cloud/storage';
|
|
|
7
7
|
|
|
8
8
|
declare class FTPStorageProvider implements StorageProviderInterface {
|
|
9
9
|
private config;
|
|
10
|
+
private static ftpModule;
|
|
10
11
|
constructor(config: FTPStorageProviderConfig);
|
|
11
12
|
private getClient;
|
|
12
13
|
exists(path: string): Promise<boolean>;
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import { Client as FTPClient } from "basic-ftp";
|
|
4
3
|
import Stream, { Readable, PassThrough } from "stream";
|
|
5
4
|
import * as mime from "mime-types";
|
|
5
|
+
import { loadPackage } from "../helper.mjs";
|
|
6
6
|
class FTPStorageProvider {
|
|
7
7
|
constructor(config) {
|
|
8
8
|
this.config = config;
|
|
9
|
+
if (!FTPStorageProvider.ftpModule) {
|
|
10
|
+
FTPStorageProvider.ftpModule = loadPackage("basic-ftp");
|
|
11
|
+
}
|
|
9
12
|
}
|
|
10
13
|
static {
|
|
11
14
|
__name(this, "FTPStorageProvider");
|
|
12
15
|
}
|
|
16
|
+
static ftpModule;
|
|
13
17
|
async getClient() {
|
|
14
|
-
const
|
|
18
|
+
const { Client } = FTPStorageProvider.ftpModule;
|
|
19
|
+
const client = new Client();
|
|
15
20
|
await client.access({
|
|
16
21
|
host: this.config.host,
|
|
17
22
|
port: this.config.port || 21,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/FTPStorageProvider.mts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/FTPStorageProvider.mts"],"sourcesContent":["import type * as BasicFtp from 'basic-ftp';\nimport { Metadata, FTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class FTPStorageProvider implements StorageProviderInterface {\n private static ftpModule: typeof BasicFtp;\n\n constructor(private config: FTPStorageProviderConfig) {\n if (!FTPStorageProvider.ftpModule) {\n FTPStorageProvider.ftpModule = loadPackage('basic-ftp');\n }\n }\n\n private async getClient(): Promise<BasicFtp.Client> {\n const { Client } = FTPStorageProvider.ftpModule;\n const client = new Client();\n await client.access({\n host: this.config.host,\n port: this.config.port || 21,\n user: this.config.user || 'anonymous',\n password: this.config.password || '',\n secure: this.config.secure || false,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.size(path);\n return true;\n } catch (error) {\n return false;\n } finally {\n client.close();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let stream: Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n const readable = new Readable();\n readable.push(typeof content === 'string' ? Buffer.from(content) : content);\n readable.push(null);\n stream = readable;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n const readable = new Readable();\n readable.push(Buffer.from(JSON.stringify(content)));\n readable.push(null);\n stream = readable;\n } else if (content instanceof Stream) {\n stream = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.uploadFrom(stream as Readable, path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const chunks: Buffer[] = [];\n const writable = new PassThrough();\n\n writable.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n\n await client.downloadTo(writable, path);\n\n return Buffer.concat(chunks);\n } finally {\n client.close();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Download to stream and close client when done\n client\n .downloadTo(passThrough, path)\n .then(() => client.close())\n .catch((error) => {\n client.close();\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n try {\n client.close();\n } catch {\n // Ignore errors if already closed\n }\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.remove(path);\n return true;\n } finally {\n client.close();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const size = await client.size(path);\n const lastMod = await client.lastMod(path);\n\n return {\n size: size,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: lastMod?.toISOString() || new Date(0).toISOString(),\n };\n } finally {\n client.close();\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,6 +8,7 @@ import '@google-cloud/storage';
|
|
|
8
8
|
declare class GCPStorageProvider implements StorageProviderInterface {
|
|
9
9
|
protected config: GCPStorageProviderConfig;
|
|
10
10
|
private storage;
|
|
11
|
+
private static gcpModule;
|
|
11
12
|
constructor(config: GCPStorageProviderConfig);
|
|
12
13
|
exists(path: string): Promise<boolean>;
|
|
13
14
|
put(path: string, content: string | object | Stream | Buffer): Promise<boolean>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import { Storage as GCPStorage } from "@google-cloud/storage";
|
|
4
3
|
import Stream from "stream";
|
|
5
4
|
import * as mime from "mime-types";
|
|
5
|
+
import { loadPackage } from "../helper.mjs";
|
|
6
6
|
class GCPStorageProvider {
|
|
7
7
|
constructor(config) {
|
|
8
8
|
this.config = config;
|
|
9
|
+
if (!GCPStorageProvider.gcpModule) {
|
|
10
|
+
GCPStorageProvider.gcpModule = loadPackage("@google-cloud/storage");
|
|
11
|
+
}
|
|
12
|
+
const { Storage: GCPStorage } = GCPStorageProvider.gcpModule;
|
|
9
13
|
const { bucket, ...gcpOptions } = config;
|
|
10
14
|
this.storage = new GCPStorage(gcpOptions);
|
|
11
15
|
}
|
|
@@ -13,6 +17,7 @@ class GCPStorageProvider {
|
|
|
13
17
|
__name(this, "GCPStorageProvider");
|
|
14
18
|
}
|
|
15
19
|
storage;
|
|
20
|
+
static gcpModule;
|
|
16
21
|
async exists(path) {
|
|
17
22
|
try {
|
|
18
23
|
const file = this.storage.bucket(this.config.bucket).file(path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/GCPStorageProvider.mts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/GCPStorageProvider.mts"],"sourcesContent":["import type * as GCPStorageModule from '@google-cloud/storage';\nimport { Metadata, GCPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class GCPStorageProvider implements StorageProviderInterface {\n private storage!: GCPStorageModule.Storage;\n private static gcpModule: typeof GCPStorageModule;\n\n constructor(protected config: GCPStorageProviderConfig) {\n if (!GCPStorageProvider.gcpModule) {\n GCPStorageProvider.gcpModule = loadPackage('@google-cloud/storage');\n }\n const { Storage: GCPStorage } = GCPStorageProvider.gcpModule;\n const { bucket, ...gcpOptions } = config;\n this.storage = new GCPStorage(gcpOptions);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [exists] = await file.exists();\n return exists;\n } catch (error) {\n return false;\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n\n let data: string | Buffer | Stream;\n if (typeof content === 'string' || content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = JSON.stringify(content);\n } else if (content instanceof Stream) {\n data = content;\n } else {\n throw new Error('Unsupported content type');\n }\n\n if (data instanceof Stream) {\n await new Promise<void>((resolve, reject) => {\n data\n .pipe(file.createWriteStream())\n .on('finish', () => resolve())\n .on('error', reject);\n });\n } else {\n await file.save(data);\n }\n\n return true;\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [content] = await file.download();\n return content;\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n return file.createReadStream() as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n await file.delete();\n return true;\n }\n\n async metadata(path: string): Promise<Metadata> {\n const file = this.storage.bucket(this.config.bucket).file(path);\n const [metadata] = await file.getMetadata();\n\n return {\n size: typeof metadata.size === 'number' ? metadata.size : parseInt(metadata.size || '0', 10),\n mimeType: metadata.contentType || mime.lookup(path) || 'unknown',\n lastModifiedDate: metadata.updated || new Date(0).toISOString(),\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,6 +7,7 @@ import '@google-cloud/storage';
|
|
|
7
7
|
|
|
8
8
|
declare class SFTPStorageProvider implements StorageProviderInterface {
|
|
9
9
|
private config;
|
|
10
|
+
private static sftpModule;
|
|
10
11
|
constructor(config: SFTPStorageProviderConfig);
|
|
11
12
|
private getClient;
|
|
12
13
|
exists(path: string): Promise<boolean>;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import SFTPClient from "ssh2-sftp-client";
|
|
4
3
|
import Stream, { Readable, PassThrough } from "stream";
|
|
5
4
|
import * as mime from "mime-types";
|
|
5
|
+
import { loadPackage } from "../helper.mjs";
|
|
6
6
|
class SFTPStorageProvider {
|
|
7
7
|
constructor(config) {
|
|
8
8
|
this.config = config;
|
|
9
|
+
if (!SFTPStorageProvider.sftpModule) {
|
|
10
|
+
SFTPStorageProvider.sftpModule = loadPackage("ssh2-sftp-client");
|
|
11
|
+
}
|
|
9
12
|
}
|
|
10
13
|
static {
|
|
11
14
|
__name(this, "SFTPStorageProvider");
|
|
12
15
|
}
|
|
16
|
+
static sftpModule;
|
|
13
17
|
async getClient() {
|
|
14
|
-
const client = new
|
|
18
|
+
const client = new SFTPStorageProvider.sftpModule();
|
|
15
19
|
await client.connect({
|
|
16
20
|
host: this.config.host,
|
|
17
21
|
port: this.config.port || 22,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/SFTPStorageProvider.mts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/SFTPStorageProvider.mts"],"sourcesContent":["import type SFTPClientType from 'ssh2-sftp-client';\nimport { Metadata, SFTPStorageProviderConfig } from '../types.mjs';\nimport { StorageProviderInterface } from '../StorageProviderInterface.mjs';\nimport { ReadStream } from 'fs';\nimport Stream, { Readable, PassThrough } from 'stream';\nimport * as mime from 'mime-types';\nimport { loadPackage } from '../helper.mjs';\n\nexport class SFTPStorageProvider implements StorageProviderInterface {\n private static sftpModule: typeof SFTPClientType;\n\n constructor(private config: SFTPStorageProviderConfig) {\n if (!SFTPStorageProvider.sftpModule) {\n SFTPStorageProvider.sftpModule = loadPackage('ssh2-sftp-client');\n }\n }\n\n private async getClient(): Promise<SFTPClientType> {\n const client = new SFTPStorageProvider.sftpModule();\n await client.connect({\n host: this.config.host,\n port: this.config.port || 22,\n username: this.config.username,\n password: this.config.password,\n privateKey: this.config.privateKey,\n passphrase: this.config.passphrase,\n });\n return client;\n }\n\n async exists(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n const result = await client.exists(path);\n return result !== false;\n } catch (error) {\n return false;\n } finally {\n await client.end();\n }\n }\n\n async put(path: string, content: string | object | Stream | Buffer): Promise<boolean> {\n const client = await this.getClient();\n try {\n let data: string | Buffer | Readable;\n if (typeof content === 'string') {\n data = content;\n } else if (content instanceof Buffer) {\n data = content;\n } else if (typeof content === 'object' && !(content instanceof Stream)) {\n data = Buffer.from(JSON.stringify(content));\n } else if (content instanceof Stream) {\n data = content as Readable;\n } else {\n throw new Error('Unsupported content type');\n }\n\n await client.put(data, path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async getJson(path: string): Promise<object> {\n const data = await this.getString(path);\n return JSON.parse(data);\n }\n\n async getString(path: string): Promise<string> {\n const buffer = await this.getBuffer(path);\n return buffer.toString('utf-8');\n }\n\n async getBuffer(path: string): Promise<Buffer> {\n const client = await this.getClient();\n try {\n const buffer = await client.get(path);\n return buffer as Buffer;\n } finally {\n await client.end();\n }\n }\n\n async getStream(path: string): Promise<ReadStream> {\n const client = await this.getClient();\n const passThrough = new PassThrough();\n\n // Get the file as a stream and close client when done\n client\n .get(path)\n .then((data) => {\n if (data instanceof Buffer) {\n const readable = new Readable();\n readable.push(data);\n readable.push(null);\n readable.pipe(passThrough);\n } else if (data instanceof Stream) {\n (data as Stream).pipe(passThrough);\n }\n return client.end();\n })\n .catch((error) => {\n client.end().catch(() => {\n // Ignore errors when closing client during error handling\n });\n passThrough.destroy(error);\n });\n\n // Ensure client is closed when stream is destroyed\n passThrough.on('close', () => {\n client.end().catch(() => {\n // Ignore errors if already closed\n });\n });\n\n return passThrough as unknown as ReadStream;\n }\n\n async delete(path: string): Promise<boolean> {\n const client = await this.getClient();\n try {\n await client.delete(path);\n return true;\n } finally {\n await client.end();\n }\n }\n\n async metadata(path: string): Promise<Metadata> {\n const client = await this.getClient();\n try {\n const stats = await client.stat(path);\n\n return {\n size: stats.size || 0,\n mimeType: mime.lookup(path) || 'unknown',\n lastModifiedDate: new Date((stats.modifyTime || 0) * 1000).toISOString(),\n };\n } finally {\n await client.end();\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devbro/neko-storage",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "abstracted file storage implementation",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.mjs",
|
|
@@ -28,8 +28,13 @@
|
|
|
28
28
|
"author": "Farzad Meow Khalafi",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"devDependencies": {
|
|
31
|
+
"@aws-sdk/client-s3": "^3.817.0",
|
|
32
|
+
"@azure/storage-blob": "^12.29.1",
|
|
33
|
+
"@google-cloud/storage": "^7.17.3",
|
|
34
|
+
"basic-ftp": "^5.0.5",
|
|
35
|
+
"ssh2-sftp-client": "^12.0.1",
|
|
31
36
|
"@types/mime-types": "^2.1.4",
|
|
32
|
-
"@types/node": "^
|
|
37
|
+
"@types/node": "^24.1.0",
|
|
33
38
|
"@types/ssh2-sftp-client": "^9.0.5",
|
|
34
39
|
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
|
35
40
|
"@typescript-eslint/parser": "^7.1.1",
|
|
@@ -37,17 +42,36 @@
|
|
|
37
42
|
"husky": "^9.1.7",
|
|
38
43
|
"prettier": "^3.5.3",
|
|
39
44
|
"tsup": "^8.0.2",
|
|
40
|
-
"typescript": "^5.
|
|
45
|
+
"typescript": "^5.9.3"
|
|
41
46
|
},
|
|
42
47
|
"dependencies": {
|
|
48
|
+
"@devbro/neko-helper": "0.1.*",
|
|
49
|
+
"mime-types": "^3.0.1"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
43
52
|
"@aws-sdk/client-s3": "^3.817.0",
|
|
44
53
|
"@azure/storage-blob": "^12.29.1",
|
|
45
|
-
"@devbro/neko-helper": "0.1.*",
|
|
46
54
|
"@google-cloud/storage": "^7.17.3",
|
|
47
55
|
"basic-ftp": "^5.0.5",
|
|
48
|
-
"mime-types": "^3.0.1",
|
|
49
56
|
"ssh2-sftp-client": "^12.0.1"
|
|
50
57
|
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"@aws-sdk/client-s3": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"@azure/storage-blob": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"@google-cloud/storage": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"basic-ftp": {
|
|
69
|
+
"optional": true
|
|
70
|
+
},
|
|
71
|
+
"ssh2-sftp-client": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
51
75
|
"directories": {
|
|
52
76
|
"doc": "docs",
|
|
53
77
|
"test": "tests"
|