96 lines
4.2 KiB
JavaScript
96 lines
4.2 KiB
JavaScript
import { z } from 'zod'
|
|
import {
|
|
DEFAULT_ANNOUNCEMENT_ALIGNMENT,
|
|
DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR,
|
|
isValidAnnouncementBackgroundColor,
|
|
normalizeAnnouncementAlignment,
|
|
normalizeAnnouncementBackgroundColor,
|
|
normalizeAnnouncementUrl
|
|
} from '../../lib/announcement-bar.js'
|
|
import {
|
|
DEFAULT_BRAND_COLOR,
|
|
isValidBrandColor,
|
|
normalizeBrandColor
|
|
} from '../../lib/brand-color.js'
|
|
import {
|
|
DEFAULT_SIGNUP_BLOCKED_USERNAMES,
|
|
MAX_SIGNUP_BLOCKED_USERNAME_COUNT,
|
|
MAX_SIGNUP_BLOCKED_USERNAME_LENGTH,
|
|
normalizeSignupBlockedUsernames
|
|
} from '../../lib/signup-blocked-usernames.js'
|
|
import { normalizeSocialLinks } from '../../lib/social-links.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),
|
|
socialLinks: z.unknown().optional().default([]),
|
|
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(''),
|
|
brandColor: z.string().trim().optional().default(DEFAULT_BRAND_COLOR),
|
|
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),
|
|
announcementAlignment: z.string().trim().optional().default(DEFAULT_ANNOUNCEMENT_ALIGNMENT),
|
|
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]),
|
|
adsTxt: z.string().max(20000).optional().default(''),
|
|
customHeadCode: z.string().max(50000).optional().default(''),
|
|
customFooterCode: z.string().max(50000).optional().default(''),
|
|
adHomeFeedCode: z.string().max(50000).optional().default(''),
|
|
adHomeInfeedCode: z.string().max(50000).optional().default(''),
|
|
adSidebarCode: z.string().max(50000).optional().default(''),
|
|
adPostSidebarCode: z.string().max(50000).optional().default(''),
|
|
adPostTopCode: z.string().max(50000).optional().default(''),
|
|
adPostInArticleCode: z.string().max(50000).optional().default(''),
|
|
adPostBottomCode: z.string().max(50000).optional().default('')
|
|
}).superRefine((data, ctx) => {
|
|
if (!isValidAnnouncementBackgroundColor(data.announcementBackgroundColor)) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: '어나운스 바 배경색이 올바르지 않습니다.',
|
|
path: ['announcementBackgroundColor']
|
|
})
|
|
}
|
|
|
|
if (!isValidBrandColor(data.brandColor)) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: '브랜드 컬러가 올바르지 않습니다.',
|
|
path: ['brandColor']
|
|
})
|
|
}
|
|
|
|
if (data.announcementEnabled && !data.announcementText.trim()) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: '어나운스 바를 사용할 때는 공지 문구를 입력해야 합니다.',
|
|
path: ['announcementText']
|
|
})
|
|
}
|
|
}).transform((data) => ({
|
|
...data,
|
|
brandColor: normalizeBrandColor(data.brandColor),
|
|
socialLinks: normalizeSocialLinks(data.socialLinks),
|
|
announcementUrl: normalizeAnnouncementUrl(data.announcementUrl),
|
|
announcementBackgroundColor: normalizeAnnouncementBackgroundColor(data.announcementBackgroundColor),
|
|
announcementAlignment: normalizeAnnouncementAlignment(data.announcementAlignment),
|
|
signupBlockedUsernames: normalizeSignupBlockedUsernames(data.signupBlockedUsernames)
|
|
}))
|
|
|
|
/**
|
|
* 관리자 사이트 설정 입력값 정리
|
|
* @param {unknown} body - 요청 본문
|
|
* @returns {import('zod').SafeParseReturnType<unknown, Object>} 검증 결과
|
|
*/
|
|
export const parseAdminSiteSettingsInput = (body) => adminSiteSettingsInputSchema.safeParse(body)
|