express-storage 1.0.0
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/LICENSE +21 -0
- package/README.md +490 -0
- package/dist/drivers/base.driver.d.ts +69 -0
- package/dist/drivers/base.driver.d.ts.map +1 -0
- package/dist/drivers/base.driver.js +161 -0
- package/dist/drivers/base.driver.js.map +1 -0
- package/dist/drivers/gcs.driver.d.ts +39 -0
- package/dist/drivers/gcs.driver.d.ts.map +1 -0
- package/dist/drivers/gcs.driver.js +126 -0
- package/dist/drivers/gcs.driver.js.map +1 -0
- package/dist/drivers/local.driver.d.ts +30 -0
- package/dist/drivers/local.driver.d.ts.map +1 -0
- package/dist/drivers/local.driver.js +102 -0
- package/dist/drivers/local.driver.js.map +1 -0
- package/dist/drivers/oci.driver.d.ts +37 -0
- package/dist/drivers/oci.driver.d.ts.map +1 -0
- package/dist/drivers/oci.driver.js +84 -0
- package/dist/drivers/oci.driver.js.map +1 -0
- package/dist/drivers/s3.driver.d.ts +38 -0
- package/dist/drivers/s3.driver.d.ts.map +1 -0
- package/dist/drivers/s3.driver.js +135 -0
- package/dist/drivers/s3.driver.js.map +1 -0
- package/dist/factory/driver.factory.d.ts +56 -0
- package/dist/factory/driver.factory.d.ts.map +1 -0
- package/dist/factory/driver.factory.js +117 -0
- package/dist/factory/driver.factory.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/storage-manager.d.ts +75 -0
- package/dist/storage-manager.d.ts.map +1 -0
- package/dist/storage-manager.js +144 -0
- package/dist/storage-manager.js.map +1 -0
- package/dist/types/storage.types.d.ts +70 -0
- package/dist/types/storage.types.d.ts.map +1 -0
- package/dist/types/storage.types.js +2 -0
- package/dist/types/storage.types.js.map +1 -0
- package/dist/utils/config.utils.d.ts +21 -0
- package/dist/utils/config.utils.d.ts.map +1 -0
- package/dist/utils/config.utils.js +128 -0
- package/dist/utils/config.utils.js.map +1 -0
- package/dist/utils/file.utils.d.ts +45 -0
- package/dist/utils/file.utils.d.ts.map +1 -0
- package/dist/utils/file.utils.js +95 -0
- package/dist/utils/file.utils.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { generateUniqueFileName } from '../utils/file.utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for all storage drivers
|
|
4
|
+
*/
|
|
5
|
+
export class BaseStorageDriver {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Upload multiple files
|
|
11
|
+
*/
|
|
12
|
+
async uploadMultiple(files) {
|
|
13
|
+
const results = [];
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
try {
|
|
16
|
+
const result = await this.upload(file);
|
|
17
|
+
results.push(result);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
results.push({
|
|
21
|
+
success: false,
|
|
22
|
+
error: error instanceof Error ? error.message : 'Upload failed',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return results;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Generate multiple upload URLs
|
|
30
|
+
*/
|
|
31
|
+
async generateMultipleUploadUrls(fileNames) {
|
|
32
|
+
const results = [];
|
|
33
|
+
for (const fileName of fileNames) {
|
|
34
|
+
try {
|
|
35
|
+
const result = await this.generateUploadUrl(fileName);
|
|
36
|
+
results.push(result);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
results.push({
|
|
40
|
+
success: false,
|
|
41
|
+
error: error instanceof Error ? error.message : 'Failed to generate upload URL',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate multiple view URLs
|
|
49
|
+
*/
|
|
50
|
+
async generateMultipleViewUrls(fileNames) {
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const fileName of fileNames) {
|
|
53
|
+
try {
|
|
54
|
+
const result = await this.generateViewUrl(fileName);
|
|
55
|
+
results.push(result);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
results.push({
|
|
59
|
+
success: false,
|
|
60
|
+
error: error instanceof Error ? error.message : 'Failed to generate view URL',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return results;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Delete multiple files
|
|
68
|
+
*/
|
|
69
|
+
async deleteMultiple(fileNames) {
|
|
70
|
+
const results = [];
|
|
71
|
+
for (const fileName of fileNames) {
|
|
72
|
+
try {
|
|
73
|
+
const result = await this.delete(fileName);
|
|
74
|
+
results.push(result);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
results.push(false);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return results;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Generate unique filename with timestamp
|
|
84
|
+
*/
|
|
85
|
+
generateFileName(originalName) {
|
|
86
|
+
return generateUniqueFileName(originalName);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Create success result
|
|
90
|
+
*/
|
|
91
|
+
createSuccessResult(fileName, fileUrl) {
|
|
92
|
+
const result = {
|
|
93
|
+
success: true,
|
|
94
|
+
fileName,
|
|
95
|
+
};
|
|
96
|
+
if (fileUrl) {
|
|
97
|
+
result.fileUrl = fileUrl;
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create error result
|
|
103
|
+
*/
|
|
104
|
+
createErrorResult(error) {
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Create presigned success result
|
|
112
|
+
*/
|
|
113
|
+
createPresignedSuccessResult(uploadUrl, viewUrl) {
|
|
114
|
+
const result = {
|
|
115
|
+
success: true,
|
|
116
|
+
};
|
|
117
|
+
if (uploadUrl) {
|
|
118
|
+
result.uploadUrl = uploadUrl;
|
|
119
|
+
}
|
|
120
|
+
if (viewUrl) {
|
|
121
|
+
result.viewUrl = viewUrl;
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create presigned error result
|
|
127
|
+
*/
|
|
128
|
+
createPresignedErrorResult(error) {
|
|
129
|
+
return {
|
|
130
|
+
success: false,
|
|
131
|
+
error,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validate file before upload
|
|
136
|
+
*/
|
|
137
|
+
validateFile(file) {
|
|
138
|
+
const errors = [];
|
|
139
|
+
if (!file) {
|
|
140
|
+
errors.push('No file provided');
|
|
141
|
+
return errors;
|
|
142
|
+
}
|
|
143
|
+
if (!file.originalname) {
|
|
144
|
+
errors.push('File must have an original name');
|
|
145
|
+
}
|
|
146
|
+
if (!file.mimetype) {
|
|
147
|
+
errors.push('File must have a MIME type');
|
|
148
|
+
}
|
|
149
|
+
if (!file.buffer || file.buffer.length === 0) {
|
|
150
|
+
errors.push('File buffer is empty');
|
|
151
|
+
}
|
|
152
|
+
return errors;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get presigned URL expiry time
|
|
156
|
+
*/
|
|
157
|
+
getPresignedUrlExpiry() {
|
|
158
|
+
return this.config.presignedUrlExpiry || 600; // Default 10 minutes
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=base.driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.driver.js","sourceRoot":"","sources":["../../src/drivers/base.driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
2
|
+
import { FileUploadResult, PresignedUrlResult } from '../types/storage.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Google Cloud Storage driver
|
|
5
|
+
*/
|
|
6
|
+
export declare class GCSStorageDriver extends BaseStorageDriver {
|
|
7
|
+
private storage;
|
|
8
|
+
private bucket;
|
|
9
|
+
private bucketName;
|
|
10
|
+
private projectId;
|
|
11
|
+
constructor(config: any);
|
|
12
|
+
/**
|
|
13
|
+
* Upload file to GCS
|
|
14
|
+
*/
|
|
15
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Generate presigned upload URL
|
|
18
|
+
*/
|
|
19
|
+
generateUploadUrl(fileName: string): Promise<PresignedUrlResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Generate presigned view URL
|
|
22
|
+
*/
|
|
23
|
+
generateViewUrl(fileName: string): Promise<PresignedUrlResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Delete file from GCS
|
|
26
|
+
*/
|
|
27
|
+
delete(fileName: string): Promise<boolean>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Google Cloud Storage presigned driver
|
|
31
|
+
*/
|
|
32
|
+
export declare class GCSPresignedStorageDriver extends GCSStorageDriver {
|
|
33
|
+
constructor(config: any);
|
|
34
|
+
/**
|
|
35
|
+
* Override upload to return presigned URL instead of direct upload
|
|
36
|
+
*/
|
|
37
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=gcs.driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.driver.d.ts","sourceRoot":"","sources":["../../src/drivers/gcs.driver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEjF;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACrD,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,GAAG;IAevB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgClE;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAmBtE;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkBpE;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CASjD;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,gBAAgB;gBACjD,MAAM,EAAE,GAAG;IAIvB;;OAEG;IACY,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyB5E"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Storage } from '@google-cloud/storage';
|
|
2
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
3
|
+
/**
|
|
4
|
+
* Google Cloud Storage driver
|
|
5
|
+
*/
|
|
6
|
+
export class GCSStorageDriver extends BaseStorageDriver {
|
|
7
|
+
constructor(config) {
|
|
8
|
+
super(config);
|
|
9
|
+
this.bucketName = config.bucketName;
|
|
10
|
+
this.projectId = config.gcsProjectId;
|
|
11
|
+
// Initialize GCS client
|
|
12
|
+
this.storage = new Storage({
|
|
13
|
+
projectId: this.projectId,
|
|
14
|
+
keyFilename: config.gcsCredentials,
|
|
15
|
+
});
|
|
16
|
+
this.bucket = this.storage.bucket(this.bucketName);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Upload file to GCS
|
|
20
|
+
*/
|
|
21
|
+
async upload(file) {
|
|
22
|
+
try {
|
|
23
|
+
// Validate file
|
|
24
|
+
const validationErrors = this.validateFile(file);
|
|
25
|
+
if (validationErrors.length > 0) {
|
|
26
|
+
return this.createErrorResult(validationErrors.join(', '));
|
|
27
|
+
}
|
|
28
|
+
// Generate unique filename
|
|
29
|
+
const fileName = this.generateFileName(file.originalname);
|
|
30
|
+
// Create file reference
|
|
31
|
+
const gcsFile = this.bucket.file(fileName);
|
|
32
|
+
// Upload file
|
|
33
|
+
await gcsFile.save(file.buffer, {
|
|
34
|
+
metadata: {
|
|
35
|
+
contentType: file.mimetype,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
// Generate file URL
|
|
39
|
+
const fileUrl = `https://storage.googleapis.com/${this.bucketName}/${fileName}`;
|
|
40
|
+
return this.createSuccessResult(fileName, fileUrl);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to upload file to GCS');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Generate presigned upload URL
|
|
48
|
+
*/
|
|
49
|
+
async generateUploadUrl(fileName) {
|
|
50
|
+
try {
|
|
51
|
+
const gcsFile = this.bucket.file(fileName);
|
|
52
|
+
const [uploadUrl] = await gcsFile.getSignedUrl({
|
|
53
|
+
version: 'v4',
|
|
54
|
+
action: 'write',
|
|
55
|
+
expires: Date.now() + (this.getPresignedUrlExpiry() * 1000),
|
|
56
|
+
contentType: 'application/octet-stream',
|
|
57
|
+
});
|
|
58
|
+
return this.createPresignedSuccessResult(uploadUrl);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return this.createPresignedErrorResult(error instanceof Error ? error.message : 'Failed to generate upload URL');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate presigned view URL
|
|
66
|
+
*/
|
|
67
|
+
async generateViewUrl(fileName) {
|
|
68
|
+
try {
|
|
69
|
+
const gcsFile = this.bucket.file(fileName);
|
|
70
|
+
const [viewUrl] = await gcsFile.getSignedUrl({
|
|
71
|
+
version: 'v4',
|
|
72
|
+
action: 'read',
|
|
73
|
+
expires: Date.now() + (this.getPresignedUrlExpiry() * 1000),
|
|
74
|
+
});
|
|
75
|
+
return this.createPresignedSuccessResult(undefined, viewUrl);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return this.createPresignedErrorResult(error instanceof Error ? error.message : 'Failed to generate view URL');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Delete file from GCS
|
|
83
|
+
*/
|
|
84
|
+
async delete(fileName) {
|
|
85
|
+
try {
|
|
86
|
+
const gcsFile = this.bucket.file(fileName);
|
|
87
|
+
await gcsFile.delete();
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Google Cloud Storage presigned driver
|
|
97
|
+
*/
|
|
98
|
+
export class GCSPresignedStorageDriver extends GCSStorageDriver {
|
|
99
|
+
constructor(config) {
|
|
100
|
+
super(config);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Override upload to return presigned URL instead of direct upload
|
|
104
|
+
*/
|
|
105
|
+
async upload(file) {
|
|
106
|
+
try {
|
|
107
|
+
// Validate file
|
|
108
|
+
const validationErrors = this.validateFile(file);
|
|
109
|
+
if (validationErrors.length > 0) {
|
|
110
|
+
return this.createErrorResult(validationErrors.join(', '));
|
|
111
|
+
}
|
|
112
|
+
// Generate unique filename
|
|
113
|
+
const fileName = this.generateFileName(file.originalname);
|
|
114
|
+
// Generate presigned upload URL
|
|
115
|
+
const presignedResult = await this.generateUploadUrl(fileName);
|
|
116
|
+
if (!presignedResult.success) {
|
|
117
|
+
return this.createErrorResult(presignedResult.error || 'Failed to generate presigned URL');
|
|
118
|
+
}
|
|
119
|
+
return this.createSuccessResult(fileName, presignedResult.uploadUrl);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to generate presigned URL');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=gcs.driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcs.driver.js","sourceRoot":"","sources":["../../src/drivers/gcs.driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
2
|
+
import { FileUploadResult, PresignedUrlResult } from '../types/storage.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Local storage driver for file system storage
|
|
5
|
+
*/
|
|
6
|
+
export declare class LocalStorageDriver extends BaseStorageDriver {
|
|
7
|
+
private basePath;
|
|
8
|
+
constructor(config: any);
|
|
9
|
+
/**
|
|
10
|
+
* Upload file to local storage
|
|
11
|
+
*/
|
|
12
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Generate upload URL (not supported for local storage)
|
|
15
|
+
*/
|
|
16
|
+
generateUploadUrl(_fileName: string): Promise<PresignedUrlResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Generate view URL (not supported for local storage)
|
|
19
|
+
*/
|
|
20
|
+
generateViewUrl(_fileName: string): Promise<PresignedUrlResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Delete file from local storage
|
|
23
|
+
*/
|
|
24
|
+
delete(fileName: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Find file path by searching through month directories
|
|
27
|
+
*/
|
|
28
|
+
private findFilePath;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=local.driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.driver.d.ts","sourceRoot":"","sources":["../../src/drivers/local.driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGjF;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,iBAAiB;IACvD,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,GAAG;IAKvB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoClE;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMvE;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMrE;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBhD;;OAEG;IACH,OAAO,CAAC,YAAY;CA+BrB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
4
|
+
import { createMonthBasedPath, ensureDirectoryExists, createLocalFileUrl } from '../utils/file.utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Local storage driver for file system storage
|
|
7
|
+
*/
|
|
8
|
+
export class LocalStorageDriver extends BaseStorageDriver {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
super(config);
|
|
11
|
+
this.basePath = config.localPath || 'public/express-storage';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Upload file to local storage
|
|
15
|
+
*/
|
|
16
|
+
async upload(file) {
|
|
17
|
+
try {
|
|
18
|
+
// Validate file
|
|
19
|
+
const validationErrors = this.validateFile(file);
|
|
20
|
+
if (validationErrors.length > 0) {
|
|
21
|
+
return this.createErrorResult(validationErrors.join(', '));
|
|
22
|
+
}
|
|
23
|
+
// Generate unique filename
|
|
24
|
+
const fileName = this.generateFileName(file.originalname);
|
|
25
|
+
// Create month-based directory path
|
|
26
|
+
const monthPath = createMonthBasedPath(this.basePath);
|
|
27
|
+
const fullDirPath = path.resolve(monthPath);
|
|
28
|
+
// Ensure directory exists
|
|
29
|
+
ensureDirectoryExists(fullDirPath);
|
|
30
|
+
// Create full file path
|
|
31
|
+
const filePath = path.join(fullDirPath, fileName);
|
|
32
|
+
// Write file to disk
|
|
33
|
+
fs.writeFileSync(filePath, file.buffer);
|
|
34
|
+
// Generate relative URL
|
|
35
|
+
const relativePath = path.relative('public', filePath);
|
|
36
|
+
const fileUrl = createLocalFileUrl(relativePath);
|
|
37
|
+
return this.createSuccessResult(fileName, fileUrl);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to upload file');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Generate upload URL (not supported for local storage)
|
|
45
|
+
*/
|
|
46
|
+
async generateUploadUrl(_fileName) {
|
|
47
|
+
return this.createPresignedErrorResult('Presigned URLs are not supported for local storage');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generate view URL (not supported for local storage)
|
|
51
|
+
*/
|
|
52
|
+
async generateViewUrl(_fileName) {
|
|
53
|
+
return this.createPresignedErrorResult('Presigned URLs are not supported for local storage');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Delete file from local storage
|
|
57
|
+
*/
|
|
58
|
+
async delete(fileName) {
|
|
59
|
+
try {
|
|
60
|
+
// Find file in month directories
|
|
61
|
+
const filePath = this.findFilePath(fileName);
|
|
62
|
+
if (!filePath) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
// Delete file
|
|
66
|
+
fs.unlinkSync(filePath);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find file path by searching through month directories
|
|
75
|
+
*/
|
|
76
|
+
findFilePath(fileName) {
|
|
77
|
+
const baseDir = path.resolve(this.basePath);
|
|
78
|
+
if (!fs.existsSync(baseDir)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// Search through all subdirectories
|
|
82
|
+
const searchDirectories = (dir) => {
|
|
83
|
+
const items = fs.readdirSync(dir);
|
|
84
|
+
for (const item of items) {
|
|
85
|
+
const itemPath = path.join(dir, item);
|
|
86
|
+
const stat = fs.statSync(itemPath);
|
|
87
|
+
if (stat.isDirectory()) {
|
|
88
|
+
// Recursively search subdirectories
|
|
89
|
+
const found = searchDirectories(itemPath);
|
|
90
|
+
if (found)
|
|
91
|
+
return found;
|
|
92
|
+
}
|
|
93
|
+
else if (item === fileName) {
|
|
94
|
+
return itemPath;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
};
|
|
99
|
+
return searchDirectories(baseDir);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=local.driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.driver.js","sourceRoot":"","sources":["../../src/drivers/local.driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
2
|
+
import { FileUploadResult, PresignedUrlResult } from '../types/storage.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Oracle Cloud Infrastructure storage driver (placeholder implementation)
|
|
5
|
+
*/
|
|
6
|
+
export declare class OCIStorageDriver extends BaseStorageDriver {
|
|
7
|
+
private bucketName;
|
|
8
|
+
private region;
|
|
9
|
+
constructor(config: any);
|
|
10
|
+
/**
|
|
11
|
+
* Upload file to OCI (placeholder)
|
|
12
|
+
*/
|
|
13
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Generate presigned upload URL (placeholder)
|
|
16
|
+
*/
|
|
17
|
+
generateUploadUrl(_fileName: string): Promise<PresignedUrlResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate presigned view URL (placeholder)
|
|
20
|
+
*/
|
|
21
|
+
generateViewUrl(_fileName: string): Promise<PresignedUrlResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Delete file from OCI (placeholder)
|
|
24
|
+
*/
|
|
25
|
+
delete(_fileName: string): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Oracle Cloud Infrastructure presigned driver
|
|
29
|
+
*/
|
|
30
|
+
export declare class OCIPresignedStorageDriver extends OCIStorageDriver {
|
|
31
|
+
constructor(config: any);
|
|
32
|
+
/**
|
|
33
|
+
* Override upload to return presigned URL instead of direct upload
|
|
34
|
+
*/
|
|
35
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=oci.driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oci.driver.d.ts","sourceRoot":"","sources":["../../src/drivers/oci.driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEjF;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,GAAG;IAOvB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsBlE;;OAEG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIvE;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIrE;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAIlD;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,gBAAgB;gBACjD,MAAM,EAAE,GAAG;IAIvB;;OAEG;IACY,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyB5E"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// OCI SDK imports - simplified for now
|
|
2
|
+
// Note: OCI SDK structure may vary, this is a placeholder implementation
|
|
3
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
4
|
+
/**
|
|
5
|
+
* Oracle Cloud Infrastructure storage driver (placeholder implementation)
|
|
6
|
+
*/
|
|
7
|
+
export class OCIStorageDriver extends BaseStorageDriver {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
super(config);
|
|
10
|
+
this.bucketName = config.bucketName;
|
|
11
|
+
this.region = config.ociRegion;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Upload file to OCI (placeholder)
|
|
15
|
+
*/
|
|
16
|
+
async upload(file) {
|
|
17
|
+
try {
|
|
18
|
+
// Validate file
|
|
19
|
+
const validationErrors = this.validateFile(file);
|
|
20
|
+
if (validationErrors.length > 0) {
|
|
21
|
+
return this.createErrorResult(validationErrors.join(', '));
|
|
22
|
+
}
|
|
23
|
+
// Generate unique filename
|
|
24
|
+
const fileName = this.generateFileName(file.originalname);
|
|
25
|
+
// Placeholder implementation
|
|
26
|
+
const fileUrl = `https://objectstorage.${this.region}.oraclecloud.com/b/${this.bucketName}/o/${fileName}`;
|
|
27
|
+
return this.createSuccessResult(fileName, fileUrl);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to upload file to OCI');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generate presigned upload URL (placeholder)
|
|
35
|
+
*/
|
|
36
|
+
async generateUploadUrl(_fileName) {
|
|
37
|
+
return this.createPresignedErrorResult('OCI presigned URLs not implemented yet');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate presigned view URL (placeholder)
|
|
41
|
+
*/
|
|
42
|
+
async generateViewUrl(_fileName) {
|
|
43
|
+
return this.createPresignedErrorResult('OCI presigned URLs not implemented yet');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Delete file from OCI (placeholder)
|
|
47
|
+
*/
|
|
48
|
+
async delete(_fileName) {
|
|
49
|
+
// Placeholder implementation
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Oracle Cloud Infrastructure presigned driver
|
|
55
|
+
*/
|
|
56
|
+
export class OCIPresignedStorageDriver extends OCIStorageDriver {
|
|
57
|
+
constructor(config) {
|
|
58
|
+
super(config);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Override upload to return presigned URL instead of direct upload
|
|
62
|
+
*/
|
|
63
|
+
async upload(file) {
|
|
64
|
+
try {
|
|
65
|
+
// Validate file
|
|
66
|
+
const validationErrors = this.validateFile(file);
|
|
67
|
+
if (validationErrors.length > 0) {
|
|
68
|
+
return this.createErrorResult(validationErrors.join(', '));
|
|
69
|
+
}
|
|
70
|
+
// Generate unique filename
|
|
71
|
+
const fileName = this.generateFileName(file.originalname);
|
|
72
|
+
// Generate presigned upload URL
|
|
73
|
+
const presignedResult = await this.generateUploadUrl(fileName);
|
|
74
|
+
if (!presignedResult.success) {
|
|
75
|
+
return this.createErrorResult(presignedResult.error || 'Failed to generate presigned URL');
|
|
76
|
+
}
|
|
77
|
+
return this.createSuccessResult(fileName, presignedResult.uploadUrl);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to generate presigned URL');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=oci.driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oci.driver.js","sourceRoot":"","sources":["../../src/drivers/oci.driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BaseStorageDriver } from './base.driver.js';
|
|
2
|
+
import { FileUploadResult, PresignedUrlResult } from '../types/storage.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* AWS S3 storage driver
|
|
5
|
+
*/
|
|
6
|
+
export declare class S3StorageDriver extends BaseStorageDriver {
|
|
7
|
+
private s3Client;
|
|
8
|
+
private bucketName;
|
|
9
|
+
private region;
|
|
10
|
+
constructor(config: any);
|
|
11
|
+
/**
|
|
12
|
+
* Upload file to S3
|
|
13
|
+
*/
|
|
14
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate presigned upload URL
|
|
17
|
+
*/
|
|
18
|
+
generateUploadUrl(fileName: string): Promise<PresignedUrlResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Generate presigned view URL
|
|
21
|
+
*/
|
|
22
|
+
generateViewUrl(fileName: string): Promise<PresignedUrlResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Delete file from S3
|
|
25
|
+
*/
|
|
26
|
+
delete(fileName: string): Promise<boolean>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* AWS S3 presigned storage driver
|
|
30
|
+
*/
|
|
31
|
+
export declare class S3PresignedStorageDriver extends S3StorageDriver {
|
|
32
|
+
constructor(config: any);
|
|
33
|
+
/**
|
|
34
|
+
* Override upload to return presigned URL instead of direct upload
|
|
35
|
+
*/
|
|
36
|
+
upload(file: Express.Multer.File): Promise<FileUploadResult>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=s3.driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.driver.d.ts","sourceRoot":"","sources":["../../src/drivers/s3.driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEjF;;GAEG;AACH,qBAAa,eAAgB,SAAQ,iBAAiB;IACpD,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,GAAG;IAevB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkClE;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoBtE;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAmBpE;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAajD;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,eAAe;gBAC/C,MAAM,EAAE,GAAG;IAIvB;;OAEG;IACY,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyB5E"}
|