에디터 미디어 업로드 검증 로직 분리

This commit is contained in:
2026-07-24 17:55:33 +09:00
parent 6cc820d2a2
commit e3f98cb820
7 changed files with 143 additions and 61 deletions

View File

@@ -23,12 +23,14 @@ import {
} from '../../lib/markdown-editor-history.js'
import {
createMediaBlockMarkdown,
findUploadSizeLimitError,
getGallerySelectionOrder as getGallerySelectionOrderFromSelection,
getMediaItemKind,
getMediaPickerPreviewUrl,
isMediaItemSelectableForTarget,
isUploadFileAllowedForMediaTarget,
resolveSelectedMediaItems,
resolveUploadFetchErrorMessage,
toggleMediaSelectionState
} from '../../lib/markdown-editor-media.js'
import {
@@ -49,9 +51,6 @@ import {
DEFAULT_UPLOAD_MAX_FILE_COUNT,
DEFAULT_UPLOAD_MAX_TOTAL_SIZE,
formatUploadSizeLimit,
getUploadFilesTotalSize,
getMaxUploadBytesForKind,
getUploadKind,
normalizeUploadMaxFileCount,
normalizeUploadMaxTotalSize
} from '../../lib/upload-size-limit.js'
@@ -3268,66 +3267,18 @@ const applyMediaSelection = () => {
closeMediaPicker()
}
/**
* 업로드 API 오류 메시지를 사용자용 문장으로 변환한다.
* @param {unknown} error - fetch 오류
* @returns {string} 오류 메시지
*/
const resolveUploadFetchErrorMessage = (error) => {
const responseMessage = error?.data?.message || error?.response?._data?.message
if (typeof responseMessage === 'string' && responseMessage.trim()) {
return responseMessage.trim()
}
if (error?.statusCode === 413 || error?.status === 413) {
return '업로드 가능한 파일 크기를 초과했습니다.'
}
if (error instanceof Error && error.message) {
return error.message
}
return '파일 업로드에 실패했습니다.'
}
/**
* 선택 파일이 업로드 한도를 넘지 않는지 검사한다.
* @param {FileList|Array<File>} files - 업로드 파일 목록
* @returns {string|null} 초과 시 오류 메시지, 아니면 null
*/
const findUploadSizeLimitError = (files) => {
const fileList = Array.from(files || [])
if (fileList.length > uploadMaxFileCount.value) {
return `한 번에 업로드할 수 있는 파일은 최대 ${uploadMaxFileCount.value}개입니다.`
}
const uploadTotalSize = getUploadFilesTotalSize(fileList)
if (uploadTotalSize > uploadMaxTotalSize.value) {
return `한 번에 업로드 가능한 전체 용량을 초과했습니다. (최대 ${formatUploadSizeLimit(uploadMaxTotalSize.value)})`
}
for (const file of fileList) {
const uploadKind = getUploadKind(file.type, file.name)
const maxBytes = getMaxUploadBytesForKind(uploadKind, uploadSizeLimits.value)
if (file.size > maxBytes) {
return `파일 크기가 너무 큽니다. (최대 ${formatUploadSizeLimit(maxBytes)})`
}
}
return null
}
/**
* 미디어 파일을 업로드한다.
* @param {FileList|Array<File>} files - 업로드 파일 목록
* @returns {Promise<Array<Object>>} 업로드된 파일 목록
*/
const uploadMediaFiles = async (files) => {
const sizeLimitError = findUploadSizeLimitError(files)
const sizeLimitError = findUploadSizeLimitError({
files,
maxFileCount: uploadMaxFileCount.value,
maxTotalSize: uploadMaxTotalSize.value,
uploadSizeLimits: uploadSizeLimits.value
})
if (sizeLimitError) {
throw new Error(sizeLimitError)