chore: fix lint errors — duplicate import, unused imports, formatting
Deploy FileDrop / deploy (push) Successful in 45s
Deploy FileDrop / deploy (push) Successful in 45s
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import { timingSafeEqual } from 'node:crypto';
|
||||
import type { LoginInput, LoginResponse, LogoutResponse, UserInfoResponse, AuthSession } from '../dto/auth';
|
||||
import type {
|
||||
AuthSession,
|
||||
LoginInput,
|
||||
LoginResponse,
|
||||
LogoutResponse,
|
||||
UserInfoResponse,
|
||||
} from '../dto/auth';
|
||||
|
||||
/** Subset of application configuration consumed by the authenticate use case. */
|
||||
export interface AuthUseCaseConfig {
|
||||
@@ -105,4 +111,4 @@ export function createMeUseCase(deps: AuthenticateUseCaseDeps) {
|
||||
expiresAt: session.expiresAt?.toISOString() ?? null,
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,4 +173,4 @@ export function createGetFileUseCase(deps: GetFileUseCaseDeps) {
|
||||
|
||||
return { type: 'redirect', file, redirectUrl, fileInfo };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,11 +98,7 @@ export function createGetBucketUseCase(deps: ManageBucketDeps) {
|
||||
export function createCreateBucketUseCase(deps: ManageBucketDeps) {
|
||||
return async (name: string): Promise<Bucket> => {
|
||||
if (!BUCKET_NAME_REGEX.test(name)) {
|
||||
throw new BucketError(
|
||||
'InvalidBucketName',
|
||||
'The specified bucket is not valid.',
|
||||
400,
|
||||
);
|
||||
throw new BucketError('InvalidBucketName', 'The specified bucket is not valid.', 400);
|
||||
}
|
||||
|
||||
const existing = await deps.bucketRepo.findByName(name);
|
||||
@@ -134,20 +130,12 @@ export function createDeleteBucketUseCase(deps: ManageBucketDeps) {
|
||||
return async (name: string): Promise<boolean> => {
|
||||
const bucket = await deps.bucketRepo.findByName(name);
|
||||
if (!bucket) {
|
||||
throw new BucketError(
|
||||
'NoSuchBucket',
|
||||
'The specified bucket does not exist.',
|
||||
404,
|
||||
);
|
||||
throw new BucketError('NoSuchBucket', 'The specified bucket does not exist.', 404);
|
||||
}
|
||||
|
||||
const objectCount = await deps.fileRepo.countByBucket(bucket.id);
|
||||
if (objectCount > 0) {
|
||||
throw new BucketError(
|
||||
'BucketNotEmpty',
|
||||
'The bucket you tried to delete is not empty.',
|
||||
409,
|
||||
);
|
||||
throw new BucketError('BucketNotEmpty', 'The bucket you tried to delete is not empty.', 409);
|
||||
}
|
||||
|
||||
return deps.bucketRepo.delete(name);
|
||||
@@ -165,4 +153,4 @@ export function createBucketExistsUseCase(deps: ManageBucketDeps) {
|
||||
return async (name: string): Promise<boolean> => {
|
||||
return deps.bucketRepo.exists(name);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,10 +116,7 @@ export interface MultipartDeps {
|
||||
* the upload initiation result, or `null` when the bucket is not found.
|
||||
*/
|
||||
export function createInitiateMultipartUploadUseCase(deps: MultipartDeps) {
|
||||
return async (
|
||||
bucketName: string,
|
||||
key: string,
|
||||
): Promise<InitiateMultipartResult | null> => {
|
||||
return async (bucketName: string, key: string): Promise<InitiateMultipartResult | null> => {
|
||||
const bucket = await deps.bucketRepo.findByName(bucketName);
|
||||
if (!bucket) return null;
|
||||
|
||||
@@ -375,4 +372,4 @@ export function createListPartsUseCase(deps: MultipartDeps) {
|
||||
createdAt: p.createdAt,
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { gzipSync } from 'node:zlib';
|
||||
import { nanoid } from 'nanoid';
|
||||
import type { File, NewFile } from '../../domain/entities/file';
|
||||
import type { File } from '../../domain/entities/file';
|
||||
import type { NewFilePart } from '../../domain/entities/file-part';
|
||||
import type { MultipartPart } from '../../domain/entities/multipart';
|
||||
import type { IBucketRepository } from '../../domain/ports/bucket-repository';
|
||||
@@ -9,7 +9,7 @@ import type { IFilePartRepository } from '../../domain/ports/file-part-repositor
|
||||
import type { IFileRepository, S3FileRecord } from '../../domain/ports/file-repository';
|
||||
import type { IMultipartRepository } from '../../domain/ports/multipart-repository';
|
||||
import type { ITelegramService, TelegramFileInfo } from '../../domain/ports/telegram-service';
|
||||
import { ensureExtension, computeHash, formatCreatedAt } from '../../shared/utils/file';
|
||||
import { computeHash, ensureExtension, formatCreatedAt } from '../../shared/utils/file';
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -456,7 +456,12 @@ export function createPutObjectUseCase(deps: S3ObjectDeps) {
|
||||
);
|
||||
|
||||
const partFileNamePrefix = `s3-${bucket.name}-${key.replace(/\//g, '_')}`;
|
||||
const { telegramChunkSizeBytes, compressChunkedUploads, chunkCompressionMinSizeBytes, storageChatId } = deps.config;
|
||||
const {
|
||||
telegramChunkSizeBytes,
|
||||
compressChunkedUploads,
|
||||
chunkCompressionMinSizeBytes,
|
||||
storageChatId,
|
||||
} = deps.config;
|
||||
|
||||
if (body.byteLength > telegramChunkSizeBytes) {
|
||||
// Chunked upload path
|
||||
@@ -594,16 +599,28 @@ export function createCopyObjectUseCase(deps: S3ObjectDeps) {
|
||||
if (!sourceFile) return null;
|
||||
|
||||
if (sourceFile.storageBackend === 'chunked') {
|
||||
throw new ObjectError('NotImplemented', 'Copying chunked objects is not yet implemented.', 501);
|
||||
throw new ObjectError(
|
||||
'NotImplemented',
|
||||
'Copying chunked objects is not yet implemented.',
|
||||
501,
|
||||
);
|
||||
}
|
||||
|
||||
// Conditional copy: if-match / if-none-match checks
|
||||
const sourceEtag = sourceFile.fileHash;
|
||||
if (input.ifMatch && sourceEtag && input.ifMatch !== sourceEtag) {
|
||||
throw new ObjectError('PreconditionFailed', 'The preconditions you specified did not hold.', 412);
|
||||
throw new ObjectError(
|
||||
'PreconditionFailed',
|
||||
'The preconditions you specified did not hold.',
|
||||
412,
|
||||
);
|
||||
}
|
||||
if (input.ifNoneMatch && sourceEtag && input.ifNoneMatch === sourceEtag) {
|
||||
throw new ObjectError('PreconditionFailed', 'The preconditions you specified did not hold.', 412);
|
||||
throw new ObjectError(
|
||||
'PreconditionFailed',
|
||||
'The preconditions you specified did not hold.',
|
||||
412,
|
||||
);
|
||||
}
|
||||
|
||||
const publicId = nanoid();
|
||||
@@ -771,4 +788,4 @@ export function createFindObjectUseCase(deps: Pick<S3ObjectDeps, 'fileRepo'>) {
|
||||
return async (bucketId: string, key: string): Promise<File | null> => {
|
||||
return deps.fileRepo.findByBucketAndKey(bucketId, key);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { open } from 'node:fs/promises';
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { open } from 'node:fs/promises';
|
||||
import { gzipSync } from 'node:zlib';
|
||||
import { nanoid } from 'nanoid';
|
||||
import type { NewFilePart } from '../../domain/entities/file-part';
|
||||
import type { IFilePartRepository } from '../../domain/ports/file-part-repository';
|
||||
import type { IFileRepository } from '../../domain/ports/file-repository';
|
||||
import type { ITelegramService } from '../../domain/ports/telegram-service';
|
||||
import { checkFileSize, computeHash, ensureExtension, getFileType } from '../../shared/utils/file';
|
||||
import type { UploadInput, UploadOutput } from '../dto/upload';
|
||||
import { getFileType, checkFileSize, ensureExtension, computeHash, formatCreatedAt } from '../../shared/utils/file';
|
||||
|
||||
/** Compression algorithm string literal used in chunked storage. */
|
||||
type ChunkCompressionAlgorithm = 'gzip' | null;
|
||||
@@ -219,7 +219,8 @@ export function createUploadFileUseCase(deps: UploadFileUseCaseDeps) {
|
||||
mimeType: existing.mimeType,
|
||||
sizeBytes: existing.sizeBytes,
|
||||
fileType: existing.fileType,
|
||||
createdAt: existing.createdAt instanceof Date ? existing.createdAt : new Date(existing.createdAt),
|
||||
createdAt:
|
||||
existing.createdAt instanceof Date ? existing.createdAt : new Date(existing.createdAt),
|
||||
downloadUrl: `${deps.config.baseUrl}/f/${existing.publicId}`,
|
||||
};
|
||||
}
|
||||
@@ -357,4 +358,4 @@ export function createUploadFileUseCase(deps: UploadFileUseCaseDeps) {
|
||||
downloadUrl: `${deps.config.baseUrl}/f/${createdFile.publicId}`,
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user