Files
web-temp/layers/utils/urlUtil.ts

150 lines
4.6 KiB
TypeScript

import { getHeader, getRequestHost, type H3Event } from 'h3'
/**
* URL이 외부 URL인지 확인하는 함수
* @param url - 확인할 URL 문자열
* @returns 외부 URL 여부
*/
export const isExternalUrl = (url: string): boolean => {
return url.startsWith('http://') || url.startsWith('https://')
}
/**
* 게임 도메인을 추출하는 함수
* 서버와 클라이언트 환경에서 모두 동작
* @param event - H3 이벤트 객체 (서버 전달 필수)
* @returns 게임 도메인 문자열
*/
export const getGameDomain = (event?: H3Event): string => {
try {
let host = ''
// 클라이언트 환경에서는 window.location.host를 사용
if (import.meta.client) {
host = (window.location.host || '').split(':')[0]
}
// 서버 환경에서는 event 객체를 사용
if (import.meta.server) {
if (!event) return ''
// 미들웨어에서 설정한 gameDomain이 있다면 우선 사용
if (event.context.gameDomain) {
host = event.context.gameDomain
} else {
const serverHost =
getHeader(event, 'host') || getRequestHost(event) || ''
host = serverHost.split(':')[0]
}
}
if (!host) return ''
// dev2 호스트명인 경우 l9-dev.onstove.com을 사용
if (host === 'samplegame-dev2.onstove.com') {
return 'l9-dev.onstove.com'
}
return host
} catch (error) {
console.error('getGameDomain error:', error)
return ''
}
}
/**
* URL에서 언어 코드를 추출하는 함수
* @param url - URL 문자열
* @returns 언어 코드 문자열
*/
export const getPathLocale = (url: string): string => {
if (!url) return ''
const cleanUrl = url.endsWith('/') ? url.slice(0, -1) : url
return cleanUrl.split('/')[1] || ''
}
/**
* URL에서 언어 코드 이후의 경로를 추출하는 함수
* 서버와 클라이언트 환경에서 모두 동작
* @param url - URL 문자열
* @returns 언어 코드 이후의 경로 문자열
*/
export const getPathAfterLanguage = (url: string): string => {
if (!url) return ''
const cleanUrl = url.split('?')[0].endsWith('/') ? url.slice(0, -1) : url
// URL에서 언어 코드 패턴을 찾아서 그 뒤의 경로를 추출
// 예: /ko/about/story -> /about/story
// 예: /ko -> "" (빈 문자열)
const languagePattern = /^\/[a-z]{2}(-[a-z]{2})?\/(.+)$/
const match = cleanUrl.match(languagePattern)
if (match && match[2]) {
return `/${match[2]}`
} else {
// 언어 코드만 있고 뒤에 아무것도 없는 경우 (예: /ko, /en, /zh-tw, /zh-cn)
const languageOnlyPattern = /^\/[a-z]{2}(-[a-z]{2})?$/
if (languageOnlyPattern.test(cleanUrl)) {
return ''
} else {
// 언어 코드가 없는 경우 원본 경로 그대로 반환 (이미 /로 시작)
return cleanUrl
}
}
}
/**
* intro page_url을 기반으로 리다이렉트 경로를 생성하는 공통 함수
* @param introPageUrl - intro.page_url 값
* @param langCode - 현재 언어 코드
* @param currentUrl - 현재 접근한 URL (쿼리스트링 포함, 옵션)
* @returns 최종 리다이렉트 경로 (없으면 기본값 /home)
*/
export const getIntroRedirectPath = (
introPageUrl: string | undefined | null,
langCode: string,
currentUrl?: string
): string => {
// 기본값: /langCode/home
let defaultPath = `/${langCode}/home`
if (introPageUrl && introPageUrl.trim() !== '') {
if (isExternalUrl(introPageUrl)) {
// 외부 URL인 경우 그대로 사용
defaultPath = introPageUrl
} else {
// 내부 경로인 경우 언어 코드 패턴 확인
const normalizedIntroUrl = introPageUrl.split('?')[0] // 쿼리스트링 제외
const languagePattern = /^\/[a-z]{2}(-[a-z]{2})?(\/|$)/
const hasLanguageCode = languagePattern.test(normalizedIntroUrl)
if (hasLanguageCode) {
// 이미 언어 코드가 있으면 그대로 사용
defaultPath = introPageUrl
} else {
// 언어 코드가 없으면 추가
const pathWithSlash = normalizedIntroUrl.startsWith('/')
? normalizedIntroUrl
: `/${normalizedIntroUrl}`
defaultPath = `/${langCode}${pathWithSlash}`
// 쿼리스트링이 있으면 다시 추가
if (introPageUrl.includes('?')) {
defaultPath += '?' + introPageUrl.split('?')[1]
}
}
}
}
// intro에 쿼리스트링이 없고, 현재 URL에 쿼리스트링이 있으면 추가
if (!defaultPath.includes('?') && currentUrl && currentUrl.includes('?')) {
const queryString = currentUrl.split('?')[1]
if (queryString) {
defaultPath += '?' + queryString
}
}
return defaultPath
}