Skip to content

Commit fe3ce1d

Browse files
committed
chore: improve code
1 parent 34cdcbd commit fe3ce1d

File tree

24 files changed

+94
-164
lines changed

24 files changed

+94
-164
lines changed
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import type { TeamCollectionName } from '../../../support/user/team/constant';
2-
3-
export type MinioTtlSchemaType = {
1+
export type S3TtlSchemaType = {
42
_id: string;
53
bucketName: string;
64
minioKey: string;
7-
expiredTime?: Date;
5+
expiredTime: Date;
86
};

packages/service/common/file/minioTtl/hooks.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

packages/service/common/file/minioTtl/schema.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/service/common/file/minioTtl/types.ts

Whitespace-only changes.

packages/service/common/file/minioTtl/controller.ts renamed to packages/service/common/file/s3Ttl/controller.ts

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MongoMinioTtl } from './schema';
1+
import { MongoS3Ttl } from './schema';
22
import { S3BucketManager } from '../../s3/buckets/manager';
33
import { addLog } from '../../system/log';
44
import { setCron } from '../../system/cron';
@@ -9,7 +9,7 @@ export async function clearExpiredMinioFiles() {
99
try {
1010
const now = new Date();
1111

12-
const expiredFiles = await MongoMinioTtl.find({
12+
const expiredFiles = await MongoS3Ttl.find({
1313
expiredTime: { $exists: true, $ne: null, $lte: now }
1414
}).lean();
1515

@@ -27,19 +27,17 @@ export async function clearExpiredMinioFiles() {
2727
for (const file of expiredFiles) {
2828
try {
2929
const bucket = (() => {
30-
switch (file.bucketName) {
31-
case process.env.S3_PUBLIC_BUCKET:
32-
return s3Manager.getPublicBucket();
33-
case process.env.S3_PRIVATE_BUCKET:
34-
return s3Manager.getPrivateBucket();
35-
default:
36-
throw new Error(`Unknown bucket name: ${file.bucketName}`);
30+
if (file.bucketName === process.env.S3_PUBLIC_BUCKET) {
31+
return s3Manager.getPublicBucket();
3732
}
33+
if (file.bucketName === process.env.S3_PRIVATE_BUCKET) {
34+
return s3Manager.getPrivateBucket();
35+
}
36+
throw new Error(`Unknown bucket name: ${file.bucketName}`);
3837
})();
3938

4039
await bucket.delete(file.minioKey);
41-
42-
await MongoMinioTtl.deleteOne({ _id: file._id });
40+
await MongoS3Ttl.deleteOne({ _id: file._id });
4341

4442
success++;
4543
addLog.info(`Deleted expired minio file: ${file.minioKey} from bucket: ${file.bucketName}`);
@@ -68,25 +66,3 @@ export function clearExpiredMinioFilesCron() {
6866
}
6967
});
7068
}
71-
72-
export async function addMinioTtlFile({
73-
bucketName,
74-
minioKey,
75-
expiredTime
76-
}: {
77-
bucketName: string;
78-
minioKey: string;
79-
expiredTime?: Date;
80-
}) {
81-
try {
82-
await MongoMinioTtl.create({
83-
bucketName,
84-
minioKey,
85-
expiredTime
86-
});
87-
addLog.info(`Added minio TTL file: ${minioKey}, expiredTime: ${expiredTime}`);
88-
} catch (error) {
89-
addLog.error('Failed to add minio TTL file', error);
90-
throw error;
91-
}
92-
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Schema, getMongoModel } from '../../mongo';
2+
import { type S3TtlSchemaType } from '@fastgpt/global/common/file/minioTtl/type';
3+
4+
const collectionName = 's3_ttl_files';
5+
6+
const S3TtlSchema = new Schema({
7+
bucketName: {
8+
type: String,
9+
required: true
10+
},
11+
minioKey: {
12+
type: String,
13+
required: true
14+
},
15+
expiredTime: {
16+
type: Date,
17+
required: true
18+
}
19+
});
20+
21+
S3TtlSchema.index({ expiredTime: 1 });
22+
S3TtlSchema.index({ bucketName: 1, minioKey: 1 });
23+
24+
export const MongoS3Ttl = getMongoModel<S3TtlSchemaType>(collectionName, S3TtlSchema);

packages/service/common/s3/buckets/base.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import { Client, type RemoveOptions, type CopyConditions, type LifecycleConfig } from 'minio';
22
import {
33
defaultS3Options,
4+
type ExtensionType,
5+
Mimes,
46
type CreatePostPresignedUrlOptions,
57
type CreatePostPresignedUrlParams,
68
type CreatePostPresignedUrlResult,
79
type S3BucketName,
810
type S3Options
9-
} from '../types';
10-
import type { IBucketBasicOperations } from '../interface';
11-
import {
12-
createObjectKey,
13-
createPresignedUrlExpires,
14-
createTempObjectKey,
15-
inferContentType
16-
} from '../helpers';
17-
import { afterCreatePresignedUrl } from '../../file/minioTtl/hooks';
11+
} from '../type';
12+
import type { BucketBasicOperationsType } from '../interface';
13+
import { createObjectKey, createTempObjectKey } from '../helpers';
14+
import path from 'node:path';
15+
import { MongoS3Ttl } from 'common/file/s3Ttl/schema';
1816

19-
export class S3BaseBucket implements IBucketBasicOperations {
17+
export class S3BaseBucket implements BucketBasicOperationsType {
2018
public client: Client;
2119

2220
/**
@@ -69,37 +67,40 @@ export class S3BaseBucket implements IBucketBasicOperations {
6967
throw new Error('Method not implemented.');
7068
}
7169

72-
lifecycle(): Promise<LifecycleConfig | null> {
70+
getLifecycle(): Promise<LifecycleConfig | null> {
7371
return this.client.getBucketLifecycle(this.name);
7472
}
7573

7674
async createPostPresignedUrl(
7775
params: CreatePostPresignedUrlParams,
7876
options: CreatePostPresignedUrlOptions = {}
7977
): Promise<CreatePostPresignedUrlResult> {
80-
const { temporay, ttl: ttlDays = 7 } = options;
81-
const contentType = inferContentType(params.filename);
78+
const { temporary, ttl = 7 * 24 } = options;
79+
const ext = path.extname(params.filename).toLowerCase() as ExtensionType;
80+
const contentType = Mimes[ext] ?? 'application/octet-stream';
8281
const maxFileSize = this.options.maxFileSize as number;
83-
const key = temporay ? createTempObjectKey(params) : createObjectKey(params);
82+
const key = temporary ? createTempObjectKey(params) : createObjectKey(params);
8483

8584
const policy = this.client.newPostPolicy();
8685
policy.setKey(key);
8786
policy.setBucket(this.name);
8887
policy.setContentType(contentType);
8988
policy.setContentLengthRange(1, maxFileSize);
90-
policy.setExpires(createPresignedUrlExpires(10));
89+
policy.setExpires(new Date(Date.now() + 10 * 60 * 1000));
9190
policy.setUserMetaData({
9291
filename: encodeURIComponent(params.filename),
9392
visibility: params.visibility
9493
});
9594

9695
const { formData, postURL } = await this.client.presignedPostPolicy(policy);
97-
await afterCreatePresignedUrl({
98-
bucketName: this.name,
99-
objectKey: key,
100-
temporay,
101-
ttl: ttlDays
102-
});
96+
97+
if (temporary) {
98+
await MongoS3Ttl.create({
99+
minioKey: key,
100+
bucketName: this.name,
101+
expiredTime: new Date(Date.now() + ttl * 3.6e6)
102+
});
103+
}
103104

104105
return {
105106
url: postURL,

packages/service/common/s3/buckets/manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type S3Options } from '../types';
1+
import { type S3Options } from '../type';
22
import { S3PublicBucket } from './public';
33
import { S3PrivateBucket } from './private';
44

packages/service/common/s3/buckets/private.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type CreatePostPresignedUrlParams,
55
type CreatePostPresignedUrlResult,
66
type S3Options
7-
} from '../types';
7+
} from '../type';
88

99
export class S3PrivateBucket extends S3BaseBucket {
1010
constructor(options?: Partial<S3Options>) {

packages/service/common/s3/buckets/public.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type CreatePostPresignedUrlParams,
77
type CreatePostPresignedUrlResult,
88
type S3Options
9-
} from '../types';
9+
} from '../type';
1010
import type { IPublicBucketOperations } from '../interface';
1111
import { lifecycleOfTemporaryAvatars } from '../lifecycle';
1212

@@ -42,7 +42,17 @@ export class S3PublicBucket extends S3BaseBucket implements IPublicBucketOperati
4242
const port = this.options.port;
4343
const bucket = this.name;
4444

45-
return `${protocol}://${hostname}:${port}/${bucket}/${objectKey}`;
45+
const url = new URL(`${protocol}://${hostname}:${port}/${bucket}/${objectKey}`);
46+
47+
if (this.options.externalBaseURL) {
48+
const externalBaseURL = new URL(this.options.externalBaseURL);
49+
50+
url.port = externalBaseURL.port;
51+
url.hostname = externalBaseURL.hostname;
52+
url.protocol = externalBaseURL.protocol;
53+
}
54+
55+
return url.toString();
4656
}
4757

4858
override createPostPresignedUrl(

0 commit comments

Comments
 (0)