refactor/better-suspend-model #3
@@ -1,14 +1,30 @@
|
|||||||
import { StorageProvider } from '@/lib/storage/storage.interface';
|
import { StorageProvider } from '@/lib/storage/storage.interface';
|
||||||
import { TypedResult, wrap } from '@/utils/types/results';
|
import { TypedResult, wrap } from '@/utils/types/results';
|
||||||
import {
|
import { DeleteObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||||
DeleteObjectCommand,
|
|
||||||
HeadObjectCommand,
|
|
||||||
PutObjectCommand,
|
|
||||||
S3Client,
|
|
||||||
} from '@aws-sdk/client-s3';
|
|
||||||
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for S3 storage adapter
|
* Configuration for S3 storage adapter
|
||||||
*/
|
*/
|
||||||
@@ -18,6 +34,7 @@ export const S3StorageConfig = z.object({
|
|||||||
region: z.string(),
|
region: z.string(),
|
||||||
accessKey: z.string(),
|
accessKey: z.string(),
|
||||||
secretKey: z.string(),
|
secretKey: z.string(),
|
||||||
|
publicUrl: z.string().optional(),
|
||||||
});
|
});
|
||||||
export type S3StorageConfig = z.infer<typeof S3StorageConfig>;
|
export type S3StorageConfig = z.infer<typeof S3StorageConfig>;
|
||||||
|
|
||||||
@@ -27,7 +44,7 @@ export type S3StorageConfig = z.infer<typeof S3StorageConfig>;
|
|||||||
*/
|
*/
|
||||||
export class S3StorageAdapter implements StorageProvider {
|
export class S3StorageAdapter implements StorageProvider {
|
||||||
private readonly s3Client: S3Client;
|
private readonly s3Client: S3Client;
|
||||||
private readonly endpoint: string;
|
private readonly publicUrl: string;
|
||||||
private readonly bucketName: string;
|
private readonly bucketName: string;
|
||||||
|
|
||||||
readonly get: (
|
readonly get: (
|
||||||
@@ -44,8 +61,9 @@ export class S3StorageAdapter implements StorageProvider {
|
|||||||
) => Promise<TypedResult<void>>;
|
) => Promise<TypedResult<void>>;
|
||||||
|
|
||||||
constructor(config: S3StorageConfig, s3Client?: S3Client) {
|
constructor(config: S3StorageConfig, s3Client?: S3Client) {
|
||||||
this.endpoint = config.endpoint;
|
|
||||||
this.bucketName = config.bucket;
|
this.bucketName = config.bucket;
|
||||||
|
this.publicUrl = config.publicUrl || config.endpoint;
|
||||||
|
|
||||||
this.s3Client =
|
this.s3Client =
|
||||||
s3Client ||
|
s3Client ||
|
||||||
new S3Client({
|
new S3Client({
|
||||||
@@ -56,6 +74,8 @@ export class S3StorageAdapter implements StorageProvider {
|
|||||||
accessKeyId: config.accessKey,
|
accessKeyId: config.accessKey,
|
||||||
secretAccessKey: config.secretKey,
|
secretAccessKey: config.secretKey,
|
||||||
},
|
},
|
||||||
|
requestChecksumCalculation: 'WHEN_REQUIRED',
|
||||||
|
responseChecksumValidation: 'WHEN_REQUIRED',
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get = wrap(this._get.bind(this));
|
this.get = wrap(this._get.bind(this));
|
||||||
@@ -65,7 +85,7 @@ export class S3StorageAdapter implements StorageProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _get(key: string): Promise<string> {
|
private async _get(key: string): Promise<string> {
|
||||||
return `${this.endpoint}/${this.bucketName}/${key}`;
|
return `${this.publicUrl}/${key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _put(key: string, contentType: string): Promise<string> {
|
private async _put(key: string, contentType: string): Promise<string> {
|
||||||
@@ -109,6 +129,7 @@ export const new_s3_storage_adapter = (): S3StorageAdapter => {
|
|||||||
region: process.env.S3_REGION,
|
region: process.env.S3_REGION,
|
||||||
accessKey: process.env.S3_ACCESS_KEY,
|
accessKey: process.env.S3_ACCESS_KEY,
|
||||||
secretKey: process.env.S3_SECRET_KEY,
|
secretKey: process.env.S3_SECRET_KEY,
|
||||||
|
publicUrl: process.env.S3_PUBLIC_URL,
|
||||||
});
|
});
|
||||||
return new S3StorageAdapter(config);
|
return new S3StorageAdapter(config);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const uploadFile = wrap(async (file: File) => {
|
|||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
throw new Error('File upload failed');
|
throw new Error('File upload failed');
|
||||||
}
|
}
|
||||||
|
console.log(result.value);
|
||||||
|
|
||||||
const response = await fetch(result.value, {
|
const response = await fetch(result.value, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
|
|||||||
Reference in New Issue
Block a user