Files
sori.studio/server/utils/admin-site-settings-input.js
zenn dcd1060ec7 v1.4.6: 사이트 설정 이미지 저장 흐름·홈 커버 라이트/다크 분리
- 로고 업로드는 파일 URL만 폼에 반영하고 기타 설정 저장 시 DB에 반영
- 메인 화면 커버 라이트·다크 이미지 필드 추가 및 테마별 HomeHero 교체
- home_cover_dark_image_url 마이그레이션 및 미디어 사용 현황 보정
2026-05-22 17:05:34 +09:00

62 lines
2.6 KiB
JavaScript

import { z } from 'zod'
import {
DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
isValidAnnouncementBackgroundColor,
normalizeAnnouncementUrl
} from '../../lib/announcement-bar.js'
import {
DEFAULT_SIGNUP_BLOCKED_USERNAMES,
MAX_SIGNUP_BLOCKED_USERNAME_COUNT,
MAX_SIGNUP_BLOCKED_USERNAME_LENGTH,
normalizeSignupBlockedUsernames
} from '../../lib/signup-blocked-usernames.js'
export const adminSiteSettingsInputSchema = z.object({
title: z.string().trim().min(1),
description: z.string().trim().min(1),
siteUrl: z.string().trim().url(),
logoText: z.string().trim().max(8).optional().default('井'),
logoUrl: z.string().trim().max(500).optional().default(''),
faviconUrl: z.string().trim().max(500).optional().default(''),
copyrightText: z.string().trim().min(1),
showPostUpdatedAt: z.boolean().optional().default(false),
homeCoverImageUrl: z.string().trim().max(500).optional().default(''),
homeCoverDarkImageUrl: z.string().trim().max(500).optional().default(''),
homeCoverTitle: z.string().trim().max(120).optional().default(''),
homeCoverText: z.string().trim().max(280).optional().default(''),
announcementEnabled: z.boolean().optional().default(false),
announcementText: z.string().trim().max(200).optional().default(''),
announcementUrl: z.string().trim().max(500).optional().default(''),
announcementBackgroundColor: z.string().trim().optional().default(DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR),
signupBlockedUsernames: z.array(
z.string().trim().min(1).max(MAX_SIGNUP_BLOCKED_USERNAME_LENGTH)
).max(MAX_SIGNUP_BLOCKED_USERNAME_COUNT).optional().default([...DEFAULT_SIGNUP_BLOCKED_USERNAMES])
}).superRefine((data, ctx) => {
if (!isValidAnnouncementBackgroundColor(data.announcementBackgroundColor)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: '어나운스 바 배경색이 올바르지 않습니다.',
path: ['announcementBackgroundColor']
})
}
if (data.announcementEnabled && !data.announcementText.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: '어나운스 바를 사용할 때는 공지 문구를 입력해야 합니다.',
path: ['announcementText']
})
}
}).transform((data) => ({
...data,
announcementUrl: normalizeAnnouncementUrl(data.announcementUrl),
signupBlockedUsernames: normalizeSignupBlockedUsernames(data.signupBlockedUsernames)
}))
/**
* 관리자 사이트 설정 입력값 정리
* @param {unknown} body - 요청 본문
* @returns {import('zod').SafeParseReturnType<unknown, Object>} 검증 결과
*/
export const parseAdminSiteSettingsInput = (body) => adminSiteSettingsInputSchema.safeParse(body)