@withwiz/toolkit 0.2.0 → 0.2.2

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 (95) hide show
  1. package/dist/auth/index.js +19 -19
  2. package/dist/chunk-7IY3RQQL.js +151 -0
  3. package/dist/chunk-GSUQE3SZ.js +225 -0
  4. package/dist/chunk-IPXPCBDO.js +127 -0
  5. package/dist/chunk-LJEGM4OO.js +136 -0
  6. package/dist/chunk-MAATEX2R.js +81 -0
  7. package/dist/chunk-NY5QXT33.js +31 -0
  8. package/dist/chunk-TH45RVP7.js +110 -0
  9. package/dist/components/ui/DataTable.d.ts +8 -103
  10. package/dist/components/ui/DataTable.js +17 -602
  11. package/dist/components/ui/data-table/DataTable.d.ts +2 -0
  12. package/dist/components/ui/data-table/DataTable.js +22 -0
  13. package/dist/components/ui/data-table/DataTableBody.d.ts +19 -0
  14. package/dist/components/ui/data-table/DataTableBody.js +10 -0
  15. package/dist/components/ui/data-table/DataTableBulkActions.d.ts +17 -0
  16. package/dist/components/ui/data-table/DataTableBulkActions.js +12 -0
  17. package/dist/components/ui/data-table/DataTableFilters.d.ts +15 -0
  18. package/dist/components/ui/data-table/DataTableFilters.js +13 -0
  19. package/dist/components/ui/data-table/DataTablePagination.d.ts +10 -0
  20. package/dist/components/ui/data-table/DataTablePagination.js +11 -0
  21. package/dist/components/ui/data-table/DataTableSearch.d.ts +24 -0
  22. package/dist/components/ui/data-table/DataTableSearch.js +12 -0
  23. package/dist/components/ui/data-table/index.d.ts +13 -0
  24. package/dist/components/ui/data-table/types.d.ts +115 -0
  25. package/dist/error/index.d.ts +0 -4
  26. package/dist/error/index.js +1 -69
  27. package/dist/geolocation/index.js +4 -4
  28. package/dist/geolocation/providers/index.js +4 -4
  29. package/dist/hooks/useDataTable.d.ts +45 -0
  30. package/dist/hooks/useDataTable.js +13 -11
  31. package/dist/utils/format-number.js +30 -4
  32. package/dist/utils/short-code-generator.js +36 -4
  33. package/dist/utils/url-normalizer.js +194 -10
  34. package/package.json +3 -2
  35. package/dist/chunk-5ATB5D6S.js +0 -40
  36. package/dist/chunk-6C7HQIX4.js +0 -13
  37. package/dist/chunk-7VJNLGAS.js +0 -110
  38. package/dist/chunk-7XFHGAJP.js +0 -0
  39. package/dist/chunk-A6EAAWMK.js +0 -50
  40. package/dist/chunk-COK4ZXNG.js +0 -0
  41. package/dist/chunk-EQYTE7WD.js +0 -139
  42. package/dist/chunk-FW3IEJ7H.js +0 -71
  43. package/dist/chunk-HGC4CCKB.js +0 -29
  44. package/dist/chunk-IAJNC34M.js +0 -102
  45. package/dist/chunk-JS5VI3OW.js +0 -143
  46. package/dist/chunk-MYLGYX4K.js +0 -57
  47. package/dist/chunk-TDZJ6SAI.js +0 -34
  48. package/dist/chunk-TEIYA7U4.js +0 -72
  49. package/dist/chunk-ULF5RDDX.js +0 -0
  50. package/dist/chunk-VWODEQ5C.js +0 -204
  51. package/dist/chunk-Y2TUZFCP.js +0 -0
  52. package/dist/chunk-YJ3TLEW3.js +0 -100
  53. package/dist/chunk-ZHVUK5OY.js +0 -314
  54. package/dist/chunk-ZZIKRBJU.js +0 -96
  55. package/dist/error/components/EmptyState.d.ts +0 -50
  56. package/dist/error/components/ErrorAlert.d.ts +0 -50
  57. package/dist/error/components/ErrorPage.d.ts +0 -39
  58. package/dist/error/components/LoadingState.d.ts +0 -37
  59. package/dist/error/components/index.d.ts +0 -13
  60. package/dist/error/components/index.js +0 -18
  61. package/dist/error/hooks/index.d.ts +0 -7
  62. package/dist/error/hooks/index.js +0 -14
  63. package/dist/error/hooks/useErrorHandler.d.ts +0 -67
  64. package/dist/error/hooks/useErrorHandler.js +0 -14
  65. package/dist/error/logging/error-logger.d.ts +0 -77
  66. package/dist/error/logging/error-logger.js +0 -10
  67. package/dist/error/logging/index.d.ts +0 -9
  68. package/dist/error/logging/index.js +0 -35
  69. package/dist/error/logging/transports/base.d.ts +0 -30
  70. package/dist/error/logging/transports/base.js +0 -7
  71. package/dist/error/logging/transports/console.d.ts +0 -40
  72. package/dist/error/logging/transports/console.js +0 -9
  73. package/dist/error/logging/transports/file.d.ts +0 -49
  74. package/dist/error/logging/transports/file.js +0 -8
  75. package/dist/error/logging/transports/index.d.ts +0 -12
  76. package/dist/error/logging/transports/index.js +0 -25
  77. package/dist/error/logging/transports/sentry.d.ts +0 -44
  78. package/dist/error/logging/transports/sentry.js +0 -9
  79. package/dist/error/logging/transports/slack.d.ts +0 -51
  80. package/dist/error/logging/transports/slack.js +0 -9
  81. package/dist/error/logging/types.d.ts +0 -83
  82. package/dist/error/logging/types.js +0 -7
  83. package/dist/error/recovery/circuit-breaker.d.ts +0 -85
  84. package/dist/error/recovery/circuit-breaker.js +0 -9
  85. package/dist/error/recovery/degradation.d.ts +0 -56
  86. package/dist/error/recovery/degradation.js +0 -7
  87. package/dist/error/recovery/fallback.d.ts +0 -55
  88. package/dist/error/recovery/fallback.js +0 -11
  89. package/dist/error/recovery/index.d.ts +0 -12
  90. package/dist/error/recovery/index.js +0 -26
  91. package/dist/error/recovery/retry.d.ts +0 -44
  92. package/dist/error/recovery/retry.js +0 -7
  93. package/dist/utils/shared-utils.d.ts +0 -25
  94. package/dist/utils/shared-utils.js +0 -43
  95. package/dist/{chunk-S73334QY.js → chunk-QF6FH4GZ.js} +3 -3
@@ -1,14 +1,198 @@
1
- import {
2
- SUPPORTED_SCHEMES,
3
- extractScheme,
4
- getUrlType,
5
- hasValidScheme,
6
- isAppScheme,
7
- isWebUrl,
8
- normalizeUrl,
9
- validateUrl
10
- } from "../chunk-VWODEQ5C.js";
11
1
  import "../chunk-ORMEWXMH.js";
2
+
3
+ // src/utils/url-normalizer.ts
4
+ var SUPPORTED_SCHEMES = [
5
+ "http:",
6
+ "https:",
7
+ "mailto:",
8
+ "tel:",
9
+ "sms:",
10
+ "ftp:",
11
+ "ftps:",
12
+ // 'file:' - 보안상 제거 (로컬 파일 접근 방지)
13
+ // 'data:' - XSS 공격 벡터로 제거 (CVSS 7.5)
14
+ // Mobile app schemes
15
+ "intent:",
16
+ "market:",
17
+ "itms:",
18
+ "itms-apps:",
19
+ // Social media apps
20
+ "fb:",
21
+ "instagram:",
22
+ "twitter:",
23
+ "youtube:",
24
+ "linkedin:",
25
+ "tiktok:",
26
+ // Messaging apps
27
+ "whatsapp:",
28
+ "telegram:",
29
+ "line:",
30
+ "kakaotalk:",
31
+ "viber:",
32
+ "wechat:",
33
+ "slack:",
34
+ "discord:",
35
+ // Other apps
36
+ "spotify:",
37
+ "zoom:",
38
+ "skype:",
39
+ "maps:",
40
+ "geo:"
41
+ ];
42
+ var CUSTOM_SCHEME_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
43
+ function hasValidScheme(url) {
44
+ try {
45
+ const urlObj = new URL(url);
46
+ const protocol = urlObj.protocol;
47
+ if (SUPPORTED_SCHEMES.includes(protocol)) {
48
+ return true;
49
+ }
50
+ if (CUSTOM_SCHEME_PATTERN.test(url)) {
51
+ return true;
52
+ }
53
+ return false;
54
+ } catch (e) {
55
+ return false;
56
+ }
57
+ }
58
+ function extractScheme(url) {
59
+ const match = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\/?\/?/);
60
+ return match ? match[1] : null;
61
+ }
62
+ function normalizeUrl(url) {
63
+ if (!url) {
64
+ return "";
65
+ }
66
+ let normalized = url.trim();
67
+ if (!normalized) {
68
+ return "";
69
+ }
70
+ const scheme = extractScheme(normalized);
71
+ if (scheme) {
72
+ return normalized;
73
+ }
74
+ if (normalized.startsWith("//")) {
75
+ return `https:${normalized}`;
76
+ }
77
+ return `https://${normalized}`;
78
+ }
79
+ function validateUrl(url, options) {
80
+ if (!url || !url.trim()) {
81
+ return {
82
+ isValid: false,
83
+ message: "URL\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694",
84
+ messageKey: "urlRequired"
85
+ };
86
+ }
87
+ const normalized = (options == null ? void 0 : options.skipNormalization) ? url.trim() : normalizeUrl(url);
88
+ try {
89
+ const urlObj = new URL(normalized);
90
+ const protocol = urlObj.protocol;
91
+ const isSupported = SUPPORTED_SCHEMES.includes(protocol);
92
+ const isCustom = CUSTOM_SCHEME_PATTERN.test(normalized);
93
+ if (!isSupported && !isCustom) {
94
+ return {
95
+ isValid: false,
96
+ message: `\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD504\uB85C\uD1A0\uCF5C\uC785\uB2C8\uB2E4: ${protocol}`,
97
+ messageKey: "unsupportedProtocol",
98
+ messageParams: { protocol }
99
+ };
100
+ }
101
+ if (protocol === "http:" || protocol === "https:") {
102
+ if (!urlObj.hostname || urlObj.hostname.length < 1) {
103
+ return {
104
+ isValid: false,
105
+ message: "\uC720\uD6A8\uD55C \uB3C4\uBA54\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694",
106
+ messageKey: "invalidDomain"
107
+ };
108
+ }
109
+ if (!urlObj.hostname.includes(".") && urlObj.hostname !== "localhost") {
110
+ return {
111
+ isValid: false,
112
+ message: "\uC720\uD6A8\uD55C \uB3C4\uBA54\uC778 \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4",
113
+ messageKey: "invalidDomainFormat"
114
+ };
115
+ }
116
+ }
117
+ if (protocol === "mailto:") {
118
+ const email = urlObj.pathname;
119
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
120
+ if (!emailRegex.test(email)) {
121
+ return {
122
+ isValid: false,
123
+ message: "\uC720\uD6A8\uD55C \uC774\uBA54\uC77C \uC8FC\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4",
124
+ messageKey: "invalidEmail"
125
+ };
126
+ }
127
+ }
128
+ if (protocol === "tel:") {
129
+ const phone = urlObj.pathname;
130
+ if (!/\d/.test(phone)) {
131
+ return {
132
+ isValid: false,
133
+ message: "\uC720\uD6A8\uD55C \uC804\uD654\uBC88\uD638\uAC00 \uC544\uB2D9\uB2C8\uB2E4",
134
+ messageKey: "invalidPhone"
135
+ };
136
+ }
137
+ }
138
+ if (normalized.length > 2048) {
139
+ return {
140
+ isValid: false,
141
+ message: "URL\uC774 \uB108\uBB34 \uAE41\uB2C8\uB2E4 (\uCD5C\uB300 2048\uC790)",
142
+ messageKey: "urlTooLong"
143
+ };
144
+ }
145
+ return {
146
+ isValid: true,
147
+ message: "\uC720\uD6A8\uD55C URL\uC785\uB2C8\uB2E4",
148
+ messageKey: "validUrl",
149
+ normalizedUrl: normalized
150
+ };
151
+ } catch (error) {
152
+ return {
153
+ isValid: false,
154
+ message: "\uC720\uD6A8\uD55C URL \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4",
155
+ messageKey: "invalidUrlFormat"
156
+ };
157
+ }
158
+ }
159
+ function isWebUrl(url) {
160
+ try {
161
+ const urlObj = new URL(url);
162
+ return urlObj.protocol === "http:" || urlObj.protocol === "https:";
163
+ } catch (e) {
164
+ return false;
165
+ }
166
+ }
167
+ function isAppScheme(url) {
168
+ try {
169
+ const urlObj = new URL(url);
170
+ return !["http:", "https:", "ftp:", "ftps:", "file:"].includes(urlObj.protocol);
171
+ } catch (e) {
172
+ return false;
173
+ }
174
+ }
175
+ function getUrlType(url) {
176
+ try {
177
+ const urlObj = new URL(url);
178
+ const protocol = urlObj.protocol;
179
+ if (protocol === "http:" || protocol === "https:") {
180
+ return "web";
181
+ }
182
+ if (protocol === "mailto:") {
183
+ return "email";
184
+ }
185
+ if (protocol === "tel:" || protocol === "sms:") {
186
+ return "tel";
187
+ }
188
+ if (isAppScheme(url)) {
189
+ return "app";
190
+ }
191
+ return "other";
192
+ } catch (e) {
193
+ return "other";
194
+ }
195
+ }
12
196
  export {
13
197
  SUPPORTED_SCHEMES,
14
198
  extractScheme,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withwiz/toolkit",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Shared utility library for withwiz projects",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -30,6 +30,8 @@
30
30
  "./cache/cache-env": "./dist/cache/cache-env.js",
31
31
  "./cache/hybrid-cache-manager": "./dist/cache/hybrid-cache-manager.js",
32
32
  "./components/ui/*": "./dist/components/ui/*.js",
33
+ "./components/ui/data-table": "./dist/components/ui/data-table/index.js",
34
+ "./components/ui/data-table/*": "./dist/components/ui/data-table/*.js",
33
35
  "./constants": "./dist/constants/index.js",
34
36
  "./constants/error-codes": "./dist/constants/error-codes.js",
35
37
  "./constants/messages": "./dist/constants/messages.js",
@@ -80,7 +82,6 @@
80
82
  "./utils/ip-utils": "./dist/utils/ip-utils.js",
81
83
  "./utils/optimistic-lock": "./dist/utils/optimistic-lock.js",
82
84
  "./utils/sanitizer": "./dist/utils/sanitizer.js",
83
- "./utils/shared-utils": "./dist/utils/shared-utils.js",
84
85
  "./utils/short-code-generator": "./dist/utils/short-code-generator.js",
85
86
  "./utils/timezone": "./dist/utils/timezone.js",
86
87
  "./utils/type-guards": "./dist/utils/type-guards.js",
@@ -1,40 +0,0 @@
1
- // src/utils/short-code-generator.ts
2
- function generateShortCode(length = 8) {
3
- if (!Number.isInteger(length) || length <= 0) {
4
- throw new Error("length must be a positive integer");
5
- }
6
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
7
- let result = "";
8
- for (let i = 0; i < length; i++) {
9
- result += chars.charAt(Math.floor(Math.random() * chars.length));
10
- }
11
- return result;
12
- }
13
- async function generateUniqueShortCode(options = {}) {
14
- const {
15
- length = 8,
16
- maxAttempts = 100,
17
- checkDuplicate
18
- } = options;
19
- let shortCode;
20
- let attempts = 0;
21
- do {
22
- shortCode = generateShortCode(length);
23
- attempts++;
24
- if (checkDuplicate) {
25
- const isDuplicate = await checkDuplicate(shortCode);
26
- if (!isDuplicate) break;
27
- } else {
28
- break;
29
- }
30
- if (attempts >= maxAttempts) {
31
- throw new Error("Failed to generate unique shortCode after multiple attempts");
32
- }
33
- } while (true);
34
- return shortCode;
35
- }
36
-
37
- export {
38
- generateShortCode,
39
- generateUniqueShortCode
40
- };
@@ -1,13 +0,0 @@
1
- // src/error/logging/types.ts
2
- var ELogLevel = /* @__PURE__ */ ((ELogLevel2) => {
3
- ELogLevel2["DEBUG"] = "debug";
4
- ELogLevel2["INFO"] = "info";
5
- ELogLevel2["WARN"] = "warn";
6
- ELogLevel2["ERROR"] = "error";
7
- ELogLevel2["CRITICAL"] = "critical";
8
- return ELogLevel2;
9
- })(ELogLevel || {});
10
-
11
- export {
12
- ELogLevel
13
- };
@@ -1,110 +0,0 @@
1
- // src/error/recovery/circuit-breaker.ts
2
- var ECircuitState = /* @__PURE__ */ ((ECircuitState2) => {
3
- ECircuitState2["CLOSED"] = "closed";
4
- ECircuitState2["OPEN"] = "open";
5
- ECircuitState2["HALF_OPEN"] = "half-open";
6
- return ECircuitState2;
7
- })(ECircuitState || {});
8
- var CircuitBreaker = class {
9
- constructor(options = {}) {
10
- this.state = "closed" /* CLOSED */;
11
- this.failureCount = 0;
12
- this.successCount = 0;
13
- this.nextAttemptTime = 0;
14
- this.options = {
15
- failureThreshold: options.failureThreshold || 5,
16
- successThreshold: options.successThreshold || 2,
17
- timeout: options.timeout || 6e4,
18
- onStateChange: options.onStateChange || (() => {
19
- }),
20
- onError: options.onError || (() => {
21
- })
22
- };
23
- }
24
- /**
25
- * 함수 실행
26
- */
27
- async execute(fn) {
28
- if (this.state === "open" /* OPEN */) {
29
- if (Date.now() < this.nextAttemptTime) {
30
- throw new Error("Circuit breaker is OPEN");
31
- }
32
- this.setState("half-open" /* HALF_OPEN */);
33
- }
34
- try {
35
- const result = await fn();
36
- this.onSuccess();
37
- return result;
38
- } catch (error) {
39
- this.onFailure();
40
- this.options.onError(error);
41
- throw error;
42
- }
43
- }
44
- /**
45
- * 성공 처리
46
- */
47
- onSuccess() {
48
- this.failureCount = 0;
49
- if (this.state === "half-open" /* HALF_OPEN */) {
50
- this.successCount++;
51
- if (this.successCount >= this.options.successThreshold) {
52
- this.setState("closed" /* CLOSED */);
53
- this.successCount = 0;
54
- }
55
- }
56
- }
57
- /**
58
- * 실패 처리
59
- */
60
- onFailure() {
61
- this.failureCount++;
62
- this.successCount = 0;
63
- if (this.failureCount >= this.options.failureThreshold) {
64
- this.setState("open" /* OPEN */);
65
- this.nextAttemptTime = Date.now() + this.options.timeout;
66
- }
67
- }
68
- /**
69
- * 상태 변경
70
- */
71
- setState(newState) {
72
- const oldState = this.state;
73
- if (oldState !== newState) {
74
- this.state = newState;
75
- this.options.onStateChange(oldState, newState);
76
- console.log(`[CircuitBreaker] State changed: ${oldState} -> ${newState}`);
77
- }
78
- }
79
- /**
80
- * 현재 상태 조회
81
- */
82
- getState() {
83
- return this.state;
84
- }
85
- /**
86
- * 상태 초기화
87
- */
88
- reset() {
89
- this.setState("closed" /* CLOSED */);
90
- this.failureCount = 0;
91
- this.successCount = 0;
92
- this.nextAttemptTime = 0;
93
- }
94
- /**
95
- * 메트릭 조회
96
- */
97
- getMetrics() {
98
- return {
99
- state: this.state,
100
- failureCount: this.failureCount,
101
- successCount: this.successCount,
102
- nextAttemptTime: this.nextAttemptTime
103
- };
104
- }
105
- };
106
-
107
- export {
108
- ECircuitState,
109
- CircuitBreaker
110
- };
File without changes
@@ -1,50 +0,0 @@
1
- // src/error/recovery/retry.ts
2
- function defaultShouldRetry(error) {
3
- if (error instanceof Error) {
4
- const message = error.message.toLowerCase();
5
- return message.includes("network") || message.includes("timeout") || message.includes("econnrefused") || message.includes("enotfound") || message.includes("503") || message.includes("504");
6
- }
7
- return false;
8
- }
9
- async function withRetry(fn, options = {}) {
10
- const {
11
- maxAttempts = 3,
12
- delay = 1e3,
13
- exponentialBackoff = true,
14
- backoffMultiplier = 2,
15
- maxDelay = 3e4,
16
- shouldRetry = defaultShouldRetry,
17
- onRetry
18
- } = options;
19
- let lastError;
20
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
21
- try {
22
- return await fn();
23
- } catch (error) {
24
- lastError = error;
25
- if (attempt === maxAttempts) {
26
- throw error;
27
- }
28
- if (!shouldRetry(error, attempt)) {
29
- throw error;
30
- }
31
- onRetry == null ? void 0 : onRetry(error, attempt);
32
- let currentDelay = delay;
33
- if (exponentialBackoff) {
34
- currentDelay = Math.min(
35
- delay * Math.pow(backoffMultiplier, attempt - 1),
36
- maxDelay
37
- );
38
- }
39
- await sleep(currentDelay);
40
- }
41
- }
42
- throw lastError;
43
- }
44
- function sleep(ms) {
45
- return new Promise((resolve) => setTimeout(resolve, ms));
46
- }
47
-
48
- export {
49
- withRetry
50
- };
File without changes
@@ -1,139 +0,0 @@
1
- import {
2
- BaseTransport
3
- } from "./chunk-HGC4CCKB.js";
4
-
5
- // src/error/logging/transports/slack.ts
6
- var LEVEL_COLORS = {
7
- ["debug" /* DEBUG */]: "#36a64f",
8
- // Green
9
- ["info" /* INFO */]: "#2196F3",
10
- // Blue
11
- ["warn" /* WARN */]: "#FFC107",
12
- // Amber
13
- ["error" /* ERROR */]: "#F44336",
14
- // Red
15
- ["critical" /* CRITICAL */]: "#9C27B0"
16
- // Purple
17
- };
18
- var SlackTransport = class extends BaseTransport {
19
- constructor(options = {}) {
20
- const webhookUrl = options.webhookUrl || process.env.SLACK_WEBHOOK_URL;
21
- super("slack", Boolean(webhookUrl) && options.enabled !== false);
22
- this.webhookUrl = webhookUrl;
23
- this.minLevel = options.minLevel || "critical" /* CRITICAL */;
24
- this.channel = options.channel;
25
- this.username = options.username || "Error Logger";
26
- this.iconEmoji = options.iconEmoji || ":rotating_light:";
27
- }
28
- async log(entry) {
29
- if (!this.webhookUrl) {
30
- return;
31
- }
32
- if (!this.shouldLog(entry.level)) {
33
- return;
34
- }
35
- try {
36
- const payload = this.buildPayload(entry);
37
- const response = await fetch(this.webhookUrl, {
38
- method: "POST",
39
- headers: {
40
- "Content-Type": "application/json"
41
- },
42
- body: JSON.stringify(payload)
43
- });
44
- if (!response.ok) {
45
- throw new Error(`Slack webhook failed: ${response.statusText}`);
46
- }
47
- } catch (error) {
48
- console.error("[SlackTransport] Failed to send to Slack:", error);
49
- }
50
- }
51
- /**
52
- * Slack 메시지 페이로드 생성
53
- */
54
- buildPayload(entry) {
55
- const payload = {
56
- username: this.username,
57
- icon_emoji: this.iconEmoji
58
- };
59
- if (this.channel) {
60
- payload.channel = this.channel;
61
- }
62
- const attachment = {
63
- color: LEVEL_COLORS[entry.level],
64
- title: `${entry.level.toUpperCase()}: ${entry.message}`,
65
- timestamp: Math.floor(entry.timestamp.getTime() / 1e3),
66
- fields: []
67
- };
68
- if (entry.context.requestId) {
69
- attachment.fields.push({
70
- title: "Request ID",
71
- value: entry.context.requestId,
72
- short: true
73
- });
74
- }
75
- if (entry.context.errorCode) {
76
- attachment.fields.push({
77
- title: "Error Code",
78
- value: entry.context.errorCode,
79
- short: true
80
- });
81
- }
82
- if (entry.context.userId) {
83
- attachment.fields.push({
84
- title: "User ID",
85
- value: entry.context.userId,
86
- short: true
87
- });
88
- }
89
- if (entry.context.environment) {
90
- attachment.fields.push({
91
- title: "Environment",
92
- value: entry.context.environment,
93
- short: true
94
- });
95
- }
96
- if (entry.context.path) {
97
- attachment.fields.push({
98
- title: "Path",
99
- value: entry.context.path,
100
- short: false
101
- });
102
- }
103
- if (entry.error && entry.error.stack) {
104
- attachment.fields.push({
105
- title: "Stack Trace",
106
- value: `\`\`\`${this.truncate(entry.error.stack, 1e3)}\`\`\``,
107
- short: false
108
- });
109
- }
110
- payload.attachments = [attachment];
111
- return payload;
112
- }
113
- /**
114
- * 문자열 자르기
115
- */
116
- truncate(str, maxLength) {
117
- if (str.length <= maxLength) {
118
- return str;
119
- }
120
- return str.substring(0, maxLength) + "...";
121
- }
122
- /**
123
- * 로그 레벨 체크
124
- */
125
- shouldLog(level) {
126
- const LOG_LEVEL_PRIORITY = {
127
- ["debug" /* DEBUG */]: 0,
128
- ["info" /* INFO */]: 1,
129
- ["warn" /* WARN */]: 2,
130
- ["error" /* ERROR */]: 3,
131
- ["critical" /* CRITICAL */]: 4
132
- };
133
- return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.minLevel];
134
- }
135
- };
136
-
137
- export {
138
- SlackTransport
139
- };
@@ -1,71 +0,0 @@
1
- import {
2
- BaseTransport
3
- } from "./chunk-HGC4CCKB.js";
4
-
5
- // src/error/logging/transports/console.ts
6
- var COLORS = {
7
- ["debug" /* DEBUG */]: "\x1B[36m",
8
- // Cyan
9
- ["info" /* INFO */]: "\x1B[32m",
10
- // Green
11
- ["warn" /* WARN */]: "\x1B[33m",
12
- // Yellow
13
- ["error" /* ERROR */]: "\x1B[31m",
14
- // Red
15
- ["critical" /* CRITICAL */]: "\x1B[35m",
16
- // Magenta
17
- reset: "\x1B[0m"
18
- };
19
- var ConsoleTransport = class extends BaseTransport {
20
- constructor(options = {}) {
21
- super("console", options.enabled !== false);
22
- this.colorize = options.colorize !== false;
23
- this.includeTimestamp = options.includeTimestamp !== false;
24
- }
25
- async log(entry) {
26
- const formatted = this.format(entry);
27
- this.output(entry.level, formatted);
28
- }
29
- /**
30
- * 로그 포맷팅
31
- */
32
- format(entry) {
33
- const parts = [];
34
- if (this.includeTimestamp) {
35
- parts.push(`[${entry.timestamp.toISOString()}]`);
36
- }
37
- const levelText = this.colorize ? `${COLORS[entry.level]}${entry.level.toUpperCase()}${COLORS.reset}` : entry.level.toUpperCase();
38
- parts.push(`[${levelText}]`);
39
- parts.push(entry.message);
40
- if (Object.keys(entry.context).length > 0) {
41
- parts.push(JSON.stringify(entry.context, null, 2));
42
- }
43
- if (entry.error && entry.error.stack) {
44
- parts.push(`
45
- Stack: ${entry.error.stack}`);
46
- }
47
- return parts.join(" ");
48
- }
49
- /**
50
- * 콘솔 출력
51
- */
52
- output(level, message) {
53
- switch (level) {
54
- case "debug" /* DEBUG */:
55
- case "info" /* INFO */:
56
- console.log(message);
57
- break;
58
- case "warn" /* WARN */:
59
- console.warn(message);
60
- break;
61
- case "error" /* ERROR */:
62
- case "critical" /* CRITICAL */:
63
- console.error(message);
64
- break;
65
- }
66
- }
67
- };
68
-
69
- export {
70
- ConsoleTransport
71
- };
@@ -1,29 +0,0 @@
1
- // src/error/logging/transports/base.ts
2
- var BaseTransport = class {
3
- constructor(name, enabled = true) {
4
- this.name = name;
5
- this.enabled = enabled;
6
- }
7
- /**
8
- * Transport 활성화 여부
9
- */
10
- isEnabled() {
11
- return this.enabled;
12
- }
13
- /**
14
- * Transport 활성화
15
- */
16
- enable() {
17
- this.enabled = true;
18
- }
19
- /**
20
- * Transport 비활성화
21
- */
22
- disable() {
23
- this.enabled = false;
24
- }
25
- };
26
-
27
- export {
28
- BaseTransport
29
- };