feat(media): support local and s3 upload providers
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { randomUUID } from "node:crypto"
|
||||
import { mkdir, writeFile } from "node:fs/promises"
|
||||
import path from "node:path"
|
||||
|
||||
type StoreUploadParams = {
|
||||
import { buildMediaStorageKey } from "@/lib/media/storage-key"
|
||||
|
||||
type StoreLocalUploadParams = {
|
||||
file: File
|
||||
mediaType: string
|
||||
}
|
||||
@@ -11,8 +12,6 @@ type StoredUpload = {
|
||||
storageKey: string
|
||||
}
|
||||
|
||||
const FALLBACK_EXTENSION = "bin"
|
||||
|
||||
function resolveBaseDirectory(): string {
|
||||
const configured = process.env.CMS_MEDIA_LOCAL_STORAGE_DIR?.trim()
|
||||
|
||||
@@ -23,37 +22,8 @@ function resolveBaseDirectory(): string {
|
||||
return path.resolve(process.cwd(), ".data", "media")
|
||||
}
|
||||
|
||||
function normalizeSegment(value: string): string {
|
||||
return value
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9._-]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
}
|
||||
|
||||
function extensionFromFilename(fileName: string): string {
|
||||
const extension = path.extname(fileName).slice(1)
|
||||
|
||||
if (!extension) {
|
||||
return FALLBACK_EXTENSION
|
||||
}
|
||||
|
||||
const normalized = normalizeSegment(extension)
|
||||
|
||||
return normalized.length > 0 ? normalized : FALLBACK_EXTENSION
|
||||
}
|
||||
|
||||
function buildStorageKey(mediaType: string, fileName: string): string {
|
||||
const now = new Date()
|
||||
const year = String(now.getUTCFullYear())
|
||||
const month = String(now.getUTCMonth() + 1).padStart(2, "0")
|
||||
const normalizedType = normalizeSegment(mediaType) || "generic"
|
||||
const extension = extensionFromFilename(fileName)
|
||||
|
||||
return [normalizedType, year, month, `${randomUUID()}.${extension}`].join("/")
|
||||
}
|
||||
|
||||
export async function storeUploadLocally(params: StoreUploadParams): Promise<StoredUpload> {
|
||||
const storageKey = buildStorageKey(params.mediaType, params.file.name)
|
||||
export async function storeUploadLocally(params: StoreLocalUploadParams): Promise<StoredUpload> {
|
||||
const storageKey = buildMediaStorageKey(params.mediaType, params.file.name)
|
||||
const baseDirectory = resolveBaseDirectory()
|
||||
const outputPath = path.join(baseDirectory, storageKey)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user