import { LRUCache } from 'lru-cache' import { usePageDataStore } from '#layers/stores/usePageDataStore' import { useLoadingStore } from '#layers/stores/useLoadingStore' import { commonFetch } from '#layers/utils/apiUtil' import { getGameDomain, getPathAfterLanguage } from '#layers/utils/urlUtil' import { DEFAULT_LOCALE_CODE } from '@/i18n.config' import type { PageDataResponse } from '#layers/types/api/pageData' /** 페이지 데이터 API 응답 LRU */ const pageDataResponseCache = new LRUCache({ max: 100, ttl: 1000 * 60, }) export default defineNuxtRouteMiddleware(async (to, _from) => { const runtimeConfig = useRuntimeConfig() // error 페이지는 실행X ----- if (to.path.includes('/error')) { return abortNavigation( createError({ statusCode: 404, statusMessage: 'error page', }) ) } // inspection 페이지는 실행X ----- if (to.path.includes('/inspection')) return const event = useRequestEvent() const gameDataStore = useGameDataStore() const pageDataStore = usePageDataStore() const loadingStore = useLoadingStore() const { currentLangCode: currentLangCodeRef } = storeToRefs(gameDataStore) const currentLangCode = currentLangCodeRef.value || DEFAULT_LOCALE_CODE const stoveApiServerBaseUrl = runtimeConfig.public.stoveApiUrlServer const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl const stoveApiOrigin = import.meta.server ? stoveApiServerBaseUrl : stoveApiBaseUrl const gameDomain = getGameDomain(event ?? undefined) const pathWithoutLocale = getPathAfterLanguage(to.path) let pageDataResponse: PageDataResponse | null = null try { // 페이지 이동 시 로딩 상태 시작 loadingStore.startFullLoading() let queryParams: Record let apiUrl: string if (pathWithoutLocale === '/preview') { // 미리보기 쿼리스트링에서 파라미터 값 추출 // preview?page_seq=1&page_ver=1&lang_code=ko const queryString = to.fullPath.includes('?') ? to.fullPath.split('?')[1] : '' const urlParams = new URLSearchParams(queryString) const pageSeq = urlParams.get('page_seq') || '' const pageVer = urlParams.get('page_ver') || '' const queryLangCode = urlParams.get('lang_code') || currentLangCode apiUrl = `${stoveApiOrigin}/pub-comm/v1.0/template/page/preview` queryParams = { lang_code: queryLangCode, page_seq: pageSeq, page_ver: pageVer, } } else { apiUrl = `${stoveApiOrigin}/pub-comm/v2.0/template/page` queryParams = { game_domain: gameDomain, lang_code: currentLangCode, page_url: pathWithoutLocale, } } const cacheKey = `${apiUrl}:${JSON.stringify(queryParams)}` const cached = pageDataResponseCache.get(cacheKey) if (cached) { pageDataResponse = cached } else { pageDataResponse = (await commonFetch('GET', apiUrl, { query: queryParams, })) as PageDataResponse | null if (pageDataResponse?.code === 0 && 'value' in pageDataResponse) { pageDataResponseCache.set(cacheKey, pageDataResponse) } } if (import.meta.dev) { console.log('🚀 ~ pageData.global response:', pageDataResponse) } } catch (error) { pageDataStore.clearPageData() console.error(error) return abortNavigation( createError({ statusCode: error.statusCode, statusMessage: error.message, fatal: true, data: { reason: 'post-not-found' }, }) ) } if (pageDataResponse?.code === 0 && 'value' in pageDataResponse) { pageDataStore.clearPageData() pageDataStore.setPageData(pageDataResponse.value) } else { pageDataStore.clearPageData() // 90001 (API Respond 4xx status): API 응답 4xx 에러 // 91001 (Invalid GameCode): 게임 코드 없음 // 91003 (Invalid PageUrl): 페이지 주소 없음 if ( pageDataResponse?.code === 90001 || pageDataResponse?.code === 91001 || pageDataResponse?.code === 91003 ) { return abortNavigation( createError({ statusCode: 404, fatal: true, statusMessage: pageDataResponse?.message, data: { reason: 'post-not-found' }, }) ) } // 91002 (Invalid LangCode): 미지원 언어로 접근 if (pageDataResponse?.code === 91002) { // 이미 /home 경로에 있으면 무한 리다이렉트 방지 if (pathWithoutLocale === '/home') { return abortNavigation( createError({ statusCode: 404, statusMessage: pageDataResponse?.message, fatal: true, data: { reason: 'invalid-lang-code', }, }) ) } return navigateTo(`/${currentLangCode}/home`, { external: true }) } // [TODO] // 90004 (Not found user): 사용자 없음 // if (pageDataResponse?.code === 90043) { // return navigateTo(`/${langCode}/home`) // } } })