sales-frontend-utils 0.0.54 → 0.0.56

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.
Files changed (37) hide show
  1. package/dist/index.cjs +58 -15
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +3 -2
  4. package/dist/index.d.ts +3 -2
  5. package/dist/index.js +56 -16
  6. package/dist/index.js.map +1 -1
  7. package/dist/types/common.types.d.cts +5 -1
  8. package/dist/types/common.types.d.ts +5 -1
  9. package/dist/utils/canvas-utils.cjs +9 -3
  10. package/dist/utils/canvas-utils.cjs.map +1 -1
  11. package/dist/utils/canvas-utils.d.cts +2 -1
  12. package/dist/utils/canvas-utils.d.ts +2 -1
  13. package/dist/utils/canvas-utils.js +9 -4
  14. package/dist/utils/canvas-utils.js.map +1 -1
  15. package/dist/utils/cookie-utils.cjs.map +1 -1
  16. package/dist/utils/cookie-utils.js.map +1 -1
  17. package/dist/utils/environment-utils.cjs +4 -1
  18. package/dist/utils/environment-utils.cjs.map +1 -1
  19. package/dist/utils/environment-utils.d.cts +1 -1
  20. package/dist/utils/environment-utils.d.ts +1 -1
  21. package/dist/utils/environment-utils.js +4 -1
  22. package/dist/utils/environment-utils.js.map +1 -1
  23. package/dist/utils/file-utils.cjs +28 -11
  24. package/dist/utils/file-utils.cjs.map +1 -1
  25. package/dist/utils/file-utils.js +28 -11
  26. package/dist/utils/file-utils.js.map +1 -1
  27. package/dist/utils/ga/index.cjs.map +1 -1
  28. package/dist/utils/ga/index.js.map +1 -1
  29. package/dist/utils/gender.cjs +21 -0
  30. package/dist/utils/gender.cjs.map +1 -0
  31. package/dist/utils/gender.d.cts +15 -0
  32. package/dist/utils/gender.d.ts +15 -0
  33. package/dist/utils/gender.js +18 -0
  34. package/dist/utils/gender.js.map +1 -0
  35. package/dist/utils/user-agent-utils.cjs.map +1 -1
  36. package/dist/utils/user-agent-utils.js.map +1 -1
  37. package/package.json +13 -3
@@ -7,5 +7,9 @@ type OSName = 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'unknown';
7
7
  * 브라우저 이름을 판단하는 타입
8
8
  */
9
9
  type BrowserName = 'chrome' | 'firefox' | 'safari' | 'edge' | 'opera' | 'samsung' | 'unknown';
10
+ /**
11
+ * 성별 코드를 판단하는 타입
12
+ */
13
+ type GenderCode = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8';
10
14
 
11
- export type { BrowserName, ExecutionEnvironment, OSName };
15
+ export type { BrowserName, ExecutionEnvironment, GenderCode, OSName };
@@ -7,5 +7,9 @@ type OSName = 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'unknown';
7
7
  * 브라우저 이름을 판단하는 타입
8
8
  */
9
9
  type BrowserName = 'chrome' | 'firefox' | 'safari' | 'edge' | 'opera' | 'samsung' | 'unknown';
10
+ /**
11
+ * 성별 코드를 판단하는 타입
12
+ */
13
+ type GenderCode = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8';
10
14
 
11
- export type { BrowserName, ExecutionEnvironment, OSName };
15
+ export type { BrowserName, ExecutionEnvironment, GenderCode, OSName };
@@ -1,6 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  // src/utils/canvas-utils.ts
4
+ var getTextWidth = (text, font, context) => {
5
+ context.font = font;
6
+ const metrics = context.measureText(text);
7
+ return metrics.width;
8
+ };
4
9
  var convertTextToImg = ({
5
10
  targetStr,
6
11
  canvasWidth,
@@ -16,8 +21,9 @@ var convertTextToImg = ({
16
21
  if (!ctx) {
17
22
  throw new Error("Canvas context\uB97C \uAC00\uC838\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
18
23
  }
24
+ const font = `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`;
19
25
  const defaultHeight = 150;
20
- const calculatedWidth = targetStr.length * 70;
26
+ const calculatedWidth = getTextWidth(targetStr, font, ctx);
21
27
  canvas.width = canvasWidth ?? calculatedWidth;
22
28
  canvas.height = canvasHeight ?? defaultHeight;
23
29
  if (backgroundColor) {
@@ -26,8 +32,7 @@ var convertTextToImg = ({
26
32
  }
27
33
  ctx.fillStyle = fontColor ?? "black";
28
34
  ctx.textAlign = "center";
29
- ctx.font = `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`;
30
- console.log("font", `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`);
35
+ ctx.font = font;
31
36
  ctx.textBaseline = "middle";
32
37
  ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);
33
38
  return canvas.toDataURL();
@@ -66,5 +71,6 @@ function drawImageResizeCentered(base64, size) {
66
71
 
67
72
  exports.convertTextToImg = convertTextToImg;
68
73
  exports.drawImageResizeCentered = drawImageResizeCentered;
74
+ exports.getTextWidth = getTextWidth;
69
75
  //# sourceMappingURL=canvas-utils.cjs.map
70
76
  //# sourceMappingURL=canvas-utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/canvas-utils.ts"],"names":[],"mappings":";;;AAwBO,IAAM,mBAAmB,CAAC;AAAA,EAC/B,SAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAa,GAAA,CAAA,yBAAA;AACf,CAAsC,KAAA;AAEpC,EAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAM,MAAA,GAAA,GAAM,MAAO,CAAA,UAAA,CAAW,IAAI,CAAA;AAElC,EAAA,IAAI,CAAC,GAAK,EAAA;AAER,IAAM,MAAA,IAAI,MAAM,0EAA6B,CAAA;AAAA;AAI/C,EAAA,MAAM,aAAgB,GAAA,GAAA;AACtB,EAAM,MAAA,eAAA,GAAkB,UAAU,MAAS,GAAA,EAAA;AAE3C,EAAA,MAAA,CAAO,QAAQ,WAAe,IAAA,eAAA;AAC9B,EAAA,MAAA,CAAO,SAAS,YAAgB,IAAA,aAAA;AAGhC,EAAA,IAAI,eAAiB,EAAA;AACnB,IAAA,GAAA,CAAI,SAAY,GAAA,eAAA;AAChB,IAAA,GAAA,CAAI,SAAS,CAAG,EAAA,CAAA,EAAG,MAAO,CAAA,KAAA,EAAO,OAAO,MAAM,CAAA;AAAA;AAIhD,EAAA,GAAA,CAAI,YAAY,SAAa,IAAA,OAAA;AAC7B,EAAA,GAAA,CAAI,SAAY,GAAA,QAAA;AAChB,EAAI,GAAA,CAAA,IAAA,GAAO,GAAG,UAAc,IAAA,QAAQ,IAAI,QAAY,IAAA,EAAE,MAAM,UAAU,CAAA,CAAA;AAEtE,EAAQ,OAAA,CAAA,GAAA,CAAI,MAAQ,EAAA,CAAA,EAAG,UAAc,IAAA,QAAQ,IAAI,QAAY,IAAA,EAAE,CAAM,GAAA,EAAA,UAAU,CAAE,CAAA,CAAA;AACjF,EAAA,GAAA,CAAI,YAAe,GAAA,QAAA;AAGnB,EAAA,GAAA,CAAI,SAAS,SAAW,EAAA,MAAA,CAAO,QAAQ,CAAG,EAAA,MAAA,CAAO,SAAS,CAAC,CAAA;AAG3D,EAAA,OAAO,OAAO,SAAU,EAAA;AAC1B;AAEO,SAAS,uBAAA,CAAwB,QAAgB,IAAqD,EAAA;AAC3G,EAAO,OAAA,IAAI,OAAQ,CAAA,CAAC,OAAY,KAAA;AAC9B,IAAM,MAAA,EAAE,YAAc,EAAA,WAAA,EAAgB,GAAA,IAAA;AAEtC,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,KAAQ,GAAA,WAAA;AACf,IAAA,MAAA,CAAO,MAAS,GAAA,YAAA;AAChB,IAAM,MAAA,GAAA,GAAM,MAAO,CAAA,UAAA,CAAW,IAAI,CAAA;AAElC,IAAM,MAAA,GAAA,GAAM,IAAI,KAAM,EAAA;AACtB,IAAA,GAAA,CAAI,GAAM,GAAA,MAAA;AACV,IAAA,GAAA,CAAI,SAAS,MAAM;AACjB,MAAA,MAAM,aAAa,GAAI,CAAA,KAAA;AACvB,MAAA,MAAM,cAAc,GAAI,CAAA,MAAA;AAExB,MAAA,MAAM,cAAc,WAAc,GAAA,YAAA;AAClC,MAAA,MAAM,aAAa,UAAa,GAAA,WAAA;AAEhC,MAAI,IAAA,QAAA;AACJ,MAAI,IAAA,SAAA;AAEJ,MAAA,IAAI,aAAa,WAAa,EAAA;AAC5B,QAAW,QAAA,GAAA,WAAA;AACX,QAAA,SAAA,GAAY,QAAW,GAAA,UAAA;AAAA,OAClB,MAAA;AACL,QAAY,SAAA,GAAA,YAAA;AACZ,QAAA,QAAA,GAAW,SAAY,GAAA,UAAA;AAAA;AAGzB,MAAM,MAAA,CAAA,GAAA,CAAK,cAAc,QAAY,IAAA,CAAA;AACrC,MAAM,MAAA,CAAA,GAAA,CAAK,eAAe,SAAa,IAAA,CAAA;AAEvC,MAAA,GAAA,EAAK,SAAU,CAAA,CAAA,EAAG,CAAG,EAAA,WAAA,EAAa,YAAY,CAAA;AAC9C,MAAA,GAAA,EAAK,SAAU,CAAA,GAAA,EAAK,CAAG,EAAA,CAAA,EAAG,UAAU,SAAS,CAAA;AAE7C,MAAQ,OAAA,CAAA,MAAA,CAAO,WAAW,CAAA;AAAA,KAC5B;AAAA,GACD,CAAA;AACH","file":"canvas-utils.cjs","sourcesContent":["interface ConvertTextToImgParams {\n /** 이미지로 변환할 문자열 */\n targetStr: string;\n /** 캔버스 너비 (지정하지 않으면 텍스트 길이에 따라 자동 계산) */\n canvasWidth?: number;\n /** 캔버스 높이 (지정하지 않으면 기본값 150px) */\n canvasHeight?: number;\n /** 배경색 (지정하지 않으면 투명) */\n backgroundColor?: string;\n /** 폰트 크기 (지정하지 않으면 기본값 75px) */\n fontSize?: number;\n /** 폰트 색상 (지정하지 않으면 기본값 검정색) */\n fontColor?: string;\n /** 폰트 두께 (지정하지 않으면 기본값 bold) */\n fontWeight?: string;\n /** 폰트 패밀리 (지정하지 않으면 기본값 ) */\n fontFamily?: string;\n}\n\n/**\n * 텍스트를 이미지(Base64)로 변환하는 함수\n * @param params - 변환에 필요한 파라미터 객체\n * @returns Base64로 인코딩된 이미지 데이터 URL\n */\nexport const convertTextToImg = ({\n targetStr,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n fontColor,\n fontSize,\n fontWeight,\n fontFamily = `'system-ui', 'sans-serif'`\n}: ConvertTextToImgParams): string => {\n // 1. 메모리에 캔버스 요소 생성\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n // 캔버스 컨텍스트를 가져올 수 없는 경우 에러 처리\n throw new Error('Canvas context를 가져올 수 없습니다.');\n }\n\n // 2. 캔버스 크기 설정\n const defaultHeight = 150;\n const calculatedWidth = targetStr.length * 70; // 글자 수 기반 너비 계산\n\n canvas.width = canvasWidth ?? calculatedWidth;\n canvas.height = canvasHeight ?? defaultHeight;\n\n // 3. 배경색 처리\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n // 4. 텍스트 그리기\n ctx.fillStyle = fontColor ?? 'black';\n ctx.textAlign = 'center';\n ctx.font = `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`;\n\n console.log('font', `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`);\n ctx.textBaseline = 'middle'; // 텍스트를 수직 중앙에 더 잘 맞추기 위해 추가\n\n // 텍스트를 캔버스 중앙에 그립니다.\n ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);\n\n // 5. Base64 이미지 데이터로 변환하여 반환\n return canvas.toDataURL(); // 기본적으로 'image/png'\n};\n\nexport function drawImageResizeCentered(base64: string, size: { canvasWidth: number; canvasHeight: number }) {\n return new Promise((resolve) => {\n const { canvasHeight, canvasWidth } = size;\n\n const canvas = document.createElement('canvas');\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const ctx = canvas.getContext('2d');\n\n const img = new Image();\n img.src = base64;\n img.onload = () => {\n const imageWidth = img.width;\n const imageHeight = img.height;\n\n const canvasRatio = canvasWidth / canvasHeight;\n const imageRatio = imageWidth / imageHeight;\n\n let newWidth;\n let newHeight;\n\n if (imageRatio > canvasRatio) {\n newWidth = canvasWidth;\n newHeight = newWidth / imageRatio;\n } else {\n newHeight = canvasHeight;\n newWidth = newHeight * imageRatio;\n }\n\n const x = (canvasWidth - newWidth) / 2;\n const y = (canvasHeight - newHeight) / 2;\n\n ctx?.clearRect(0, 0, canvasWidth, canvasHeight);\n ctx?.drawImage(img, x, y, newWidth, newHeight);\n\n resolve(canvas.toDataURL());\n };\n });\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/canvas-utils.ts"],"names":[],"mappings":"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","file":"canvas-utils.cjs","sourcesContent":["interface ConvertTextToImgParams {\n /** 이미지로 변환할 문자열 */\n targetStr: string;\n /** 캔버스 너비 (지정하지 않으면 텍스트 길이에 따라 자동 계산) */\n canvasWidth?: number;\n /** 캔버스 높이 (지정하지 않으면 기본값 150px) */\n canvasHeight?: number;\n /** 배경색 (지정하지 않으면 투명) */\n backgroundColor?: string;\n /** 폰트 크기 (지정하지 않으면 기본값 75px) */\n fontSize?: number;\n /** 폰트 색상 (지정하지 않으면 기본값 검정색) */\n fontColor?: string;\n /** 폰트 두께 (지정하지 않으면 기본값 bold) */\n fontWeight?: string;\n /** 폰트 패밀리 (지정하지 않으면 기본값 ) */\n fontFamily?: string;\n}\n\n\n\nexport const getTextWidth = (text: string, font: string, context: CanvasRenderingContext2D) => {\n\n // 폰트 스타일 설정\n context.font = font;\n\n // measureText()를 사용하여 TextMetrics 객체 가져오기\n const metrics = context.measureText(text);\n\n // 너비(width) 반환\n return metrics.width;\n}\n\n\n\n\n/**\n * 텍스트를 이미지(Base64)로 변환하는 함수\n * @param params - 변환에 필요한 파라미터 객체\n * @returns Base64로 인코딩된 이미지 데이터 URL\n */\nexport const convertTextToImg = ({\n targetStr,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n fontColor,\n fontSize,\n fontWeight,\n fontFamily = `'system-ui', 'sans-serif'`\n}: ConvertTextToImgParams): string => {\n // 1. 메모리에 캔버스 요소 생성\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n // 캔버스 컨텍스트를 가져올 수 없는 경우 에러 처리\n throw new Error('Canvas context를 가져올 수 없습니다.');\n }\n\n const font = `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`;\n\n // 2. 캔버스 크기 설정\n const defaultHeight = 150;\n\n // as-is\n // const calculatedWidth = targetStr.length * 70; // 글자 수 기반 너비 계산\n\n const calculatedWidth = getTextWidth(targetStr, font, ctx);\n canvas.width = canvasWidth ?? calculatedWidth;\n canvas.height = canvasHeight ?? defaultHeight;\n\n // 3. 배경색 처리\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n // 4. 텍스트 그리기\n ctx.fillStyle = fontColor ?? 'black';\n ctx.textAlign = 'center';\n ctx.font = font;\n ctx.textBaseline = 'middle'; // 텍스트를 수직 중앙에 더 잘 맞추기 위해 추가\n\n // 텍스트를 캔버스 중앙에 그립니다.\n ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);\n\n // 5. Base64 이미지 데이터로 변환하여 반환\n return canvas.toDataURL(); // 기본적으로 'image/png'\n};\n\nexport function drawImageResizeCentered(base64: string, size: { canvasWidth: number; canvasHeight: number }) {\n return new Promise((resolve) => {\n const { canvasHeight, canvasWidth } = size;\n\n const canvas = document.createElement('canvas');\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const ctx = canvas.getContext('2d');\n\n const img = new Image();\n img.src = base64;\n img.onload = () => {\n const imageWidth = img.width;\n const imageHeight = img.height;\n\n const canvasRatio = canvasWidth / canvasHeight;\n const imageRatio = imageWidth / imageHeight;\n\n let newWidth;\n let newHeight;\n\n if (imageRatio > canvasRatio) {\n newWidth = canvasWidth;\n newHeight = newWidth / imageRatio;\n } else {\n newHeight = canvasHeight;\n newWidth = newHeight * imageRatio;\n }\n\n const x = (canvasWidth - newWidth) / 2;\n const y = (canvasHeight - newHeight) / 2;\n\n ctx?.clearRect(0, 0, canvasWidth, canvasHeight);\n ctx?.drawImage(img, x, y, newWidth, newHeight);\n\n resolve(canvas.toDataURL());\n };\n });\n}\n"]}
@@ -16,6 +16,7 @@ interface ConvertTextToImgParams {
16
16
  /** 폰트 패밀리 (지정하지 않으면 기본값 ) */
17
17
  fontFamily?: string;
18
18
  }
19
+ declare const getTextWidth: (text: string, font: string, context: CanvasRenderingContext2D) => number;
19
20
  /**
20
21
  * 텍스트를 이미지(Base64)로 변환하는 함수
21
22
  * @param params - 변환에 필요한 파라미터 객체
@@ -27,4 +28,4 @@ declare function drawImageResizeCentered(base64: string, size: {
27
28
  canvasHeight: number;
28
29
  }): Promise<unknown>;
29
30
 
30
- export { convertTextToImg, drawImageResizeCentered };
31
+ export { convertTextToImg, drawImageResizeCentered, getTextWidth };
@@ -16,6 +16,7 @@ interface ConvertTextToImgParams {
16
16
  /** 폰트 패밀리 (지정하지 않으면 기본값 ) */
17
17
  fontFamily?: string;
18
18
  }
19
+ declare const getTextWidth: (text: string, font: string, context: CanvasRenderingContext2D) => number;
19
20
  /**
20
21
  * 텍스트를 이미지(Base64)로 변환하는 함수
21
22
  * @param params - 변환에 필요한 파라미터 객체
@@ -27,4 +28,4 @@ declare function drawImageResizeCentered(base64: string, size: {
27
28
  canvasHeight: number;
28
29
  }): Promise<unknown>;
29
30
 
30
- export { convertTextToImg, drawImageResizeCentered };
31
+ export { convertTextToImg, drawImageResizeCentered, getTextWidth };
@@ -1,4 +1,9 @@
1
1
  // src/utils/canvas-utils.ts
2
+ var getTextWidth = (text, font, context) => {
3
+ context.font = font;
4
+ const metrics = context.measureText(text);
5
+ return metrics.width;
6
+ };
2
7
  var convertTextToImg = ({
3
8
  targetStr,
4
9
  canvasWidth,
@@ -14,8 +19,9 @@ var convertTextToImg = ({
14
19
  if (!ctx) {
15
20
  throw new Error("Canvas context\uB97C \uAC00\uC838\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
16
21
  }
22
+ const font = `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`;
17
23
  const defaultHeight = 150;
18
- const calculatedWidth = targetStr.length * 70;
24
+ const calculatedWidth = getTextWidth(targetStr, font, ctx);
19
25
  canvas.width = canvasWidth ?? calculatedWidth;
20
26
  canvas.height = canvasHeight ?? defaultHeight;
21
27
  if (backgroundColor) {
@@ -24,8 +30,7 @@ var convertTextToImg = ({
24
30
  }
25
31
  ctx.fillStyle = fontColor ?? "black";
26
32
  ctx.textAlign = "center";
27
- ctx.font = `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`;
28
- console.log("font", `${fontWeight ?? "normal"} ${fontSize ?? 75}px ${fontFamily}`);
33
+ ctx.font = font;
29
34
  ctx.textBaseline = "middle";
30
35
  ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);
31
36
  return canvas.toDataURL();
@@ -62,6 +67,6 @@ function drawImageResizeCentered(base64, size) {
62
67
  });
63
68
  }
64
69
 
65
- export { convertTextToImg, drawImageResizeCentered };
70
+ export { convertTextToImg, drawImageResizeCentered, getTextWidth };
66
71
  //# sourceMappingURL=canvas-utils.js.map
67
72
  //# sourceMappingURL=canvas-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/canvas-utils.ts"],"names":[],"mappings":"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","file":"canvas-utils.js","sourcesContent":["interface ConvertTextToImgParams {\n /** 이미지로 변환할 문자열 */\n targetStr: string;\n /** 캔버스 너비 (지정하지 않으면 텍스트 길이에 따라 자동 계산) */\n canvasWidth?: number;\n /** 캔버스 높이 (지정하지 않으면 기본값 150px) */\n canvasHeight?: number;\n /** 배경색 (지정하지 않으면 투명) */\n backgroundColor?: string;\n /** 폰트 크기 (지정하지 않으면 기본값 75px) */\n fontSize?: number;\n /** 폰트 색상 (지정하지 않으면 기본값 검정색) */\n fontColor?: string;\n /** 폰트 두께 (지정하지 않으면 기본값 bold) */\n fontWeight?: string;\n /** 폰트 패밀리 (지정하지 않으면 기본값 ) */\n fontFamily?: string;\n}\n\n/**\n * 텍스트를 이미지(Base64)로 변환하는 함수\n * @param params - 변환에 필요한 파라미터 객체\n * @returns Base64로 인코딩된 이미지 데이터 URL\n */\nexport const convertTextToImg = ({\n targetStr,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n fontColor,\n fontSize,\n fontWeight,\n fontFamily = `'system-ui', 'sans-serif'`\n}: ConvertTextToImgParams): string => {\n // 1. 메모리에 캔버스 요소 생성\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n // 캔버스 컨텍스트를 가져올 수 없는 경우 에러 처리\n throw new Error('Canvas context를 가져올 수 없습니다.');\n }\n\n // 2. 캔버스 크기 설정\n const defaultHeight = 150;\n const calculatedWidth = targetStr.length * 70; // 글자 수 기반 너비 계산\n\n canvas.width = canvasWidth ?? calculatedWidth;\n canvas.height = canvasHeight ?? defaultHeight;\n\n // 3. 배경색 처리\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n // 4. 텍스트 그리기\n ctx.fillStyle = fontColor ?? 'black';\n ctx.textAlign = 'center';\n ctx.font = `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`;\n\n console.log('font', `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`);\n ctx.textBaseline = 'middle'; // 텍스트를 수직 중앙에 더 잘 맞추기 위해 추가\n\n // 텍스트를 캔버스 중앙에 그립니다.\n ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);\n\n // 5. Base64 이미지 데이터로 변환하여 반환\n return canvas.toDataURL(); // 기본적으로 'image/png'\n};\n\nexport function drawImageResizeCentered(base64: string, size: { canvasWidth: number; canvasHeight: number }) {\n return new Promise((resolve) => {\n const { canvasHeight, canvasWidth } = size;\n\n const canvas = document.createElement('canvas');\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const ctx = canvas.getContext('2d');\n\n const img = new Image();\n img.src = base64;\n img.onload = () => {\n const imageWidth = img.width;\n const imageHeight = img.height;\n\n const canvasRatio = canvasWidth / canvasHeight;\n const imageRatio = imageWidth / imageHeight;\n\n let newWidth;\n let newHeight;\n\n if (imageRatio > canvasRatio) {\n newWidth = canvasWidth;\n newHeight = newWidth / imageRatio;\n } else {\n newHeight = canvasHeight;\n newWidth = newHeight * imageRatio;\n }\n\n const x = (canvasWidth - newWidth) / 2;\n const y = (canvasHeight - newHeight) / 2;\n\n ctx?.clearRect(0, 0, canvasWidth, canvasHeight);\n ctx?.drawImage(img, x, y, newWidth, newHeight);\n\n resolve(canvas.toDataURL());\n };\n });\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/canvas-utils.ts"],"names":[],"mappings":"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","file":"canvas-utils.js","sourcesContent":["interface ConvertTextToImgParams {\n /** 이미지로 변환할 문자열 */\n targetStr: string;\n /** 캔버스 너비 (지정하지 않으면 텍스트 길이에 따라 자동 계산) */\n canvasWidth?: number;\n /** 캔버스 높이 (지정하지 않으면 기본값 150px) */\n canvasHeight?: number;\n /** 배경색 (지정하지 않으면 투명) */\n backgroundColor?: string;\n /** 폰트 크기 (지정하지 않으면 기본값 75px) */\n fontSize?: number;\n /** 폰트 색상 (지정하지 않으면 기본값 검정색) */\n fontColor?: string;\n /** 폰트 두께 (지정하지 않으면 기본값 bold) */\n fontWeight?: string;\n /** 폰트 패밀리 (지정하지 않으면 기본값 ) */\n fontFamily?: string;\n}\n\n\n\nexport const getTextWidth = (text: string, font: string, context: CanvasRenderingContext2D) => {\n\n // 폰트 스타일 설정\n context.font = font;\n\n // measureText()를 사용하여 TextMetrics 객체 가져오기\n const metrics = context.measureText(text);\n\n // 너비(width) 반환\n return metrics.width;\n}\n\n\n\n\n/**\n * 텍스트를 이미지(Base64)로 변환하는 함수\n * @param params - 변환에 필요한 파라미터 객체\n * @returns Base64로 인코딩된 이미지 데이터 URL\n */\nexport const convertTextToImg = ({\n targetStr,\n canvasWidth,\n canvasHeight,\n backgroundColor,\n fontColor,\n fontSize,\n fontWeight,\n fontFamily = `'system-ui', 'sans-serif'`\n}: ConvertTextToImgParams): string => {\n // 1. 메모리에 캔버스 요소 생성\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n // 캔버스 컨텍스트를 가져올 수 없는 경우 에러 처리\n throw new Error('Canvas context를 가져올 수 없습니다.');\n }\n\n const font = `${fontWeight ?? 'normal'} ${fontSize ?? 75}px ${fontFamily}`;\n\n // 2. 캔버스 크기 설정\n const defaultHeight = 150;\n\n // as-is\n // const calculatedWidth = targetStr.length * 70; // 글자 수 기반 너비 계산\n\n const calculatedWidth = getTextWidth(targetStr, font, ctx);\n canvas.width = canvasWidth ?? calculatedWidth;\n canvas.height = canvasHeight ?? defaultHeight;\n\n // 3. 배경색 처리\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n // 4. 텍스트 그리기\n ctx.fillStyle = fontColor ?? 'black';\n ctx.textAlign = 'center';\n ctx.font = font;\n ctx.textBaseline = 'middle'; // 텍스트를 수직 중앙에 더 잘 맞추기 위해 추가\n\n // 텍스트를 캔버스 중앙에 그립니다.\n ctx.fillText(targetStr, canvas.width / 2, canvas.height / 2);\n\n // 5. Base64 이미지 데이터로 변환하여 반환\n return canvas.toDataURL(); // 기본적으로 'image/png'\n};\n\nexport function drawImageResizeCentered(base64: string, size: { canvasWidth: number; canvasHeight: number }) {\n return new Promise((resolve) => {\n const { canvasHeight, canvasWidth } = size;\n\n const canvas = document.createElement('canvas');\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n const ctx = canvas.getContext('2d');\n\n const img = new Image();\n img.src = base64;\n img.onload = () => {\n const imageWidth = img.width;\n const imageHeight = img.height;\n\n const canvasRatio = canvasWidth / canvasHeight;\n const imageRatio = imageWidth / imageHeight;\n\n let newWidth;\n let newHeight;\n\n if (imageRatio > canvasRatio) {\n newWidth = canvasWidth;\n newHeight = newWidth / imageRatio;\n } else {\n newHeight = canvasHeight;\n newWidth = newHeight * imageRatio;\n }\n\n const x = (canvasWidth - newWidth) / 2;\n const y = (canvasHeight - newHeight) / 2;\n\n ctx?.clearRect(0, 0, canvasWidth, canvasHeight);\n ctx?.drawImage(img, x, y, newWidth, newHeight);\n\n resolve(canvas.toDataURL());\n };\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-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;;;AClEa,IAAA,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;AAEO,IAAM,YAAY,CACvB,IAAA,EACA,KACA,EAAA,OAAA,GAKI,EACK,KAAA;AACT,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAA;AAAA;AAGF,EAAA,IAAI,eAAe,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAEvD,EAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,IAAI,IAAA,WAAA;AACJ,IAAI,IAAA,OAAO,OAAQ,CAAA,OAAA,KAAY,QAAU,EAAA;AACvC,MAAA,WAAA,uBAAkB,IAAK,EAAA;AACvB,MAAA,WAAA,CAAY,OAAQ,CAAA,WAAA,CAAY,OAAQ,EAAA,GAAI,QAAQ,OAAO,CAAA;AAAA,KACtD,MAAA;AACL,MAAA,WAAA,GAAc,OAAQ,CAAA,OAAA;AAAA;AAExB,IAAgB,YAAA,IAAA,CAAA,UAAA,EAAa,WAAY,CAAA,WAAA,EAAa,CAAA,CAAA;AAAA;AAGxD,EAAgB,YAAA,IAAA,CAAA,OAAA,EAAU,OAAQ,CAAA,IAAA,IAAQ,GAAG,CAAA,CAAA;AAE7C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA;AAG5C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,UAAA;AAAA;AAGlB,EAAA,QAAA,CAAS,MAAS,GAAA,YAAA;AACpB;AAEO,IAAM,YAAe,GAAA,CAAC,IAAc,EAAA,OAAA,GAA8C,EAAa,KAAA;AACpG,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAA,SAAA,CAAU,MAAM,EAAI,EAAA,EAAE,GAAG,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AACjD","file":"cookie-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"]}
1
+ {"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts"],"names":[],"mappings":";;;AA4DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;AChEa,IAAA,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;AAEO,IAAM,YAAY,CACvB,IAAA,EACA,KACA,EAAA,OAAA,GAKI,EACK,KAAA;AACT,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAA;AAAA;AAGF,EAAA,IAAI,eAAe,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAEvD,EAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,IAAI,IAAA,WAAA;AACJ,IAAI,IAAA,OAAO,OAAQ,CAAA,OAAA,KAAY,QAAU,EAAA;AACvC,MAAA,WAAA,uBAAkB,IAAK,EAAA;AACvB,MAAA,WAAA,CAAY,OAAQ,CAAA,WAAA,CAAY,OAAQ,EAAA,GAAI,QAAQ,OAAO,CAAA;AAAA,KACtD,MAAA;AACL,MAAA,WAAA,GAAc,OAAQ,CAAA,OAAA;AAAA;AAExB,IAAgB,YAAA,IAAA,CAAA,UAAA,EAAa,WAAY,CAAA,WAAA,EAAa,CAAA,CAAA;AAAA;AAGxD,EAAgB,YAAA,IAAA,CAAA,OAAA,EAAU,OAAQ,CAAA,IAAA,IAAQ,GAAG,CAAA,CAAA;AAE7C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA;AAG5C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,UAAA;AAAA;AAGlB,EAAA,QAAA,CAAS,MAAS,GAAA,YAAA;AACpB;AAEO,IAAM,YAAe,GAAA,CAAC,IAAc,EAAA,OAAA,GAA8C,EAAa,KAAA;AACpG,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAA,SAAA,CAAU,MAAM,EAAI,EAAA,EAAE,GAAG,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AACjD","file":"cookie-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 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 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 = (pathname?: string) => {\n if (pathname) {\n return pathname.split('/')[1] ?? '';\n }\n\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 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 * @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","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"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-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;;;AClEa,IAAA,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;AAEO,IAAM,YAAY,CACvB,IAAA,EACA,KACA,EAAA,OAAA,GAKI,EACK,KAAA;AACT,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAA;AAAA;AAGF,EAAA,IAAI,eAAe,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAEvD,EAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,IAAI,IAAA,WAAA;AACJ,IAAI,IAAA,OAAO,OAAQ,CAAA,OAAA,KAAY,QAAU,EAAA;AACvC,MAAA,WAAA,uBAAkB,IAAK,EAAA;AACvB,MAAA,WAAA,CAAY,OAAQ,CAAA,WAAA,CAAY,OAAQ,EAAA,GAAI,QAAQ,OAAO,CAAA;AAAA,KACtD,MAAA;AACL,MAAA,WAAA,GAAc,OAAQ,CAAA,OAAA;AAAA;AAExB,IAAgB,YAAA,IAAA,CAAA,UAAA,EAAa,WAAY,CAAA,WAAA,EAAa,CAAA,CAAA;AAAA;AAGxD,EAAgB,YAAA,IAAA,CAAA,OAAA,EAAU,OAAQ,CAAA,IAAA,IAAQ,GAAG,CAAA,CAAA;AAE7C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA;AAG5C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,UAAA;AAAA;AAGlB,EAAA,QAAA,CAAS,MAAS,GAAA,YAAA;AACpB;AAEO,IAAM,YAAe,GAAA,CAAC,IAAc,EAAA,OAAA,GAA8C,EAAa,KAAA;AACpG,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAA,SAAA,CAAU,MAAM,EAAI,EAAA,EAAE,GAAG,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AACjD","file":"cookie-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"]}
1
+ {"version":3,"sources":["../../src/utils/environment-utils.ts","../../src/utils/cookie-utils.ts"],"names":[],"mappings":";AA4DO,IAAM,WAAW,MAAM;AAC5B,EAAI,IAAA;AACF,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,MAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX,CAAA;;;AChEa,IAAA,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;AAEO,IAAM,YAAY,CACvB,IAAA,EACA,KACA,EAAA,OAAA,GAKI,EACK,KAAA;AACT,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,IAAA;AAAA;AAGF,EAAA,IAAI,eAAe,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAEvD,EAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,IAAI,IAAA,WAAA;AACJ,IAAI,IAAA,OAAO,OAAQ,CAAA,OAAA,KAAY,QAAU,EAAA;AACvC,MAAA,WAAA,uBAAkB,IAAK,EAAA;AACvB,MAAA,WAAA,CAAY,OAAQ,CAAA,WAAA,CAAY,OAAQ,EAAA,GAAI,QAAQ,OAAO,CAAA;AAAA,KACtD,MAAA;AACL,MAAA,WAAA,GAAc,OAAQ,CAAA,OAAA;AAAA;AAExB,IAAgB,YAAA,IAAA,CAAA,UAAA,EAAa,WAAY,CAAA,WAAA,EAAa,CAAA,CAAA;AAAA;AAGxD,EAAgB,YAAA,IAAA,CAAA,OAAA,EAAU,OAAQ,CAAA,IAAA,IAAQ,GAAG,CAAA,CAAA;AAE7C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA;AAG5C,EAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,IAAgB,YAAA,IAAA,UAAA;AAAA;AAGlB,EAAA,QAAA,CAAS,MAAS,GAAA,YAAA;AACpB;AAEO,IAAM,YAAe,GAAA,CAAC,IAAc,EAAA,OAAA,GAA8C,EAAa,KAAA;AACpG,EAAI,IAAA,CAAC,UAAY,EAAA;AACf,IAAA;AAAA;AAEF,EAAA,SAAA,CAAU,MAAM,EAAI,EAAA,EAAE,GAAG,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AACjD","file":"cookie-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 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 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 = (pathname?: string) => {\n if (pathname) {\n return pathname.split('/')[1] ?? '';\n }\n\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 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 * @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","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"]}
@@ -56,7 +56,10 @@ var isStorybookEnv = () => {
56
56
  return false;
57
57
  }
58
58
  };
59
- var getBusinessWorkDivisionCode = () => {
59
+ var getBusinessWorkDivisionCode = (pathname) => {
60
+ if (pathname) {
61
+ return pathname.split("/")[1] ?? "";
62
+ }
60
63
  return location.pathname.split("/")[1] ?? "";
61
64
  };
62
65
  var getServicePath = () => {
@@ -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\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
+ {"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 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 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 = (pathname?: string) => {\n if (pathname) {\n return pathname.split('/')[1] ?? '';\n }\n\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 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 * @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"]}
@@ -41,7 +41,7 @@ declare const isStorybookEnv: () => boolean;
41
41
  * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환
42
42
  * @returns
43
43
  */
44
- declare const getBusinessWorkDivisionCode: () => string;
44
+ declare const getBusinessWorkDivisionCode: (pathname?: string) => string;
45
45
  /**
46
46
  * @description storybook에서 동작을 고려하여 수정한 버전
47
47
  * @returns
@@ -41,7 +41,7 @@ declare const isStorybookEnv: () => boolean;
41
41
  * 원칙: pathname의 첫 번째가 업무구분코드를 사용할 경우 해당 값을 반환
42
42
  * @returns
43
43
  */
44
- declare const getBusinessWorkDivisionCode: () => string;
44
+ declare const getBusinessWorkDivisionCode: (pathname?: string) => string;
45
45
  /**
46
46
  * @description storybook에서 동작을 고려하여 수정한 버전
47
47
  * @returns
@@ -54,7 +54,10 @@ var isStorybookEnv = () => {
54
54
  return false;
55
55
  }
56
56
  };
57
- var getBusinessWorkDivisionCode = () => {
57
+ var getBusinessWorkDivisionCode = (pathname) => {
58
+ if (pathname) {
59
+ return pathname.split("/")[1] ?? "";
60
+ }
58
61
  return location.pathname.split("/")[1] ?? "";
59
62
  };
60
63
  var getServicePath = () => {
@@ -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\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
+ {"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 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 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 = (pathname?: string) => {\n if (pathname) {\n return pathname.split('/')[1] ?? '';\n }\n\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 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 * @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"]}
@@ -26,23 +26,40 @@ function base64ToBlob(base64String, contentType = "") {
26
26
  const regex = /^data:([a-zA-Z0-9/+.-]+);base64,/;
27
27
  const matches = base64String.match(regex);
28
28
  if (matches === null) {
29
- throw new Error("Invalid base64 string");
29
+ const debugInfo = {
30
+ base64String
31
+ };
32
+ throw new Error(`Invalid base64 string format. Debug info: ${JSON.stringify(debugInfo, null, 2)}`);
30
33
  }
31
34
  const contentTypeFinal = contentType || matches[1];
32
- const byteCharacters = atob(base64String.replace(regex, ""));
33
- const byteNumbers = new Array(byteCharacters.length);
34
- for (let i = 0; i < byteCharacters.length; i++) {
35
- byteNumbers[i] = byteCharacters.charCodeAt(i);
35
+ try {
36
+ const byteCharacters = atob(base64String.replace(regex, ""));
37
+ const byteNumbers = new Array(byteCharacters.length);
38
+ for (let i = 0; i < byteCharacters.length; i++) {
39
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
40
+ }
41
+ const byteArray = new Uint8Array(byteNumbers);
42
+ return new Blob([byteArray], { type: contentTypeFinal });
43
+ } catch (error) {
44
+ throw new Error(
45
+ `Failed to decode base64 string. Original error: ${error instanceof Error ? error.message : "Unknown error"}. String length: ${base64String?.length}, Content type: ${contentTypeFinal}`
46
+ );
36
47
  }
37
- const byteArray = new Uint8Array(byteNumbers);
38
- return new Blob([byteArray], { type: contentTypeFinal });
39
48
  }
40
49
  function base64ToFile(base64String, fileName, contentType = "") {
41
- const blob = base64ToBlob(base64String, contentType);
42
- if (!blob) {
43
- throw new Error("Invalid base64 string");
50
+ try {
51
+ const blob = base64ToBlob(base64String, contentType);
52
+ if (!blob) {
53
+ throw new Error(
54
+ `Failed to create blob. FileName: ${fileName}, ContentType: ${contentType}, StringLength: ${base64String?.length}`
55
+ );
56
+ }
57
+ return blobToFile(blob, fileName);
58
+ } catch (error) {
59
+ throw new Error(
60
+ `base64ToFile failed for "${fileName}". ${error instanceof Error ? error.message : "Unknown error"}`
61
+ );
44
62
  }
45
- return blobToFile(blob, fileName);
46
63
  }
47
64
  function blobToFile(blob, fileName) {
48
65
  return new File([blob], fileName, {