Files
frontend/apps/sn/app/components/lib/utils/fileUploadUtil.tsx
T

68 lines
2.0 KiB
TypeScript

/**
* 📄 File Upload Utility
* 파일 업로드 유틸리티
*
* - TUS 프로토콜을 통한 파일 업로드 처리
* - 쿠키 기반 인증 토큰 관리 및 사용자 조회
* - Axios 기반 HTTP 요청 처리
* - 업로드 진행률 및 성공/실패 콜백 지원
* - 파일 메타데이터 설정 및 헤더 추가
* - 대용량 파일 청크 업로드 지원
*/
import { Upload, type HttpResponse } from "tus-js-client";
import { getCookie, setCookie } from "@/shared/lib";
import { ENDPOINT } from "../api/attachment/attachment-service";
const AUTH_USER_ID = process.env.NEXT_PUBLIC_AUTH_USER_ID || "token-id";
const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization";
type UploadOptions = {
handleUploadStart?: (upload: Upload) => void;
handleProgress?: (percentage: string) => void;
handleSuccess?: (upload: Upload) => void;
handleResponse?: (res: HttpResponse) => void;
};
export const handleUpload = (files: FileList, options?: UploadOptions) => {
let metadata = {};
const file = files.item(0);
if (!file) return;
metadata = {
filename: file.name,
filetype: file.type,
};
const upload = new Upload(file, {
endpoint: ENDPOINT.ATTACH_SERVICE.TUS_UPLOAD,
chunkSize: 10 * 1024 * 1024,
headers: {
[CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "",
[AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "",
},
metadata,
onError(error) {
console.error(`Failed because: ${error}`);
},
onProgress(bytesUploaded, bytesTotal) {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
options?.handleProgress?.(percentage);
},
onAfterResponse(req, res) {
const fileInfo = res.getHeader("X-File-Info");
if (fileInfo === undefined || fileInfo === null) return;
setCookie("atfl-cd-key", JSON.parse(fileInfo)?.atflCd ?? "");
options?.handleResponse?.(res);
},
onSuccess() {
options?.handleSuccess?.(upload);
},
});
upload.start();
options?.handleUploadStart?.(upload);
console.log("upload start");
};