@aphexcms/storage-s3 0.1.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/dist/index.d.ts +125 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +200 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { StorageAdapter, StorageProvider, StorageConfig, UploadFileData, StorageFile } from '@aphexcms/cms-core/server';
|
|
2
|
+
export interface S3StorageConfig extends StorageConfig {
|
|
3
|
+
options: {
|
|
4
|
+
bucket: string;
|
|
5
|
+
endpoint: string;
|
|
6
|
+
accessKeyId: string;
|
|
7
|
+
secretAccessKey: string;
|
|
8
|
+
region?: string;
|
|
9
|
+
publicUrl?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* S3-Compatible Storage Adapter
|
|
14
|
+
*
|
|
15
|
+
* This adapter uses the S3-compatible API to store files in any S3-compatible storage service:
|
|
16
|
+
* - AWS S3
|
|
17
|
+
* - Cloudflare R2
|
|
18
|
+
* - MinIO
|
|
19
|
+
* - DigitalOcean Spaces
|
|
20
|
+
* - Backblaze B2
|
|
21
|
+
* - Any other S3-compatible service
|
|
22
|
+
*
|
|
23
|
+
* Key design decisions:
|
|
24
|
+
* - Storage keys include the bucket name (e.g., "my-bucket/filename.jpg")
|
|
25
|
+
* - Public URLs can use custom CDN/public URLs without the bucket prefix
|
|
26
|
+
* - This separation allows S3 API to work correctly while serving public URLs cleanly
|
|
27
|
+
*/
|
|
28
|
+
export declare class S3StorageAdapter implements StorageAdapter {
|
|
29
|
+
readonly name = "s3";
|
|
30
|
+
private client;
|
|
31
|
+
private bucket;
|
|
32
|
+
private publicUrl;
|
|
33
|
+
private config;
|
|
34
|
+
constructor(config: S3StorageConfig);
|
|
35
|
+
private generateUniqueFilename;
|
|
36
|
+
store(data: UploadFileData): Promise<StorageFile>;
|
|
37
|
+
delete(path: string): Promise<boolean>;
|
|
38
|
+
exists(path: string): Promise<boolean>;
|
|
39
|
+
getUrl(path: string): string;
|
|
40
|
+
getStorageInfo(): Promise<{
|
|
41
|
+
totalSize: number;
|
|
42
|
+
}>;
|
|
43
|
+
isHealthy(): Promise<boolean>;
|
|
44
|
+
getSignedUrl(path: string): Promise<string>;
|
|
45
|
+
}
|
|
46
|
+
export declare class S3StorageProvider implements StorageProvider {
|
|
47
|
+
name: string;
|
|
48
|
+
createAdapter(config: StorageConfig): StorageAdapter;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Helper function to configure S3-compatible storage
|
|
52
|
+
*
|
|
53
|
+
* Works with any S3-compatible service including AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, etc.
|
|
54
|
+
*
|
|
55
|
+
* @param config - S3 configuration options
|
|
56
|
+
* @param config.bucket - Bucket name
|
|
57
|
+
* @param config.endpoint - S3 endpoint URL
|
|
58
|
+
* @param config.accessKeyId - API access key ID
|
|
59
|
+
* @param config.secretAccessKey - API secret access key
|
|
60
|
+
* @param config.publicUrl - Public URL for file access (optional, uses endpoint if not provided)
|
|
61
|
+
* @param config.region - AWS region (defaults to 'auto')
|
|
62
|
+
* @param config.basePath - Optional path prefix for organizing files
|
|
63
|
+
* @param config.maxFileSize - Maximum file size in bytes (default: 10MB)
|
|
64
|
+
* @param config.allowedTypes - Allowed MIME types (default: common image types)
|
|
65
|
+
*
|
|
66
|
+
* @example Cloudflare R2
|
|
67
|
+
* ```typescript
|
|
68
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
69
|
+
*
|
|
70
|
+
* export default createCMSConfig({
|
|
71
|
+
* storage: s3Storage({
|
|
72
|
+
* bucket: env.R2_BUCKET,
|
|
73
|
+
* endpoint: env.R2_ENDPOINT,
|
|
74
|
+
* accessKeyId: env.R2_ACCESS_KEY_ID,
|
|
75
|
+
* secretAccessKey: env.R2_SECRET_ACCESS_KEY,
|
|
76
|
+
* publicUrl: env.R2_PUBLIC_URL
|
|
77
|
+
* })
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example AWS S3
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
84
|
+
*
|
|
85
|
+
* export default createCMSConfig({
|
|
86
|
+
* storage: s3Storage({
|
|
87
|
+
* bucket: 'my-bucket',
|
|
88
|
+
* endpoint: 'https://s3.us-east-1.amazonaws.com',
|
|
89
|
+
* accessKeyId: env.AWS_ACCESS_KEY_ID,
|
|
90
|
+
* secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
|
|
91
|
+
* region: 'us-east-1'
|
|
92
|
+
* })
|
|
93
|
+
* });
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @example MinIO
|
|
97
|
+
* ```typescript
|
|
98
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
99
|
+
*
|
|
100
|
+
* export default createCMSConfig({
|
|
101
|
+
* storage: s3Storage({
|
|
102
|
+
* bucket: 'my-bucket',
|
|
103
|
+
* endpoint: 'http://localhost:9000',
|
|
104
|
+
* accessKeyId: 'minioadmin',
|
|
105
|
+
* secretAccessKey: 'minioadmin'
|
|
106
|
+
* })
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function s3Storage(config: {
|
|
111
|
+
bucket: string;
|
|
112
|
+
endpoint: string;
|
|
113
|
+
accessKeyId: string;
|
|
114
|
+
secretAccessKey: string;
|
|
115
|
+
region?: string;
|
|
116
|
+
publicUrl?: string;
|
|
117
|
+
basePath?: string;
|
|
118
|
+
baseUrl?: string;
|
|
119
|
+
maxFileSize?: number;
|
|
120
|
+
allowedTypes?: string[];
|
|
121
|
+
}): {
|
|
122
|
+
adapter: S3StorageAdapter;
|
|
123
|
+
disableLocalStorage: boolean;
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD,OAAO,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACtD,QAAQ,CAAC,IAAI,QAAQ;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAA2C;gBAE7C,MAAM,EAAE,eAAe;IA0BnC,OAAO,CAAC,sBAAsB;IAOxB,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IA+BjD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAStB,cAAc,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAKhD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKjD;AAED,qBAAa,iBAAkB,YAAW,eAAe;IACxD,IAAI,SAAQ;IACZ,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;CAGpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;;;EAkBA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { S3mini } from 's3mini';
|
|
2
|
+
/**
|
|
3
|
+
* S3-Compatible Storage Adapter
|
|
4
|
+
*
|
|
5
|
+
* This adapter uses the S3-compatible API to store files in any S3-compatible storage service:
|
|
6
|
+
* - AWS S3
|
|
7
|
+
* - Cloudflare R2
|
|
8
|
+
* - MinIO
|
|
9
|
+
* - DigitalOcean Spaces
|
|
10
|
+
* - Backblaze B2
|
|
11
|
+
* - Any other S3-compatible service
|
|
12
|
+
*
|
|
13
|
+
* Key design decisions:
|
|
14
|
+
* - Storage keys include the bucket name (e.g., "my-bucket/filename.jpg")
|
|
15
|
+
* - Public URLs can use custom CDN/public URLs without the bucket prefix
|
|
16
|
+
* - This separation allows S3 API to work correctly while serving public URLs cleanly
|
|
17
|
+
*/
|
|
18
|
+
export class S3StorageAdapter {
|
|
19
|
+
name = 's3';
|
|
20
|
+
client;
|
|
21
|
+
bucket;
|
|
22
|
+
publicUrl;
|
|
23
|
+
config;
|
|
24
|
+
constructor(config) {
|
|
25
|
+
const { bucket, endpoint, accessKeyId, secretAccessKey, region, publicUrl } = config.options;
|
|
26
|
+
this.client = new S3mini({
|
|
27
|
+
endpoint,
|
|
28
|
+
accessKeyId,
|
|
29
|
+
secretAccessKey,
|
|
30
|
+
region: region || 'auto'
|
|
31
|
+
});
|
|
32
|
+
this.bucket = bucket;
|
|
33
|
+
this.publicUrl = publicUrl || endpoint;
|
|
34
|
+
this.config = {
|
|
35
|
+
basePath: config.basePath ?? '',
|
|
36
|
+
baseUrl: config.baseUrl || this.publicUrl,
|
|
37
|
+
maxFileSize: config.maxFileSize || 10 * 1024 * 1024, // 10MB default
|
|
38
|
+
allowedTypes: config.allowedTypes || [
|
|
39
|
+
'image/jpeg',
|
|
40
|
+
'image/png',
|
|
41
|
+
'image/webp',
|
|
42
|
+
'image/gif',
|
|
43
|
+
'image/avif'
|
|
44
|
+
]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
generateUniqueFilename(originalFilename) {
|
|
48
|
+
const lastDot = originalFilename.lastIndexOf('.');
|
|
49
|
+
const name = lastDot > -1 ? originalFilename.substring(0, lastDot) : originalFilename;
|
|
50
|
+
const ext = lastDot > -1 ? originalFilename.substring(lastDot) : '';
|
|
51
|
+
return `${name}-${Date.now()}-${Math.random().toString(36).substring(2, 8)}${ext}`;
|
|
52
|
+
}
|
|
53
|
+
async store(data) {
|
|
54
|
+
if (!this.config.allowedTypes.includes(data.mimeType)) {
|
|
55
|
+
throw new Error(`Invalid file type: ${data.mimeType}`);
|
|
56
|
+
}
|
|
57
|
+
if (data.size > this.config.maxFileSize) {
|
|
58
|
+
throw new Error(`File too large: ${data.size} bytes`);
|
|
59
|
+
}
|
|
60
|
+
const filename = this.generateUniqueFilename(data.filename);
|
|
61
|
+
// S3 operations require bucket in the key path
|
|
62
|
+
const s3Key = this.config.basePath
|
|
63
|
+
? `${this.bucket}/${this.config.basePath}/${filename}`
|
|
64
|
+
: `${this.bucket}/${filename}`;
|
|
65
|
+
// Public URL path excludes bucket (public URL already points to bucket)
|
|
66
|
+
const publicPath = this.config.basePath ? `${this.config.basePath}/${filename}` : filename;
|
|
67
|
+
// Ensure proper Buffer format for fetch API compatibility
|
|
68
|
+
const buffer = Buffer.isBuffer(data.buffer) ? data.buffer : Buffer.from(data.buffer);
|
|
69
|
+
await this.client.putObject(s3Key, buffer, data.mimeType);
|
|
70
|
+
return {
|
|
71
|
+
path: s3Key,
|
|
72
|
+
url: `${this.config.baseUrl}/${publicPath}`,
|
|
73
|
+
size: data.size
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async delete(path) {
|
|
77
|
+
return await this.client.deleteObject(path);
|
|
78
|
+
}
|
|
79
|
+
async exists(path) {
|
|
80
|
+
try {
|
|
81
|
+
const response = await this.client.objectExists(path);
|
|
82
|
+
return Boolean(response?.valueOf?.() ?? response);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error(`Error checking existence of ${path}:`, error);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
getUrl(path) {
|
|
90
|
+
// Strip bucket prefix from stored path for public URLs
|
|
91
|
+
// Example: "my-bucket/image.jpg" -> "image.jpg"
|
|
92
|
+
const pathWithoutBucket = path.startsWith(`${this.bucket}/`)
|
|
93
|
+
? path.slice(this.bucket.length + 1)
|
|
94
|
+
: path;
|
|
95
|
+
return `${this.config.baseUrl}/${pathWithoutBucket}`;
|
|
96
|
+
}
|
|
97
|
+
async getStorageInfo() {
|
|
98
|
+
// TODO: Implement bucket size calculation
|
|
99
|
+
return { totalSize: 0 };
|
|
100
|
+
}
|
|
101
|
+
async isHealthy() {
|
|
102
|
+
try {
|
|
103
|
+
return await this.client.bucketExists();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async getSignedUrl(path) {
|
|
110
|
+
// TODO: Implement AWS Signature V4 for private file access
|
|
111
|
+
// For now, return public URL
|
|
112
|
+
return this.getUrl(path);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export class S3StorageProvider {
|
|
116
|
+
name = 's3';
|
|
117
|
+
createAdapter(config) {
|
|
118
|
+
return new S3StorageAdapter(config);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Helper function to configure S3-compatible storage
|
|
123
|
+
*
|
|
124
|
+
* Works with any S3-compatible service including AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, etc.
|
|
125
|
+
*
|
|
126
|
+
* @param config - S3 configuration options
|
|
127
|
+
* @param config.bucket - Bucket name
|
|
128
|
+
* @param config.endpoint - S3 endpoint URL
|
|
129
|
+
* @param config.accessKeyId - API access key ID
|
|
130
|
+
* @param config.secretAccessKey - API secret access key
|
|
131
|
+
* @param config.publicUrl - Public URL for file access (optional, uses endpoint if not provided)
|
|
132
|
+
* @param config.region - AWS region (defaults to 'auto')
|
|
133
|
+
* @param config.basePath - Optional path prefix for organizing files
|
|
134
|
+
* @param config.maxFileSize - Maximum file size in bytes (default: 10MB)
|
|
135
|
+
* @param config.allowedTypes - Allowed MIME types (default: common image types)
|
|
136
|
+
*
|
|
137
|
+
* @example Cloudflare R2
|
|
138
|
+
* ```typescript
|
|
139
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
140
|
+
*
|
|
141
|
+
* export default createCMSConfig({
|
|
142
|
+
* storage: s3Storage({
|
|
143
|
+
* bucket: env.R2_BUCKET,
|
|
144
|
+
* endpoint: env.R2_ENDPOINT,
|
|
145
|
+
* accessKeyId: env.R2_ACCESS_KEY_ID,
|
|
146
|
+
* secretAccessKey: env.R2_SECRET_ACCESS_KEY,
|
|
147
|
+
* publicUrl: env.R2_PUBLIC_URL
|
|
148
|
+
* })
|
|
149
|
+
* });
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @example AWS S3
|
|
153
|
+
* ```typescript
|
|
154
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
155
|
+
*
|
|
156
|
+
* export default createCMSConfig({
|
|
157
|
+
* storage: s3Storage({
|
|
158
|
+
* bucket: 'my-bucket',
|
|
159
|
+
* endpoint: 'https://s3.us-east-1.amazonaws.com',
|
|
160
|
+
* accessKeyId: env.AWS_ACCESS_KEY_ID,
|
|
161
|
+
* secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
|
|
162
|
+
* region: 'us-east-1'
|
|
163
|
+
* })
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @example MinIO
|
|
168
|
+
* ```typescript
|
|
169
|
+
* import { s3Storage } from '@aphexcms/storage-s3';
|
|
170
|
+
*
|
|
171
|
+
* export default createCMSConfig({
|
|
172
|
+
* storage: s3Storage({
|
|
173
|
+
* bucket: 'my-bucket',
|
|
174
|
+
* endpoint: 'http://localhost:9000',
|
|
175
|
+
* accessKeyId: 'minioadmin',
|
|
176
|
+
* secretAccessKey: 'minioadmin'
|
|
177
|
+
* })
|
|
178
|
+
* });
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export function s3Storage(config) {
|
|
182
|
+
return {
|
|
183
|
+
adapter: new S3StorageAdapter({
|
|
184
|
+
basePath: config.basePath ?? '',
|
|
185
|
+
baseUrl: config.baseUrl || config.publicUrl || config.endpoint,
|
|
186
|
+
maxFileSize: config.maxFileSize,
|
|
187
|
+
allowedTypes: config.allowedTypes,
|
|
188
|
+
options: {
|
|
189
|
+
bucket: config.bucket,
|
|
190
|
+
endpoint: config.endpoint,
|
|
191
|
+
accessKeyId: config.accessKeyId,
|
|
192
|
+
secretAccessKey: config.secretAccessKey,
|
|
193
|
+
region: config.region,
|
|
194
|
+
publicUrl: config.publicUrl
|
|
195
|
+
}
|
|
196
|
+
}),
|
|
197
|
+
disableLocalStorage: true
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aphexcms/storage-s3",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "S3-compatible storage adapter for Aphex CMS (AWS S3, Cloudflare R2, MinIO, etc.)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"prepublishOnly": "pnpm build"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"s3mini": "^0.5.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@aphexcms/cms-core": "workspace:*"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@aphexcms/cms-core": "workspace:*",
|
|
30
|
+
"tsup": "^8.0.0",
|
|
31
|
+
"typescript": "^5.3.3"
|
|
32
|
+
}
|
|
33
|
+
}
|