sales-frontend-utils 0.0.50 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +9 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -10
- package/dist/index.js.map +1 -1
- package/dist/utils/astx2-utils.cjs +1 -1
- package/dist/utils/astx2-utils.cjs.map +1 -1
- package/dist/utils/astx2-utils.js +1 -1
- package/dist/utils/astx2-utils.js.map +1 -1
- package/dist/utils/cookie-utils.cjs.map +1 -1
- package/dist/utils/cookie-utils.js.map +1 -1
- package/dist/utils/environment-utils.cjs +8 -9
- package/dist/utils/environment-utils.cjs.map +1 -1
- package/dist/utils/environment-utils.d.cts +1 -2
- package/dist/utils/environment-utils.d.ts +1 -2
- package/dist/utils/environment-utils.js +8 -9
- package/dist/utils/environment-utils.js.map +1 -1
- package/dist/utils/file-utils.cjs.map +1 -1
- package/dist/utils/file-utils.js.map +1 -1
- package/dist/utils/ga/index.cjs.map +1 -1
- package/dist/utils/ga/index.js.map +1 -1
- package/dist/utils/user-agent-utils.cjs.map +1 -1
- package/dist/utils/user-agent-utils.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/cookie-utils.ts","../../src/utils/environment-utils.ts"],"names":[],"mappings":"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","file":"environment-utils.cjs","sourcesContent":["import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cookie-utils.ts","../../src/utils/environment-utils.ts"],"names":[],"mappings":"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","file":"environment-utils.cjs","sourcesContent":["import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n"]}
|
|
@@ -66,12 +66,11 @@ declare const getCdnHostNameFromEnvironment: (currentHostname: string, forceApiH
|
|
|
66
66
|
/**
|
|
67
67
|
* @description
|
|
68
68
|
* 환경에 맞는 비정형PI 호스트명을 반환합니다.
|
|
69
|
-
* client side에서 사용하는 함수입니다.
|
|
70
69
|
* @param serviceCode dea,dis,dcm
|
|
71
70
|
* @param hostname window.location.hostname
|
|
72
71
|
* @returns
|
|
73
72
|
*/
|
|
74
|
-
declare const getDudApiBasePathFromEnvironment: (hostname
|
|
73
|
+
declare const getDudApiBasePathFromEnvironment: (hostname: string, servicePath: string) => string;
|
|
75
74
|
/**
|
|
76
75
|
* @description
|
|
77
76
|
* 환경에 맞는 Dsp 호스트명을 반환합니다.
|
|
@@ -66,12 +66,11 @@ declare const getCdnHostNameFromEnvironment: (currentHostname: string, forceApiH
|
|
|
66
66
|
/**
|
|
67
67
|
* @description
|
|
68
68
|
* 환경에 맞는 비정형PI 호스트명을 반환합니다.
|
|
69
|
-
* client side에서 사용하는 함수입니다.
|
|
70
69
|
* @param serviceCode dea,dis,dcm
|
|
71
70
|
* @param hostname window.location.hostname
|
|
72
71
|
* @returns
|
|
73
72
|
*/
|
|
74
|
-
declare const getDudApiBasePathFromEnvironment: (hostname
|
|
73
|
+
declare const getDudApiBasePathFromEnvironment: (hostname: string, servicePath: string) => string;
|
|
75
74
|
/**
|
|
76
75
|
* @description
|
|
77
76
|
* 환경에 맞는 Dsp 호스트명을 반환합니다.
|
|
@@ -22,9 +22,11 @@ var getSubdomain = (hostname) => {
|
|
|
22
22
|
return parts[0] ?? "";
|
|
23
23
|
};
|
|
24
24
|
var getEnvironmentFromHostname = (hostname) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (isClient()) {
|
|
26
|
+
const debugModeEnv = getCookie("dsp-debug-mode-env")?.toLowerCase();
|
|
27
|
+
if (debugModeEnv) {
|
|
28
|
+
return debugModeEnv;
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
const subDomain = getSubdomain(hostname);
|
|
30
32
|
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("localhost")) {
|
|
@@ -101,18 +103,15 @@ var getCdnHostNameFromEnvironment = (currentHostname, forceApiHostName) => {
|
|
|
101
103
|
return "";
|
|
102
104
|
}
|
|
103
105
|
};
|
|
104
|
-
var getDudApiBasePathFromEnvironment = (hostname) => {
|
|
105
|
-
|
|
106
|
-
return "";
|
|
107
|
-
}
|
|
108
|
-
const environment = getEnvironmentFromHostname(hostname || location.hostname);
|
|
106
|
+
var getDudApiBasePathFromEnvironment = (hostname, servicePath) => {
|
|
107
|
+
const environment = getEnvironmentFromHostname(hostname);
|
|
109
108
|
switch (environment) {
|
|
110
109
|
/**
|
|
111
110
|
* local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.
|
|
112
111
|
* (cors이슈 해결을 위해 필수)
|
|
113
112
|
*/
|
|
114
113
|
case "local":
|
|
115
|
-
return `${
|
|
114
|
+
return `${servicePath}/api/dud`;
|
|
116
115
|
/**
|
|
117
116
|
* local 이 아닌 환경에서는 전체주소를 호출합니다.
|
|
118
117
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/cookie-utils.ts","../../src/utils/environment-utils.ts"],"names":[],"mappings":"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","file":"environment-utils.js","sourcesContent":["import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cookie-utils.ts","../../src/utils/environment-utils.ts"],"names":[],"mappings":";AAEO,IAAM,SAAA,GAAY,CAAC,IAAyB,KAAA;AACjD,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAET,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAO,OAAA,EAAA;AAAA;AAET,EAAM,MAAA,KAAA,GAAQ,SAAS,MAAO,CAAA,KAAA,CAAM,IAAI,MAAO,CAAA,CAAA,OAAA,EAAU,IAAI,CAAA,QAAA,CAAU,CAAC,CAAA;AAExE,EAAA,OAAO,QAAQ,kBAAmB,CAAA,KAAA,CAAM,CAAC,CAAA,IAAK,EAAE,CAAI,GAAA,EAAA;AACtD,CAAA;;;ACLa,IAAA,YAAA,GAAe,CAAC,QAA6B,KAAA;AACxD,EAAA,IAAI,CAAC,QAAA,IAAY,QAAa,KAAA,WAAA,IAAe,aAAa,WAAa,EAAA;AACrE,IAAO,OAAA,EAAA;AAAA;AAGT,EAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA;AAGhC,EAAI,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACpB,IAAO,OAAA,EAAA;AAAA;AAIT,EAAO,OAAA,KAAA,CAAM,CAAC,CAAK,IAAA,EAAA;AACrB;AAOa,IAAA,0BAAA,GAA6B,CAAC,QAAsD,KAAA;AAE/F,EAAA,IAAI,UAAY,EAAA;AACd,IAAA,MAAM,YAAe,GAAA,SAAA,CAAU,oBAAoB,CAAA,EAAG,WAAY,EAAA;AAClE,IAAA,IAAI,YAAc,EAAA;AAChB,MAAO,OAAA,YAAA;AAAA;AACT;AAGF,EAAM,MAAA,SAAA,GAAY,aAAa,QAAQ,CAAA;AAGvC,EAAA,IAAI,aAAa,WAAe,IAAA,QAAA,KAAa,eAAe,QAAS,CAAA,UAAA,CAAW,WAAW,CAAG,EAAA;AAC5F,IAAO,OAAA,OAAA;AAAA;AAIT,EAAI,IAAA,SAAA,CAAU,QAAS,CAAA,CAAA,GAAA,CAAK,CAAG,EAAA;AAC7B,IAAO,OAAA,KAAA;AAAA;AAIT,EAAI,IAAA,SAAA,CAAU,QAAS,CAAA,KAAK,CAAG,EAAA;AAC7B,IAAO,OAAA,KAAA;AAAA;AAIT,EAAO,OAAA,KAAA;AACT;AAMO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX;AAwBO,IAAM,iBAAiB,MAAM;AAClC,EAAI,IAAA;AACF,IAAA,OAAO,OAAO,cAAmB,KAAA,IAAA;AAAA,GAC3B,CAAA,MAAA;AAEN,IAAO,OAAA,KAAA;AAAA;AAEX;AAOO,IAAM,8BAA8B,MAAM;AAC/C,EAAA,OAAO,SAAS,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAK,IAAA,EAAA;AAC5C;AAMO,IAAM,iBAAiB,MAAM;AAClC,EAAI,IAAA,OAAO,MAAO,CAAA,cAAA,KAAmB,SAAW,EAAA;AAC9C,IAAO,OAAA,EAAA;AAAA,GACF,MAAA;AACL,IAAO,OAAA,CAAA,CAAA,EAAI,6BAA6B,CAAA,CAAA;AAAA;AAE5C;AAUa,IAAA,6BAAA,GAAgC,CAAC,eAAA,EAAyB,gBAA8B,KAAA;AACnG,EAAA,IAAI,gBAAkB,EAAA;AACpB,IAAO,OAAA,gBAAA;AAAA;AAGT,EAAM,MAAA,WAAA,GAAc,2BAA2B,eAAe,CAAA;AAE9D,EAAA,QAAQ,WAAa;AAAA,IACnB,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET,KAAK,OAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,8BAAA,CAAA;AAAA,IAET;AACE,MAAA,OAAA,CAAQ,KAAK,oCAAoC,CAAA;AAEjD,MAAO,OAAA,EAAA;AAAA;AAEb;AASa,IAAA,6BAAA,GAAgC,CAAC,eAAA,EAAyB,gBAA8B,KAAA;AACnG,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAGT,EAAA,IAAI,gBAAkB,EAAA;AACpB,IAAO,OAAA,gBAAA;AAAA;AAGT,EAAM,MAAA,WAAA,GAAc,2BAA2B,eAAe,CAAA;AAE9D,EAAA,QAAQ,WAAa;AAAA,IACnB,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,qCAAA,CAAA;AAAA,IAET,KAAK,OAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,qCAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET;AACE,MAAA,OAAA,CAAQ,KAAK,gCAAgC,CAAA;AAE7C,MAAO,OAAA,EAAA;AAAA;AAEb;AASa,IAAA,gCAAA,GAAmC,CAAC,QAAA,EAAkB,WAAwB,KAAA;AAEzF,EAAM,MAAA,WAAA,GAAc,2BAA2B,QAAQ,CAAA;AAEvD,EAAA,QAAQ,WAAa;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnB,KAAK,OAAA;AACH,MAAA,OAAO,GAAG,WAAW,CAAA,QAAA,CAAA;AAAA;AAAA;AAAA;AAAA,IAIvB,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,4CAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,4CAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET;AACE,MAAA,OAAA,CAAQ,KAAK,oCAAoC,CAAA;AAEjD,MAAO,OAAA,EAAA;AAAA;AAEb;AAUa,IAAA,gCAAA,GAAmC,CAAC,aAAA,EAAuB,QAAsB,KAAA;AAC5F,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAET,EAAA,MAAM,WAAc,GAAA,0BAAA,CAA2B,QAAY,IAAA,QAAA,CAAS,QAAQ,CAAA;AAE5E,EAAA,QAAQ,WAAa;AAAA;AAAA;AAAA;AAAA;AAAA,IAKnB,KAAK,OAAA;AACH,MAAA,OAAO,CAAG,EAAA,cAAA,EAAgB,CAAA,KAAA,EAAQ,aAAa,CAAA,CAAA;AAAA;AAAA;AAAA;AAAA,IAIjD,KAAK,KAAA;AACH,MAAA,OAAO,0CAA0C,aAAa,CAAA,CAAA;AAAA,IAEhE,KAAK,KAAA;AACH,MAAA,OAAO,0CAA0C,aAAa,CAAA,CAAA;AAAA,IAEhE,KAAK,KAAA;AACH,MAAA,OAAO,sCAAsC,aAAa,CAAA,CAAA;AAAA,IAE5D;AACE,MAAA,OAAA,CAAQ,KAAK,oCAAoC,CAAA;AAEjD,MAAO,OAAA,EAAA;AAAA;AAEb;AAUa,IAAA,yBAAA,GAA4B,CAAC,QAAsB,KAAA;AAC9D,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAGT,EAAA,MAAM,WAAc,GAAA,0BAAA,CAA2B,QAAY,IAAA,QAAA,CAAS,QAAQ,CAAA;AAE5E,EAAA,QAAQ,WAAa;AAAA,IACnB,KAAK,OAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,kCAAA,CAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAO,OAAA,CAAA,8BAAA,CAAA;AAAA,IAET;AACE,MAAA,OAAA,CAAQ,KAAK,gCAAgC,CAAA;AAE7C,MAAO,OAAA,EAAA;AAAA;AAEb","file":"environment-utils.js","sourcesContent":["import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts","../../src/utils/file-utils.ts"],"names":[],"mappings":"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","file":"file-utils.cjs","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from \"./cookie-utils\";\n\nexport function base64ToBlob(base64String: string, contentType = '') {\n const regex = /^data:([a-zA-Z0-9/+.-]+);base64,/;\n const matches = base64String.match(regex);\n\n if (matches === null) {\n throw new Error('Invalid base64 string');\n }\n\n const contentTypeFinal = contentType || matches[1];\n const byteCharacters = atob(base64String.replace(regex, ''));\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n\n return new Blob([byteArray], { type: contentTypeFinal });\n}\n\nexport function base64ToFile(base64String: string, fileName: string, contentType = '') {\n const blob = base64ToBlob(base64String, contentType);\n\n if (!blob) {\n throw new Error('Invalid base64 string');\n }\n\n return blobToFile(blob, fileName);\n}\n\nexport function blobToFile(blob: Blob, fileName: string) {\n return new File([blob], fileName, {\n type: blob.type,\n lastModified: Date.now()\n });\n}\n\nexport async function fileToBase64(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * 파일확장자 리턴\n * @param data string File Blob\n */\nexport function getExt(data: string | File | Blob) {\n if (typeof data === 'string') {\n return data.split('.').pop();\n }\n\n if (data instanceof File) {\n return data.name.split('/').pop();\n }\n\n if (data instanceof Blob) {\n return data.type.split('/').pop();\n }\n}\n\nexport async function objectUrlToBlob(objectUrl: string) {\n try {\n const response = await fetch(objectUrl);\n const blob = await response.blob();\n\n return blob;\n } catch (error) {\n console.error('Error converting object URL to Blob:', error);\n throw error;\n }\n}\n\nexport async function objectUrlToBase64(objectUrl: string): Promise<string> {\n const blob = await objectUrlToBlob(objectUrl);\n\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport function downloadBlob(blob: Blob, filename: string) {\n // 1. Create a temporary URL for the Blob object\n const url = URL.createObjectURL(blob);\n\n // 2. Create a hidden anchor element\n const link = document.createElement('a');\n link.style.display = 'none';\n link.href = url;\n\n // 3. Set the 'download' attribute with the desired file name\n // This attribute forces the browser to download the URL content instead of navigating to it\n link.download = `${filename}.${getExt(blob)}`;\n\n // 4. Append the link to the body (necessary for the click to work in some browsers)\n document.body.appendChild(link);\n\n // 5. Simulate a click on the link to trigger the download\n link.click();\n\n // 6. Clean up: Remove the link and revoke the object URL\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * image url을 File Object로 변경.\n * @param imageUrl fileObject로 변경할 image url\n * @note fetch를 이용하여 변환하기때문에, 앱내 커스텀스킴을 사용하는경우는 처리불가. imageUrlToFileWithCanvas사용\n * @return file object\n */\nexport async function imageUrlToFileFetch(imageUrl: string): Promise<File> {\n\n const headers = new Headers();\n headers.append('cache-control', 'no-cache');\n const resImage = await fetch(imageUrl, { headers });\n const blob = await resImage.blob();\n const { type } = blob;\n const name = type.split('/').join('.');\n const file = new File([blob], name, { type });\n\n return file;\n}\n\nexport async function imageUrlToFile(imageUrl: string): Promise<File> {\n const fileConvertTypeCookieKey = 'dsp-debug-mode-file-convert-type';\n const fileConvertType = getCookie(fileConvertTypeCookieKey);\n\n if (fileConvertType === 'fetch') {\n return await imageUrlToFileFetch(imageUrl);\n }\n\n if (fileConvertType === 'xhr') {\n return await imageUrlToFileWithXMLHttpRequest(imageUrl);\n }\n\n return await imageUrlToFileWithCanvas(imageUrl);\n}\n\n\n/**\n * imageUrlToFile버전을 사용할수 없는경우 대체하여 사용.\n * 메모리소모가 증가하고, 이미지손실가능성이 있음.\n * 이미지원본에 대한 보존이 필수인경우 비추\n * @param imageUrl \n * @returns \n */\nexport async function imageUrlToFileWithCanvas(imageUrl: string): Promise<File> {\n const newImage = new Image();\n newImage.src = imageUrl;\n newImage.crossOrigin = 'Anonymous';\n\n return new Promise((resolve, reject) => {\n newImage.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = newImage.width;\n canvas.height = newImage.height;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.drawImage(newImage, 0, 0);\n canvas.toBlob((blob) => {\n if (blob) {\n const ext = getExt(imageUrl);\n const file = new File([blob], `image.${ext}`, { type: blob.type });\n resolve(file);\n }\n });\n }\n };\n newImage.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n}\n\nexport async function imageUrlToFileWithXMLHttpRequest(imageUrl: string): Promise<File> {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', imageUrl, true);\n xhr.responseType = 'blob';\n xhr.send();\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status === 200) {\n const blob = xhr.response; ``\n const file = new File([blob], `image.${getExt(imageUrl)}`, { type: blob.type });\n resolve(file);\n } else {\n reject(new Error(`Failed to load image: ${xhr.status}`));\n }\n };\n xhr.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n};"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts","../../src/utils/file-utils.ts"],"names":[],"mappings":"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","file":"file-utils.cjs","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from \"./cookie-utils\";\n\nexport function base64ToBlob(base64String: string, contentType = '') {\n const regex = /^data:([a-zA-Z0-9/+.-]+);base64,/;\n const matches = base64String.match(regex);\n\n if (matches === null) {\n throw new Error('Invalid base64 string');\n }\n\n const contentTypeFinal = contentType || matches[1];\n const byteCharacters = atob(base64String.replace(regex, ''));\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n\n return new Blob([byteArray], { type: contentTypeFinal });\n}\n\nexport function base64ToFile(base64String: string, fileName: string, contentType = '') {\n const blob = base64ToBlob(base64String, contentType);\n\n if (!blob) {\n throw new Error('Invalid base64 string');\n }\n\n return blobToFile(blob, fileName);\n}\n\nexport function blobToFile(blob: Blob, fileName: string) {\n return new File([blob], fileName, {\n type: blob.type,\n lastModified: Date.now()\n });\n}\n\nexport async function fileToBase64(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * 파일확장자 리턴\n * @param data string File Blob\n */\nexport function getExt(data: string | File | Blob) {\n if (typeof data === 'string') {\n return data.split('.').pop();\n }\n\n if (data instanceof File) {\n return data.name.split('/').pop();\n }\n\n if (data instanceof Blob) {\n return data.type.split('/').pop();\n }\n}\n\nexport async function objectUrlToBlob(objectUrl: string) {\n try {\n const response = await fetch(objectUrl);\n const blob = await response.blob();\n\n return blob;\n } catch (error) {\n console.error('Error converting object URL to Blob:', error);\n throw error;\n }\n}\n\nexport async function objectUrlToBase64(objectUrl: string): Promise<string> {\n const blob = await objectUrlToBlob(objectUrl);\n\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport function downloadBlob(blob: Blob, filename: string) {\n // 1. Create a temporary URL for the Blob object\n const url = URL.createObjectURL(blob);\n\n // 2. Create a hidden anchor element\n const link = document.createElement('a');\n link.style.display = 'none';\n link.href = url;\n\n // 3. Set the 'download' attribute with the desired file name\n // This attribute forces the browser to download the URL content instead of navigating to it\n link.download = `${filename}.${getExt(blob)}`;\n\n // 4. Append the link to the body (necessary for the click to work in some browsers)\n document.body.appendChild(link);\n\n // 5. Simulate a click on the link to trigger the download\n link.click();\n\n // 6. Clean up: Remove the link and revoke the object URL\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * image url을 File Object로 변경.\n * @param imageUrl fileObject로 변경할 image url\n * @note fetch를 이용하여 변환하기때문에, 앱내 커스텀스킴을 사용하는경우는 처리불가. imageUrlToFileWithCanvas사용\n * @return file object\n */\nexport async function imageUrlToFileFetch(imageUrl: string): Promise<File> {\n\n const headers = new Headers();\n headers.append('cache-control', 'no-cache');\n const resImage = await fetch(imageUrl, { headers });\n const blob = await resImage.blob();\n const { type } = blob;\n const name = type.split('/').join('.');\n const file = new File([blob], name, { type });\n\n return file;\n}\n\nexport async function imageUrlToFile(imageUrl: string): Promise<File> {\n const fileConvertTypeCookieKey = 'dsp-debug-mode-file-convert-type';\n const fileConvertType = getCookie(fileConvertTypeCookieKey);\n\n if (fileConvertType === 'fetch') {\n return await imageUrlToFileFetch(imageUrl);\n }\n\n if (fileConvertType === 'xhr') {\n return await imageUrlToFileWithXMLHttpRequest(imageUrl);\n }\n\n return await imageUrlToFileWithCanvas(imageUrl);\n}\n\n\n/**\n * imageUrlToFile버전을 사용할수 없는경우 대체하여 사용.\n * 메모리소모가 증가하고, 이미지손실가능성이 있음.\n * 이미지원본에 대한 보존이 필수인경우 비추\n * @param imageUrl \n * @returns \n */\nexport async function imageUrlToFileWithCanvas(imageUrl: string): Promise<File> {\n const newImage = new Image();\n newImage.src = imageUrl;\n newImage.crossOrigin = 'Anonymous';\n\n return new Promise((resolve, reject) => {\n newImage.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = newImage.width;\n canvas.height = newImage.height;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.drawImage(newImage, 0, 0);\n canvas.toBlob((blob) => {\n if (blob) {\n const ext = getExt(imageUrl);\n const file = new File([blob], `image.${ext}`, { type: blob.type });\n resolve(file);\n }\n });\n }\n };\n newImage.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n}\n\nexport async function imageUrlToFileWithXMLHttpRequest(imageUrl: string): Promise<File> {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', imageUrl, true);\n xhr.responseType = 'blob';\n xhr.send();\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status === 200) {\n const blob = xhr.response; ``\n const file = new File([blob], `image.${getExt(imageUrl)}`, { type: blob.type });\n resolve(file);\n } else {\n reject(new Error(`Failed to load image: ${xhr.status}`));\n }\n };\n xhr.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n};"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts","../../src/utils/file-utils.ts"],"names":[],"mappings":";AA0DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;AC9DO,IAAM,SAAA,GAAY,CAAC,IAAyB,KAAA;AACjD,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAET,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAO,OAAA,EAAA;AAAA;AAET,EAAM,MAAA,KAAA,GAAQ,SAAS,MAAO,CAAA,KAAA,CAAM,IAAI,MAAO,CAAA,CAAA,OAAA,EAAU,IAAI,CAAA,QAAA,CAAU,CAAC,CAAA;AAExE,EAAA,OAAO,QAAQ,kBAAmB,CAAA,KAAA,CAAM,CAAC,CAAA,IAAK,EAAE,CAAI,GAAA,EAAA;AACtD,CAAA;;;ACVO,SAAS,YAAA,CAAa,YAAsB,EAAA,WAAA,GAAc,EAAI,EAAA;AACnE,EAAA,MAAM,KAAQ,GAAA,kCAAA;AACd,EAAM,MAAA,OAAA,GAAU,YAAa,CAAA,KAAA,CAAM,KAAK,CAAA;AAExC,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAM,MAAA,gBAAA,GAAmB,WAAe,IAAA,OAAA,CAAQ,CAAC,CAAA;AACjD,EAAA,MAAM,iBAAiB,IAAK,CAAA,YAAA,CAAa,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAC,CAAA;AAC3D,EAAA,MAAM,WAAc,GAAA,IAAI,KAAM,CAAA,cAAA,CAAe,MAAM,CAAA;AACnD,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,cAAA,CAAe,QAAQ,CAAK,EAAA,EAAA;AAC9C,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,cAAe,CAAA,UAAA,CAAW,CAAC,CAAA;AAAA;AAG9C,EAAM,MAAA,SAAA,GAAY,IAAI,UAAA,CAAW,WAAW,CAAA;AAE5C,EAAO,OAAA,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,IAAA,EAAM,kBAAkB,CAAA;AACzD;AAEO,SAAS,YAAa,CAAA,YAAA,EAAsB,QAAkB,EAAA,WAAA,GAAc,EAAI,EAAA;AACrF,EAAM,MAAA,IAAA,GAAO,YAAa,CAAA,YAAA,EAAc,WAAW,CAAA;AAEnD,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAO,OAAA,UAAA,CAAW,MAAM,QAAQ,CAAA;AAClC;AAEO,SAAS,UAAA,CAAW,MAAY,QAAkB,EAAA;AACvD,EAAA,OAAO,IAAI,IAAA,CAAK,CAAC,IAAI,GAAG,QAAU,EAAA;AAAA,IAChC,MAAM,IAAK,CAAA,IAAA;AAAA,IACX,YAAA,EAAc,KAAK,GAAI;AAAA,GACxB,CAAA;AACH;AAEA,eAAsB,aAAa,IAAoC,EAAA;AACrE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA;AAE9B,IAAA,MAAA,CAAO,SAAS,MAAM;AACpB,MAAI,IAAA,OAAO,MAAO,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,OAChB,MAAA;AACL,QAAO,MAAA,CAAA,IAAI,KAAM,CAAA,mBAAmB,CAAC,CAAA;AAAA;AACvC,KACF;AAEA,IAAO,MAAA,CAAA,OAAA,GAAU,CAAC,KAAU,KAAA;AAC1B,MAAA,MAAA,CAAO,KAAK,CAAA;AAAA,KACd;AAEA,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,GAC1B,CAAA;AACH;AAMO,SAAS,OAAO,IAA4B,EAAA;AACjD,EAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,GAAI,EAAA;AAAA;AAG7B,EAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,IAAA,OAAO,IAAK,CAAA,IAAA,CAAK,KAAM,CAAA,GAAG,EAAE,GAAI,EAAA;AAAA;AAGlC,EAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,IAAA,OAAO,IAAK,CAAA,IAAA,CAAK,KAAM,CAAA,GAAG,EAAE,GAAI,EAAA;AAAA;AAEpC;AAEA,eAAsB,gBAAgB,SAAmB,EAAA;AACvD,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,SAAS,CAAA;AACtC,IAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA;AAEjC,IAAO,OAAA,IAAA;AAAA,WACA,KAAO,EAAA;AACd,IAAQ,OAAA,CAAA,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAC3D,IAAM,MAAA,KAAA;AAAA;AAEV;AAEA,eAAsB,kBAAkB,SAAoC,EAAA;AAC1E,EAAM,MAAA,IAAA,GAAO,MAAM,eAAA,CAAgB,SAAS,CAAA;AAE5C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA;AAC9B,IAAA,MAAA,CAAO,YAAY,MAAM;AACvB,MAAI,IAAA,OAAO,MAAO,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,OAChB,MAAA;AACL,QAAO,MAAA,CAAA,IAAI,KAAM,CAAA,mBAAmB,CAAC,CAAA;AAAA;AACvC,KACF;AACA,IAAA,MAAA,CAAO,OAAU,GAAA,MAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,GAC1B,CAAA;AACH;AAEO,SAAS,YAAA,CAAa,MAAY,QAAkB,EAAA;AAEzD,EAAM,MAAA,GAAA,GAAM,GAAI,CAAA,eAAA,CAAgB,IAAI,CAAA;AAGpC,EAAM,MAAA,IAAA,GAAO,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA;AACvC,EAAA,IAAA,CAAK,MAAM,OAAU,GAAA,MAAA;AACrB,EAAA,IAAA,CAAK,IAAO,GAAA,GAAA;AAIZ,EAAA,IAAA,CAAK,WAAW,CAAG,EAAA,QAAQ,CAAI,CAAA,EAAA,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA;AAG3C,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAG9B,EAAA,IAAA,CAAK,KAAM,EAAA;AAGX,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAC9B,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;AAQA,eAAsB,oBAAoB,QAAiC,EAAA;AAEzE,EAAM,MAAA,OAAA,GAAU,IAAI,OAAQ,EAAA;AAC5B,EAAQ,OAAA,CAAA,MAAA,CAAO,iBAAiB,UAAU,CAAA;AAC1C,EAAA,MAAM,WAAW,MAAM,KAAA,CAAM,QAAU,EAAA,EAAE,SAAS,CAAA;AAClD,EAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA;AACjC,EAAM,MAAA,EAAE,MAAS,GAAA,IAAA;AACjB,EAAA,MAAM,OAAO,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AACrC,EAAM,MAAA,IAAA,GAAO,IAAI,IAAK,CAAA,CAAC,IAAI,CAAG,EAAA,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA;AAE5C,EAAO,OAAA,IAAA;AACT;AAEA,eAAsB,eAAe,QAAiC,EAAA;AACpE,EAAA,MAAM,wBAA2B,GAAA,kCAAA;AACjC,EAAM,MAAA,eAAA,GAAkB,UAAU,wBAAwB,CAAA;AAE1D,EAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,IAAO,OAAA,MAAM,oBAAoB,QAAQ,CAAA;AAAA;AAG3C,EAAA,IAAI,oBAAoB,KAAO,EAAA;AAC7B,IAAO,OAAA,MAAM,iCAAiC,QAAQ,CAAA;AAAA;AAGxD,EAAO,OAAA,MAAM,yBAAyB,QAAQ,CAAA;AAChD;AAUA,eAAsB,yBAAyB,QAAiC,EAAA;AAC9E,EAAM,MAAA,QAAA,GAAW,IAAI,KAAM,EAAA;AAC3B,EAAA,QAAA,CAAS,GAAM,GAAA,QAAA;AACf,EAAA,QAAA,CAAS,WAAc,GAAA,WAAA;AAEvB,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAA,QAAA,CAAS,SAAS,MAAM;AACtB,MAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAA,CAAO,QAAQ,QAAS,CAAA,KAAA;AACxB,MAAA,MAAA,CAAO,SAAS,QAAS,CAAA,MAAA;AACzB,MAAM,MAAA,GAAA,GAAM,MAAO,CAAA,UAAA,CAAW,IAAI,CAAA;AAClC,MAAA,IAAI,GAAK,EAAA;AACP,QAAI,GAAA,CAAA,SAAA,CAAU,QAAU,EAAA,CAAA,EAAG,CAAC,CAAA;AAC5B,QAAO,MAAA,CAAA,MAAA,CAAO,CAAC,IAAS,KAAA;AACtB,UAAA,IAAI,IAAM,EAAA;AACR,YAAM,MAAA,GAAA,GAAM,OAAO,QAAQ,CAAA;AAC3B,YAAA,MAAM,IAAO,GAAA,IAAI,IAAK,CAAA,CAAC,IAAI,CAAA,EAAG,CAAS,MAAA,EAAA,GAAG,CAAI,CAAA,EAAA,EAAE,IAAM,EAAA,IAAA,CAAK,MAAM,CAAA;AACjE,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA;AACd,SACD,CAAA;AAAA;AACH,KACF;AACA,IAAS,QAAA,CAAA,OAAA,GAAU,CAAC,CAAM,KAAA;AACxB,MAAO,MAAA,CAAA,IAAA,CAAK,SAAU,CAAA,CAAC,CAAC,CAAA;AAAA,KAC1B;AAAA,GACD,CAAA;AACH;AAEA,eAAsB,iCAAiC,QAAiC,EAAA;AACtF,EAAM,MAAA,GAAA,GAAM,IAAI,cAAe,EAAA;AAC/B,EAAI,GAAA,CAAA,IAAA,CAAK,KAAO,EAAA,QAAA,EAAU,IAAI,CAAA;AAC9B,EAAA,GAAA,CAAI,YAAe,GAAA,MAAA;AACnB,EAAA,GAAA,CAAI,IAAK,EAAA;AAET,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAA,GAAA,CAAI,SAAS,MAAM;AACjB,MAAI,IAAA,GAAA,CAAI,WAAW,GAAK,EAAA;AACtB,QAAA,MAAM,OAAO,GAAI,CAAA,QAAA;AACjB,QAAA,MAAM,IAAO,GAAA,IAAI,IAAK,CAAA,CAAC,IAAI,CAAG,EAAA,CAAA,MAAA,EAAS,MAAO,CAAA,QAAQ,CAAC,CAAI,CAAA,EAAA,EAAE,IAAM,EAAA,IAAA,CAAK,MAAM,CAAA;AAC9E,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,OACP,MAAA;AACL,QAAA,MAAA,CAAO,IAAI,KAAM,CAAA,CAAA,sBAAA,EAAyB,GAAI,CAAA,MAAM,EAAE,CAAC,CAAA;AAAA;AACzD,KACF;AACA,IAAI,GAAA,CAAA,OAAA,GAAU,CAAC,CAAM,KAAA;AACnB,MAAO,MAAA,CAAA,IAAA,CAAK,SAAU,CAAA,CAAC,CAAC,CAAA;AAAA,KAC1B;AAAA,GACD,CAAA;AACH","file":"file-utils.js","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from \"./cookie-utils\";\n\nexport function base64ToBlob(base64String: string, contentType = '') {\n const regex = /^data:([a-zA-Z0-9/+.-]+);base64,/;\n const matches = base64String.match(regex);\n\n if (matches === null) {\n throw new Error('Invalid base64 string');\n }\n\n const contentTypeFinal = contentType || matches[1];\n const byteCharacters = atob(base64String.replace(regex, ''));\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n\n return new Blob([byteArray], { type: contentTypeFinal });\n}\n\nexport function base64ToFile(base64String: string, fileName: string, contentType = '') {\n const blob = base64ToBlob(base64String, contentType);\n\n if (!blob) {\n throw new Error('Invalid base64 string');\n }\n\n return blobToFile(blob, fileName);\n}\n\nexport function blobToFile(blob: Blob, fileName: string) {\n return new File([blob], fileName, {\n type: blob.type,\n lastModified: Date.now()\n });\n}\n\nexport async function fileToBase64(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * 파일확장자 리턴\n * @param data string File Blob\n */\nexport function getExt(data: string | File | Blob) {\n if (typeof data === 'string') {\n return data.split('.').pop();\n }\n\n if (data instanceof File) {\n return data.name.split('/').pop();\n }\n\n if (data instanceof Blob) {\n return data.type.split('/').pop();\n }\n}\n\nexport async function objectUrlToBlob(objectUrl: string) {\n try {\n const response = await fetch(objectUrl);\n const blob = await response.blob();\n\n return blob;\n } catch (error) {\n console.error('Error converting object URL to Blob:', error);\n throw error;\n }\n}\n\nexport async function objectUrlToBase64(objectUrl: string): Promise<string> {\n const blob = await objectUrlToBlob(objectUrl);\n\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport function downloadBlob(blob: Blob, filename: string) {\n // 1. Create a temporary URL for the Blob object\n const url = URL.createObjectURL(blob);\n\n // 2. Create a hidden anchor element\n const link = document.createElement('a');\n link.style.display = 'none';\n link.href = url;\n\n // 3. Set the 'download' attribute with the desired file name\n // This attribute forces the browser to download the URL content instead of navigating to it\n link.download = `${filename}.${getExt(blob)}`;\n\n // 4. Append the link to the body (necessary for the click to work in some browsers)\n document.body.appendChild(link);\n\n // 5. Simulate a click on the link to trigger the download\n link.click();\n\n // 6. Clean up: Remove the link and revoke the object URL\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * image url을 File Object로 변경.\n * @param imageUrl fileObject로 변경할 image url\n * @note fetch를 이용하여 변환하기때문에, 앱내 커스텀스킴을 사용하는경우는 처리불가. imageUrlToFileWithCanvas사용\n * @return file object\n */\nexport async function imageUrlToFileFetch(imageUrl: string): Promise<File> {\n\n const headers = new Headers();\n headers.append('cache-control', 'no-cache');\n const resImage = await fetch(imageUrl, { headers });\n const blob = await resImage.blob();\n const { type } = blob;\n const name = type.split('/').join('.');\n const file = new File([blob], name, { type });\n\n return file;\n}\n\nexport async function imageUrlToFile(imageUrl: string): Promise<File> {\n const fileConvertTypeCookieKey = 'dsp-debug-mode-file-convert-type';\n const fileConvertType = getCookie(fileConvertTypeCookieKey);\n\n if (fileConvertType === 'fetch') {\n return await imageUrlToFileFetch(imageUrl);\n }\n\n if (fileConvertType === 'xhr') {\n return await imageUrlToFileWithXMLHttpRequest(imageUrl);\n }\n\n return await imageUrlToFileWithCanvas(imageUrl);\n}\n\n\n/**\n * imageUrlToFile버전을 사용할수 없는경우 대체하여 사용.\n * 메모리소모가 증가하고, 이미지손실가능성이 있음.\n * 이미지원본에 대한 보존이 필수인경우 비추\n * @param imageUrl \n * @returns \n */\nexport async function imageUrlToFileWithCanvas(imageUrl: string): Promise<File> {\n const newImage = new Image();\n newImage.src = imageUrl;\n newImage.crossOrigin = 'Anonymous';\n\n return new Promise((resolve, reject) => {\n newImage.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = newImage.width;\n canvas.height = newImage.height;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.drawImage(newImage, 0, 0);\n canvas.toBlob((blob) => {\n if (blob) {\n const ext = getExt(imageUrl);\n const file = new File([blob], `image.${ext}`, { type: blob.type });\n resolve(file);\n }\n });\n }\n };\n newImage.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n}\n\nexport async function imageUrlToFileWithXMLHttpRequest(imageUrl: string): Promise<File> {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', imageUrl, true);\n xhr.responseType = 'blob';\n xhr.send();\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status === 200) {\n const blob = xhr.response; ``\n const file = new File([blob], `image.${getExt(imageUrl)}`, { type: blob.type });\n resolve(file);\n } else {\n reject(new Error(`Failed to load image: ${xhr.status}`));\n }\n };\n xhr.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n};"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts","../../src/utils/file-utils.ts"],"names":[],"mappings":";AA8DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;AClEO,IAAM,SAAA,GAAY,CAAC,IAAyB,KAAA;AACjD,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAET,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAO,OAAA,EAAA;AAAA;AAET,EAAM,MAAA,KAAA,GAAQ,SAAS,MAAO,CAAA,KAAA,CAAM,IAAI,MAAO,CAAA,CAAA,OAAA,EAAU,IAAI,CAAA,QAAA,CAAU,CAAC,CAAA;AAExE,EAAA,OAAO,QAAQ,kBAAmB,CAAA,KAAA,CAAM,CAAC,CAAA,IAAK,EAAE,CAAI,GAAA,EAAA;AACtD,CAAA;;;ACVO,SAAS,YAAA,CAAa,YAAsB,EAAA,WAAA,GAAc,EAAI,EAAA;AACnE,EAAA,MAAM,KAAQ,GAAA,kCAAA;AACd,EAAM,MAAA,OAAA,GAAU,YAAa,CAAA,KAAA,CAAM,KAAK,CAAA;AAExC,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAM,MAAA,gBAAA,GAAmB,WAAe,IAAA,OAAA,CAAQ,CAAC,CAAA;AACjD,EAAA,MAAM,iBAAiB,IAAK,CAAA,YAAA,CAAa,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAC,CAAA;AAC3D,EAAA,MAAM,WAAc,GAAA,IAAI,KAAM,CAAA,cAAA,CAAe,MAAM,CAAA;AACnD,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,cAAA,CAAe,QAAQ,CAAK,EAAA,EAAA;AAC9C,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,cAAe,CAAA,UAAA,CAAW,CAAC,CAAA;AAAA;AAG9C,EAAM,MAAA,SAAA,GAAY,IAAI,UAAA,CAAW,WAAW,CAAA;AAE5C,EAAO,OAAA,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,IAAA,EAAM,kBAAkB,CAAA;AACzD;AAEO,SAAS,YAAa,CAAA,YAAA,EAAsB,QAAkB,EAAA,WAAA,GAAc,EAAI,EAAA;AACrF,EAAM,MAAA,IAAA,GAAO,YAAa,CAAA,YAAA,EAAc,WAAW,CAAA;AAEnD,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAM,MAAA,IAAI,MAAM,uBAAuB,CAAA;AAAA;AAGzC,EAAO,OAAA,UAAA,CAAW,MAAM,QAAQ,CAAA;AAClC;AAEO,SAAS,UAAA,CAAW,MAAY,QAAkB,EAAA;AACvD,EAAA,OAAO,IAAI,IAAA,CAAK,CAAC,IAAI,GAAG,QAAU,EAAA;AAAA,IAChC,MAAM,IAAK,CAAA,IAAA;AAAA,IACX,YAAA,EAAc,KAAK,GAAI;AAAA,GACxB,CAAA;AACH;AAEA,eAAsB,aAAa,IAAoC,EAAA;AACrE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA;AAE9B,IAAA,MAAA,CAAO,SAAS,MAAM;AACpB,MAAI,IAAA,OAAO,MAAO,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,OAChB,MAAA;AACL,QAAO,MAAA,CAAA,IAAI,KAAM,CAAA,mBAAmB,CAAC,CAAA;AAAA;AACvC,KACF;AAEA,IAAO,MAAA,CAAA,OAAA,GAAU,CAAC,KAAU,KAAA;AAC1B,MAAA,MAAA,CAAO,KAAK,CAAA;AAAA,KACd;AAEA,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,GAC1B,CAAA;AACH;AAMO,SAAS,OAAO,IAA4B,EAAA;AACjD,EAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,GAAI,EAAA;AAAA;AAG7B,EAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,IAAA,OAAO,IAAK,CAAA,IAAA,CAAK,KAAM,CAAA,GAAG,EAAE,GAAI,EAAA;AAAA;AAGlC,EAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,IAAA,OAAO,IAAK,CAAA,IAAA,CAAK,KAAM,CAAA,GAAG,EAAE,GAAI,EAAA;AAAA;AAEpC;AAEA,eAAsB,gBAAgB,SAAmB,EAAA;AACvD,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,SAAS,CAAA;AACtC,IAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA;AAEjC,IAAO,OAAA,IAAA;AAAA,WACA,KAAO,EAAA;AACd,IAAQ,OAAA,CAAA,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAC3D,IAAM,MAAA,KAAA;AAAA;AAEV;AAEA,eAAsB,kBAAkB,SAAoC,EAAA;AAC1E,EAAM,MAAA,IAAA,GAAO,MAAM,eAAA,CAAgB,SAAS,CAAA;AAE5C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA;AAC9B,IAAA,MAAA,CAAO,YAAY,MAAM;AACvB,MAAI,IAAA,OAAO,MAAO,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,OAChB,MAAA;AACL,QAAO,MAAA,CAAA,IAAI,KAAM,CAAA,mBAAmB,CAAC,CAAA;AAAA;AACvC,KACF;AACA,IAAA,MAAA,CAAO,OAAU,GAAA,MAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,GAC1B,CAAA;AACH;AAEO,SAAS,YAAA,CAAa,MAAY,QAAkB,EAAA;AAEzD,EAAM,MAAA,GAAA,GAAM,GAAI,CAAA,eAAA,CAAgB,IAAI,CAAA;AAGpC,EAAM,MAAA,IAAA,GAAO,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA;AACvC,EAAA,IAAA,CAAK,MAAM,OAAU,GAAA,MAAA;AACrB,EAAA,IAAA,CAAK,IAAO,GAAA,GAAA;AAIZ,EAAA,IAAA,CAAK,WAAW,CAAG,EAAA,QAAQ,CAAI,CAAA,EAAA,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA;AAG3C,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAG9B,EAAA,IAAA,CAAK,KAAM,EAAA;AAGX,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAC9B,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;AAQA,eAAsB,oBAAoB,QAAiC,EAAA;AAEzE,EAAM,MAAA,OAAA,GAAU,IAAI,OAAQ,EAAA;AAC5B,EAAQ,OAAA,CAAA,MAAA,CAAO,iBAAiB,UAAU,CAAA;AAC1C,EAAA,MAAM,WAAW,MAAM,KAAA,CAAM,QAAU,EAAA,EAAE,SAAS,CAAA;AAClD,EAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA;AACjC,EAAM,MAAA,EAAE,MAAS,GAAA,IAAA;AACjB,EAAA,MAAM,OAAO,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AACrC,EAAM,MAAA,IAAA,GAAO,IAAI,IAAK,CAAA,CAAC,IAAI,CAAG,EAAA,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA;AAE5C,EAAO,OAAA,IAAA;AACT;AAEA,eAAsB,eAAe,QAAiC,EAAA;AACpE,EAAA,MAAM,wBAA2B,GAAA,kCAAA;AACjC,EAAM,MAAA,eAAA,GAAkB,UAAU,wBAAwB,CAAA;AAE1D,EAAA,IAAI,oBAAoB,OAAS,EAAA;AAC/B,IAAO,OAAA,MAAM,oBAAoB,QAAQ,CAAA;AAAA;AAG3C,EAAA,IAAI,oBAAoB,KAAO,EAAA;AAC7B,IAAO,OAAA,MAAM,iCAAiC,QAAQ,CAAA;AAAA;AAGxD,EAAO,OAAA,MAAM,yBAAyB,QAAQ,CAAA;AAChD;AAUA,eAAsB,yBAAyB,QAAiC,EAAA;AAC9E,EAAM,MAAA,QAAA,GAAW,IAAI,KAAM,EAAA;AAC3B,EAAA,QAAA,CAAS,GAAM,GAAA,QAAA;AACf,EAAA,QAAA,CAAS,WAAc,GAAA,WAAA;AAEvB,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAA,QAAA,CAAS,SAAS,MAAM;AACtB,MAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAA,CAAO,QAAQ,QAAS,CAAA,KAAA;AACxB,MAAA,MAAA,CAAO,SAAS,QAAS,CAAA,MAAA;AACzB,MAAM,MAAA,GAAA,GAAM,MAAO,CAAA,UAAA,CAAW,IAAI,CAAA;AAClC,MAAA,IAAI,GAAK,EAAA;AACP,QAAI,GAAA,CAAA,SAAA,CAAU,QAAU,EAAA,CAAA,EAAG,CAAC,CAAA;AAC5B,QAAO,MAAA,CAAA,MAAA,CAAO,CAAC,IAAS,KAAA;AACtB,UAAA,IAAI,IAAM,EAAA;AACR,YAAM,MAAA,GAAA,GAAM,OAAO,QAAQ,CAAA;AAC3B,YAAA,MAAM,IAAO,GAAA,IAAI,IAAK,CAAA,CAAC,IAAI,CAAA,EAAG,CAAS,MAAA,EAAA,GAAG,CAAI,CAAA,EAAA,EAAE,IAAM,EAAA,IAAA,CAAK,MAAM,CAAA;AACjE,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA;AACd,SACD,CAAA;AAAA;AACH,KACF;AACA,IAAS,QAAA,CAAA,OAAA,GAAU,CAAC,CAAM,KAAA;AACxB,MAAO,MAAA,CAAA,IAAA,CAAK,SAAU,CAAA,CAAC,CAAC,CAAA;AAAA,KAC1B;AAAA,GACD,CAAA;AACH;AAEA,eAAsB,iCAAiC,QAAiC,EAAA;AACtF,EAAM,MAAA,GAAA,GAAM,IAAI,cAAe,EAAA;AAC/B,EAAI,GAAA,CAAA,IAAA,CAAK,KAAO,EAAA,QAAA,EAAU,IAAI,CAAA;AAC9B,EAAA,GAAA,CAAI,YAAe,GAAA,MAAA;AACnB,EAAA,GAAA,CAAI,IAAK,EAAA;AAET,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,IAAA,GAAA,CAAI,SAAS,MAAM;AACjB,MAAI,IAAA,GAAA,CAAI,WAAW,GAAK,EAAA;AACtB,QAAA,MAAM,OAAO,GAAI,CAAA,QAAA;AACjB,QAAA,MAAM,IAAO,GAAA,IAAI,IAAK,CAAA,CAAC,IAAI,CAAG,EAAA,CAAA,MAAA,EAAS,MAAO,CAAA,QAAQ,CAAC,CAAI,CAAA,EAAA,EAAE,IAAM,EAAA,IAAA,CAAK,MAAM,CAAA;AAC9E,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,OACP,MAAA;AACL,QAAA,MAAA,CAAO,IAAI,KAAM,CAAA,CAAA,sBAAA,EAAyB,GAAI,CAAA,MAAM,EAAE,CAAC,CAAA;AAAA;AACzD,KACF;AACA,IAAI,GAAA,CAAA,OAAA,GAAU,CAAC,CAAM,KAAA;AACnB,MAAO,MAAA,CAAA,IAAA,CAAK,SAAU,CAAA,CAAC,CAAC,CAAA;AAAA,KAC1B;AAAA,GACD,CAAA;AACH","file":"file-utils.js","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","import { isClient } from \"./environment-utils\";\n\nexport const getCookie = (name: string): string => {\n if (!isClient()) {\n return '';\n }\n if (typeof document === 'undefined') {\n return '';\n }\n const match = document.cookie.match(new RegExp(`(^|; *)${name}=([^;]*)`));\n\n return match ? decodeURIComponent(match[2] || '') : '';\n};\n\nexport const setCookie = (\n name: string,\n value: string,\n options: {\n expires?: number | Date; // number of days\n path?: string;\n domain?: string;\n secure?: boolean;\n } = {}\n): void => {\n if (!isClient()) {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n\n if (options.expires) {\n let expiresDate: Date;\n if (typeof options.expires === 'number') {\n expiresDate = new Date();\n expiresDate.setDate(expiresDate.getDate() + options.expires);\n } else {\n expiresDate = options.expires;\n }\n cookieString += `; expires=${expiresDate.toUTCString()}`;\n }\n\n cookieString += `; path=${options.path || '/'}`;\n\n if (options.domain) {\n cookieString += `; domain=${options.domain}`;\n }\n\n if (options.secure) {\n cookieString += '; secure';\n }\n\n document.cookie = cookieString;\n};\n\nexport const deleteCookie = (name: string, options: { path?: string; domain?: string } = {}): void => {\n if (!isClient()) {\n return;\n }\n setCookie(name, '', { ...options, expires: -1 });\n};\n","import { getCookie } from \"./cookie-utils\";\n\nexport function base64ToBlob(base64String: string, contentType = '') {\n const regex = /^data:([a-zA-Z0-9/+.-]+);base64,/;\n const matches = base64String.match(regex);\n\n if (matches === null) {\n throw new Error('Invalid base64 string');\n }\n\n const contentTypeFinal = contentType || matches[1];\n const byteCharacters = atob(base64String.replace(regex, ''));\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n\n return new Blob([byteArray], { type: contentTypeFinal });\n}\n\nexport function base64ToFile(base64String: string, fileName: string, contentType = '') {\n const blob = base64ToBlob(base64String, contentType);\n\n if (!blob) {\n throw new Error('Invalid base64 string');\n }\n\n return blobToFile(blob, fileName);\n}\n\nexport function blobToFile(blob: Blob, fileName: string) {\n return new File([blob], fileName, {\n type: blob.type,\n lastModified: Date.now()\n });\n}\n\nexport async function fileToBase64(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * 파일확장자 리턴\n * @param data string File Blob\n */\nexport function getExt(data: string | File | Blob) {\n if (typeof data === 'string') {\n return data.split('.').pop();\n }\n\n if (data instanceof File) {\n return data.name.split('/').pop();\n }\n\n if (data instanceof Blob) {\n return data.type.split('/').pop();\n }\n}\n\nexport async function objectUrlToBlob(objectUrl: string) {\n try {\n const response = await fetch(objectUrl);\n const blob = await response.blob();\n\n return blob;\n } catch (error) {\n console.error('Error converting object URL to Blob:', error);\n throw error;\n }\n}\n\nexport async function objectUrlToBase64(objectUrl: string): Promise<string> {\n const blob = await objectUrlToBlob(objectUrl);\n\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n } else {\n reject(new Error('Invalid file type'));\n }\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport function downloadBlob(blob: Blob, filename: string) {\n // 1. Create a temporary URL for the Blob object\n const url = URL.createObjectURL(blob);\n\n // 2. Create a hidden anchor element\n const link = document.createElement('a');\n link.style.display = 'none';\n link.href = url;\n\n // 3. Set the 'download' attribute with the desired file name\n // This attribute forces the browser to download the URL content instead of navigating to it\n link.download = `${filename}.${getExt(blob)}`;\n\n // 4. Append the link to the body (necessary for the click to work in some browsers)\n document.body.appendChild(link);\n\n // 5. Simulate a click on the link to trigger the download\n link.click();\n\n // 6. Clean up: Remove the link and revoke the object URL\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * image url을 File Object로 변경.\n * @param imageUrl fileObject로 변경할 image url\n * @note fetch를 이용하여 변환하기때문에, 앱내 커스텀스킴을 사용하는경우는 처리불가. imageUrlToFileWithCanvas사용\n * @return file object\n */\nexport async function imageUrlToFileFetch(imageUrl: string): Promise<File> {\n\n const headers = new Headers();\n headers.append('cache-control', 'no-cache');\n const resImage = await fetch(imageUrl, { headers });\n const blob = await resImage.blob();\n const { type } = blob;\n const name = type.split('/').join('.');\n const file = new File([blob], name, { type });\n\n return file;\n}\n\nexport async function imageUrlToFile(imageUrl: string): Promise<File> {\n const fileConvertTypeCookieKey = 'dsp-debug-mode-file-convert-type';\n const fileConvertType = getCookie(fileConvertTypeCookieKey);\n\n if (fileConvertType === 'fetch') {\n return await imageUrlToFileFetch(imageUrl);\n }\n\n if (fileConvertType === 'xhr') {\n return await imageUrlToFileWithXMLHttpRequest(imageUrl);\n }\n\n return await imageUrlToFileWithCanvas(imageUrl);\n}\n\n\n/**\n * imageUrlToFile버전을 사용할수 없는경우 대체하여 사용.\n * 메모리소모가 증가하고, 이미지손실가능성이 있음.\n * 이미지원본에 대한 보존이 필수인경우 비추\n * @param imageUrl \n * @returns \n */\nexport async function imageUrlToFileWithCanvas(imageUrl: string): Promise<File> {\n const newImage = new Image();\n newImage.src = imageUrl;\n newImage.crossOrigin = 'Anonymous';\n\n return new Promise((resolve, reject) => {\n newImage.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = newImage.width;\n canvas.height = newImage.height;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.drawImage(newImage, 0, 0);\n canvas.toBlob((blob) => {\n if (blob) {\n const ext = getExt(imageUrl);\n const file = new File([blob], `image.${ext}`, { type: blob.type });\n resolve(file);\n }\n });\n }\n };\n newImage.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n}\n\nexport async function imageUrlToFileWithXMLHttpRequest(imageUrl: string): Promise<File> {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', imageUrl, true);\n xhr.responseType = 'blob';\n xhr.send();\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status === 200) {\n const blob = xhr.response; ``\n const file = new File([blob], `image.${getExt(imageUrl)}`, { type: blob.type });\n resolve(file);\n } else {\n reject(new Error(`Failed to load image: ${xhr.status}`));\n }\n };\n xhr.onerror = (e) => {\n reject(JSON.stringify(e));\n };\n });\n};"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/environment-utils.ts","../../../src/utils/ga/ga.js","../../../src/utils/ga/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/environment-utils.ts","../../../src/utils/ga/ga.js","../../../src/utils/ga/index.ts"],"names":[],"mappings":";;;AA8DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;ACpEA,IAAA,UAAA,GAAA,uaAAA;;;ACIO,IAAM,eAAe,MAAM;AAC9B,EAAA,IAAI,UAAY,EAAA;AAEZ,IAAI,IAAA,QAAA,CAAS,aAAc,CAAA,4CAA4C,CAAG,EAAA;AACtE,MAAA;AAAA;AAEJ,IAAA,OAAA,CAAQ,IAAI,wBAAwB,CAAA;AACpC,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,SAAY,GAAA;AAAA,QAAA,EACjB,UAAQ;AAAA,QAAA,CAAA;AAEV,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA;AAGxC","file":"index.cjs","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","(function (w, d, s, l, i) {\n w[l] = w[l] || [];\n w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n let f = d.getElementsByTagName(s)[0],\n j = d.createElement(s),\n dl = l !== 'dataLayer' ? `&l=${l}` : '';\n j.async = true;\n j.src = `https://www.googletagmanager.com/gtm.js?id=${i}${dl}`;\n f.parentNode.insertBefore(j, f);\n})(window, document, 'script', 'dataLayer', 'GTM-PPT3LJ56');\n","import { isClient } from '../environment-utils.js';\n\nimport gaScript from './ga.js';\n\nexport const loadGaScript = () => {\n if (isClient()) {\n //이미 로드된 경우 return\n if (document.querySelector('script[src*=\"googletagmanager.com/gtm.js\"]')) {\n return;\n }\n console.log('ga script load dynamic');\n const script = document.createElement('script');\n script.innerHTML = `\n ${gaScript}\n `;\n document.head.appendChild(script);\n\n }\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/environment-utils.ts","../../../src/utils/ga/ga.js","../../../src/utils/ga/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/environment-utils.ts","../../../src/utils/ga/ga.js","../../../src/utils/ga/index.ts"],"names":[],"mappings":";AA8DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;ACpEA,IAAA,UAAA,GAAA,uaAAA;;;ACIO,IAAM,eAAe,MAAM;AAC9B,EAAA,IAAI,UAAY,EAAA;AAEZ,IAAI,IAAA,QAAA,CAAS,aAAc,CAAA,4CAA4C,CAAG,EAAA;AACtE,MAAA;AAAA;AAEJ,IAAA,OAAA,CAAQ,IAAI,wBAAwB,CAAA;AACpC,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,SAAY,GAAA;AAAA,QAAA,EACjB,UAAQ;AAAA,QAAA,CAAA;AAEV,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA;AAGxC","file":"index.js","sourcesContent":["import { getCookie } from './cookie-utils';\n\n/**\n * 호스트명에서 서브도메인을 추출합니다.\n * @param hostname 호스트명\n * @returns 서브도메인 (예: nxl-dsp-dev)\n */\nexport const getSubdomain = (hostname: string): string => {\n if (!hostname || hostname === 'localhost' || hostname === '127.0.0.1') {\n return '';\n }\n\n const parts = hostname.split('.');\n\n // 최소 3개 부분이 있어야 서브도메인 존재 (subdomain.domain.com)\n if (parts.length < 3) {\n return '';\n }\n\n // 첫 번째 부분이 서브도메인\n return parts[0] ?? '';\n};\n\n/**\n * 호스트명을 기반으로 환경을 판단합니다.\n * @param hostname 호스트명\n * @returns 환경 구분 문자열 ('local' | 'dev' | 'stg' | 'prd')\n */\nexport const getEnvironmentFromHostname = (hostname: string): 'local' | 'dev' | 'stg' | 'prd' => {\n\n if (isClient()) {\n const debugModeEnv = getCookie('dsp-debug-mode-env')?.toLowerCase();\n if (debugModeEnv) {\n return debugModeEnv as 'local' | 'dev' | 'stg' | 'prd';\n }\n\n }\n const subDomain = getSubdomain(hostname);\n\n // localhost 판단\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('localhost')) {\n return 'local';\n }\n\n // dev 환경 판단\n if (subDomain.includes(`dev`)) {\n return 'dev';\n }\n\n // stg 환경 판단\n if (subDomain.includes('stg')) {\n return 'stg';\n }\n\n // 기본 운영\n return 'prd';\n};\n\n/**\n * @see https://github.com/storybookjs/storybook/issues/32028#issuecomment-3298982086\n * @note 스토리북에서 버그로인해 window객체를 정상적으로 탐지하지 못하는 이슈우회\n */\nexport const isClient = () => {\n try {\n return !!window;\n } catch {\n return false;\n }\n};\n\n// window.isStorybookEnv 접근을 위한 타입캐스팅\ndeclare const window: Window & { isStorybookEnv?: boolean };\n/**\n * 현재 실행 환경이 Storybook인지 확인하는 함수\n *\n * 사용 전, `viteFinal` 설정에서 `window.isStorybookEnv`를 `true`로 정의해야 정상 동작합니다.\n *\n * 예시:\n * ```ts\n * const config: StorybookConfig = {\n * viteFinal: (config) => {\n * // window.isStorybookEnv를 true로 설정 (boolean 값으로 처리됨)\n * config.define = {\n * ...config.define,\n * 'window.isStorybookEnv': 'true',\n * };\n *\n * return config;\n * },\n * };\n * ```\n */\nexport const isStorybookEnv = () => {\n try {\n return window.isStorybookEnv === true;\n } catch {\n // window가 존재하지 않는 등 예외 상황에서는 false 반환\n return false;\n }\n};\n\n/**\n * 현재 업무구분 코드 구하기\n * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환\n * @returns\n */\nexport const getBusinessWorkDivisionCode = () => {\n return location.pathname.split('/')[1] ?? '';\n};\n\n/**\n * @description storybook에서 동작을 고려하여 수정한 버전\n * @returns\n */\nexport const getServicePath = () => {\n if (typeof window.isStorybookEnv === 'boolean') {\n return '';\n } else {\n return `/${getBusinessWorkDivisionCode()}`;\n }\n};\n\n/**\n * 환경에 맞는 API 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\n\nexport const getApiHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * 환경에 맞는 CDN 호스트명을 반환합니다.\n * 호스트명을 강제하고 싶으면 두 번째 파라미터로 넘기세요.\n * @param currentHostname\n * @param forceApiHostName\n * @returns\n */\nexport const getCdnHostNameFromEnvironment = (currentHostname: string, forceApiHostName?: string) => {\n if (!isClient()) {\n return '';\n }\n\n if (forceApiHostName) {\n return forceApiHostName;\n }\n\n const environment = getEnvironmentFromHostname(currentHostname);\n\n switch (environment) {\n case 'dev':\n return `https://dev-dsp-static.hanwhalife.com`;\n\n case 'local':\n case 'stg':\n return `https://stg-dsp-static.hanwhalife.com`;\n\n case 'prd':\n return `https://dsp-static.hanwhalife.com'`;\n\n default:\n console.warn('DSP environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 비정형PI 호스트명을 반환합니다.\n * @param serviceCode dea,dis,dcm\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDudApiBasePathFromEnvironment = (hostname: string, servicePath: string) => {\n\n const environment = getEnvironmentFromHostname(hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${servicePath}/api/dud`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://dsp-dud-dev.hanwhalife.com:10101/api`;\n\n case 'stg':\n return `https://dsp-dud-stg.hanwhalife.com:10102/api`;\n\n case 'prd':\n return `https://dsp-dud.hanwhalife.com/api`;\n\n default:\n console.warn('DUD API environment is not defined');\n\n return '';\n }\n};\n\n/**\n * @description\n * 환경에 맞는 Dsp 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param serviceCodeTo dea,dis 같은 api서버명\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getDspApiBasePathFromEnvironment = (serviceCodeTo: string, hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n /**\n * local에서 호출시, rewrite동작을 위해 상대주소를 호출합니다.\n * (cors이슈 해결을 위해 필수)\n */\n case 'local':\n return `${getServicePath()}/api/${serviceCodeTo}`;\n /**\n * local 이 아닌 환경에서는 전체주소를 호출합니다.\n */\n case 'dev':\n return `https://nxl-dsp-dev.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'stg':\n return `https://nxl-dsp-stg.hanwhalife.com/api/${serviceCodeTo}`;\n\n case 'prd':\n return `https://nxl-dsp.hanwhalife.com/api/${serviceCodeTo}`;\n\n default:\n console.warn('DSP API environment is not defined');\n\n return '';\n }\n};\n\n\n/**\n * @description\n * 환경에 맞는 NLC 호스트명을 반환합니다.\n * client side에서 사용하는 함수입니다.\n * @param hostname window.location.hostname\n * @returns\n */\nexport const getNlcHostFromEnvironment = (hostname?: string) => {\n if (!isClient()) {\n return '';\n }\n\n const environment = getEnvironmentFromHostname(hostname || location.hostname);\n\n switch (environment) {\n case 'local':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'dev':\n return `https://nxl-nlc-dev.hanwhalife.com`;\n\n case 'stg':\n return `https://nxl-nlc-stg.hanwhalife.com`;\n\n case 'prd':\n return `https://nxl-nlc.hanwhalife.com`;\n\n default:\n console.warn('NLC environment is not defined');\n\n return '';\n }\n};\n\n","(function (w, d, s, l, i) {\n w[l] = w[l] || [];\n w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n let f = d.getElementsByTagName(s)[0],\n j = d.createElement(s),\n dl = l !== 'dataLayer' ? `&l=${l}` : '';\n j.async = true;\n j.src = `https://www.googletagmanager.com/gtm.js?id=${i}${dl}`;\n f.parentNode.insertBefore(j, f);\n})(window, document, 'script', 'dataLayer', 'GTM-PPT3LJ56');\n","import { isClient } from '../environment-utils.js';\n\nimport gaScript from './ga.js';\n\nexport const loadGaScript = () => {\n if (isClient()) {\n //이미 로드된 경우 return\n if (document.querySelector('script[src*=\"googletagmanager.com/gtm.js\"]')) {\n return;\n }\n console.log('ga script load dynamic');\n const script = document.createElement('script');\n script.innerHTML = `\n ${gaScript}\n `;\n document.head.appendChild(script);\n\n }\n}"]}
|