@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.
- package/dist/auth/index.js +19 -19
- package/dist/chunk-7IY3RQQL.js +151 -0
- package/dist/chunk-GSUQE3SZ.js +225 -0
- package/dist/chunk-IPXPCBDO.js +127 -0
- package/dist/chunk-LJEGM4OO.js +136 -0
- package/dist/chunk-MAATEX2R.js +81 -0
- package/dist/chunk-NY5QXT33.js +31 -0
- package/dist/chunk-TH45RVP7.js +110 -0
- package/dist/components/ui/DataTable.d.ts +8 -103
- package/dist/components/ui/DataTable.js +17 -602
- package/dist/components/ui/data-table/DataTable.d.ts +2 -0
- package/dist/components/ui/data-table/DataTable.js +22 -0
- package/dist/components/ui/data-table/DataTableBody.d.ts +19 -0
- package/dist/components/ui/data-table/DataTableBody.js +10 -0
- package/dist/components/ui/data-table/DataTableBulkActions.d.ts +17 -0
- package/dist/components/ui/data-table/DataTableBulkActions.js +12 -0
- package/dist/components/ui/data-table/DataTableFilters.d.ts +15 -0
- package/dist/components/ui/data-table/DataTableFilters.js +13 -0
- package/dist/components/ui/data-table/DataTablePagination.d.ts +10 -0
- package/dist/components/ui/data-table/DataTablePagination.js +11 -0
- package/dist/components/ui/data-table/DataTableSearch.d.ts +24 -0
- package/dist/components/ui/data-table/DataTableSearch.js +12 -0
- package/dist/components/ui/data-table/index.d.ts +13 -0
- package/dist/components/ui/data-table/types.d.ts +115 -0
- package/dist/error/index.d.ts +0 -4
- package/dist/error/index.js +1 -69
- package/dist/geolocation/index.js +4 -4
- package/dist/geolocation/providers/index.js +4 -4
- package/dist/hooks/useDataTable.d.ts +45 -0
- package/dist/hooks/useDataTable.js +13 -11
- package/dist/utils/format-number.js +30 -4
- package/dist/utils/short-code-generator.js +36 -4
- package/dist/utils/url-normalizer.js +194 -10
- package/package.json +3 -2
- package/dist/chunk-5ATB5D6S.js +0 -40
- package/dist/chunk-6C7HQIX4.js +0 -13
- package/dist/chunk-7VJNLGAS.js +0 -110
- package/dist/chunk-7XFHGAJP.js +0 -0
- package/dist/chunk-A6EAAWMK.js +0 -50
- package/dist/chunk-COK4ZXNG.js +0 -0
- package/dist/chunk-EQYTE7WD.js +0 -139
- package/dist/chunk-FW3IEJ7H.js +0 -71
- package/dist/chunk-HGC4CCKB.js +0 -29
- package/dist/chunk-IAJNC34M.js +0 -102
- package/dist/chunk-JS5VI3OW.js +0 -143
- package/dist/chunk-MYLGYX4K.js +0 -57
- package/dist/chunk-TDZJ6SAI.js +0 -34
- package/dist/chunk-TEIYA7U4.js +0 -72
- package/dist/chunk-ULF5RDDX.js +0 -0
- package/dist/chunk-VWODEQ5C.js +0 -204
- package/dist/chunk-Y2TUZFCP.js +0 -0
- package/dist/chunk-YJ3TLEW3.js +0 -100
- package/dist/chunk-ZHVUK5OY.js +0 -314
- package/dist/chunk-ZZIKRBJU.js +0 -96
- package/dist/error/components/EmptyState.d.ts +0 -50
- package/dist/error/components/ErrorAlert.d.ts +0 -50
- package/dist/error/components/ErrorPage.d.ts +0 -39
- package/dist/error/components/LoadingState.d.ts +0 -37
- package/dist/error/components/index.d.ts +0 -13
- package/dist/error/components/index.js +0 -18
- package/dist/error/hooks/index.d.ts +0 -7
- package/dist/error/hooks/index.js +0 -14
- package/dist/error/hooks/useErrorHandler.d.ts +0 -67
- package/dist/error/hooks/useErrorHandler.js +0 -14
- package/dist/error/logging/error-logger.d.ts +0 -77
- package/dist/error/logging/error-logger.js +0 -10
- package/dist/error/logging/index.d.ts +0 -9
- package/dist/error/logging/index.js +0 -35
- package/dist/error/logging/transports/base.d.ts +0 -30
- package/dist/error/logging/transports/base.js +0 -7
- package/dist/error/logging/transports/console.d.ts +0 -40
- package/dist/error/logging/transports/console.js +0 -9
- package/dist/error/logging/transports/file.d.ts +0 -49
- package/dist/error/logging/transports/file.js +0 -8
- package/dist/error/logging/transports/index.d.ts +0 -12
- package/dist/error/logging/transports/index.js +0 -25
- package/dist/error/logging/transports/sentry.d.ts +0 -44
- package/dist/error/logging/transports/sentry.js +0 -9
- package/dist/error/logging/transports/slack.d.ts +0 -51
- package/dist/error/logging/transports/slack.js +0 -9
- package/dist/error/logging/types.d.ts +0 -83
- package/dist/error/logging/types.js +0 -7
- package/dist/error/recovery/circuit-breaker.d.ts +0 -85
- package/dist/error/recovery/circuit-breaker.js +0 -9
- package/dist/error/recovery/degradation.d.ts +0 -56
- package/dist/error/recovery/degradation.js +0 -7
- package/dist/error/recovery/fallback.d.ts +0 -55
- package/dist/error/recovery/fallback.js +0 -11
- package/dist/error/recovery/index.d.ts +0 -12
- package/dist/error/recovery/index.js +0 -26
- package/dist/error/recovery/retry.d.ts +0 -44
- package/dist/error/recovery/retry.js +0 -7
- package/dist/utils/shared-utils.d.ts +0 -25
- package/dist/utils/shared-utils.js +0 -43
- package/dist/{chunk-S73334QY.js → chunk-QF6FH4GZ.js} +3 -3
package/dist/chunk-IAJNC34M.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getErrorDisplayInfo
|
|
3
|
-
} from "./chunk-POKGHK3L.js";
|
|
4
|
-
import {
|
|
5
|
-
AppError
|
|
6
|
-
} from "./chunk-MLGO3HLS.js";
|
|
7
|
-
import {
|
|
8
|
-
ERROR_CODES
|
|
9
|
-
} from "./chunk-Y3OTJH2S.js";
|
|
10
|
-
|
|
11
|
-
// src/error/hooks/useErrorHandler.ts
|
|
12
|
-
import { useState, useCallback } from "react";
|
|
13
|
-
function useErrorHandler(locale = "ko") {
|
|
14
|
-
const [errorState, setErrorState] = useState({
|
|
15
|
-
hasError: false
|
|
16
|
-
});
|
|
17
|
-
const handleError = useCallback(
|
|
18
|
-
(error) => {
|
|
19
|
-
console.error("[useErrorHandler] Error occurred:", error);
|
|
20
|
-
if (error instanceof AppError) {
|
|
21
|
-
const displayInfo2 = getErrorDisplayInfo(error.code, locale);
|
|
22
|
-
setErrorState({
|
|
23
|
-
hasError: true,
|
|
24
|
-
code: error.code,
|
|
25
|
-
message: error.message,
|
|
26
|
-
displayInfo: displayInfo2,
|
|
27
|
-
timestamp: Date.now()
|
|
28
|
-
});
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (error && typeof error === "object" && "error" in error && typeof error.error === "object") {
|
|
32
|
-
const apiError = error.error;
|
|
33
|
-
const code = apiError.code || ERROR_CODES.INTERNAL_SERVER_ERROR.code;
|
|
34
|
-
const displayInfo2 = getErrorDisplayInfo(code, locale);
|
|
35
|
-
setErrorState({
|
|
36
|
-
hasError: true,
|
|
37
|
-
code,
|
|
38
|
-
message: apiError.message || "Unknown error",
|
|
39
|
-
displayInfo: displayInfo2,
|
|
40
|
-
timestamp: Date.now()
|
|
41
|
-
});
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (error instanceof Error) {
|
|
45
|
-
const displayInfo2 = getErrorDisplayInfo(
|
|
46
|
-
ERROR_CODES.INTERNAL_SERVER_ERROR.code,
|
|
47
|
-
locale
|
|
48
|
-
);
|
|
49
|
-
setErrorState({
|
|
50
|
-
hasError: true,
|
|
51
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR.code,
|
|
52
|
-
message: error.message,
|
|
53
|
-
displayInfo: displayInfo2,
|
|
54
|
-
timestamp: Date.now()
|
|
55
|
-
});
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const displayInfo = getErrorDisplayInfo(
|
|
59
|
-
ERROR_CODES.INTERNAL_SERVER_ERROR.code,
|
|
60
|
-
locale
|
|
61
|
-
);
|
|
62
|
-
setErrorState({
|
|
63
|
-
hasError: true,
|
|
64
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR.code,
|
|
65
|
-
message: String(error),
|
|
66
|
-
displayInfo,
|
|
67
|
-
timestamp: Date.now()
|
|
68
|
-
});
|
|
69
|
-
},
|
|
70
|
-
[locale]
|
|
71
|
-
);
|
|
72
|
-
const clearError = useCallback(() => {
|
|
73
|
-
setErrorState({
|
|
74
|
-
hasError: false
|
|
75
|
-
});
|
|
76
|
-
}, []);
|
|
77
|
-
const handleAuthError = useCallback(
|
|
78
|
-
(error, redirectUrl = "/login") => {
|
|
79
|
-
handleError(error);
|
|
80
|
-
if (error instanceof AppError) {
|
|
81
|
-
const httpStatus = Math.floor(error.code / 100);
|
|
82
|
-
if (httpStatus === 401 || httpStatus === 403) {
|
|
83
|
-
setTimeout(() => {
|
|
84
|
-
window.location.href = redirectUrl;
|
|
85
|
-
}, 1e3);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
[handleError]
|
|
90
|
-
);
|
|
91
|
-
return {
|
|
92
|
-
errorState,
|
|
93
|
-
handleError,
|
|
94
|
-
clearError,
|
|
95
|
-
handleAuthError,
|
|
96
|
-
hasError: errorState.hasError
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export {
|
|
101
|
-
useErrorHandler
|
|
102
|
-
};
|
package/dist/chunk-JS5VI3OW.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AppError
|
|
3
|
-
} from "./chunk-MLGO3HLS.js";
|
|
4
|
-
import {
|
|
5
|
-
__spreadProps,
|
|
6
|
-
__spreadValues
|
|
7
|
-
} from "./chunk-ORMEWXMH.js";
|
|
8
|
-
|
|
9
|
-
// src/error/logging/error-logger.ts
|
|
10
|
-
var LOG_LEVEL_PRIORITY = {
|
|
11
|
-
["debug" /* DEBUG */]: 0,
|
|
12
|
-
["info" /* INFO */]: 1,
|
|
13
|
-
["warn" /* WARN */]: 2,
|
|
14
|
-
["error" /* ERROR */]: 3,
|
|
15
|
-
["critical" /* CRITICAL */]: 4
|
|
16
|
-
};
|
|
17
|
-
var ErrorLogger = class {
|
|
18
|
-
constructor(options = {}) {
|
|
19
|
-
this.options = {
|
|
20
|
-
minLevel: options.minLevel || "info" /* INFO */,
|
|
21
|
-
environment: options.environment || process.env.NODE_ENV || "development",
|
|
22
|
-
version: options.version || process.env.APP_VERSION || "1.0.0",
|
|
23
|
-
transports: options.transports || []
|
|
24
|
-
};
|
|
25
|
-
this.transports = this.options.transports.filter((t) => t.isEnabled());
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Transport 추가
|
|
29
|
-
*/
|
|
30
|
-
addTransport(transport) {
|
|
31
|
-
if (transport.isEnabled()) {
|
|
32
|
-
this.transports.push(transport);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Transport 제거
|
|
37
|
-
*/
|
|
38
|
-
removeTransport(transportName) {
|
|
39
|
-
this.transports = this.transports.filter((t) => t.name !== transportName);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Debug 로그
|
|
43
|
-
*/
|
|
44
|
-
debug(message, context) {
|
|
45
|
-
this.log("debug" /* DEBUG */, message, context);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Info 로그
|
|
49
|
-
*/
|
|
50
|
-
info(message, context) {
|
|
51
|
-
this.log("info" /* INFO */, message, context);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Warning 로그
|
|
55
|
-
*/
|
|
56
|
-
warn(message, context) {
|
|
57
|
-
this.log("warn" /* WARN */, message, context);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Error 로그
|
|
61
|
-
*/
|
|
62
|
-
error(message, context, error) {
|
|
63
|
-
this.log("error" /* ERROR */, message, context, error);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Critical 로그
|
|
67
|
-
*/
|
|
68
|
-
critical(message, context, error) {
|
|
69
|
-
this.log("critical" /* CRITICAL */, message, context, error);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* 로그 기록
|
|
73
|
-
*/
|
|
74
|
-
log(level, message, context, error) {
|
|
75
|
-
if (!this.shouldLog(level)) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const entry = {
|
|
79
|
-
level,
|
|
80
|
-
message,
|
|
81
|
-
context: this.enrichContext(context, error),
|
|
82
|
-
error,
|
|
83
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
84
|
-
};
|
|
85
|
-
this.sendToTransports(entry);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* 로그 레벨 체크
|
|
89
|
-
*/
|
|
90
|
-
shouldLog(level) {
|
|
91
|
-
return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.options.minLevel];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* 컨텍스트 보강
|
|
95
|
-
*/
|
|
96
|
-
enrichContext(context, error) {
|
|
97
|
-
const enriched = __spreadProps(__spreadValues({}, context), {
|
|
98
|
-
environment: this.options.environment,
|
|
99
|
-
version: this.options.version,
|
|
100
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
101
|
-
});
|
|
102
|
-
if (error) {
|
|
103
|
-
if (error instanceof AppError) {
|
|
104
|
-
enriched.errorCode = error.code;
|
|
105
|
-
enriched.errorMessage = error.message;
|
|
106
|
-
enriched.errorStack = error.stack;
|
|
107
|
-
} else if (error instanceof Error) {
|
|
108
|
-
enriched.errorMessage = error.message;
|
|
109
|
-
enriched.errorStack = error.stack;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return enriched;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Transport로 전송
|
|
116
|
-
*/
|
|
117
|
-
async sendToTransports(entry) {
|
|
118
|
-
const promises = this.transports.map(
|
|
119
|
-
(transport) => transport.log(entry).catch((err) => {
|
|
120
|
-
console.error(`[ErrorLogger] Transport ${transport.name} failed:`, err);
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
Promise.all(promises).catch(() => {
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* AppError 로깅 헬퍼
|
|
128
|
-
*/
|
|
129
|
-
logAppError(error, context) {
|
|
130
|
-
const httpStatus = Math.floor(error.code / 100);
|
|
131
|
-
if (httpStatus >= 500) {
|
|
132
|
-
this.error(error.message, __spreadProps(__spreadValues({}, context), { error }));
|
|
133
|
-
} else if (httpStatus >= 400) {
|
|
134
|
-
this.warn(error.message, __spreadProps(__spreadValues({}, context), { error }));
|
|
135
|
-
} else {
|
|
136
|
-
this.info(error.message, __spreadProps(__spreadValues({}, context), { error }));
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export {
|
|
142
|
-
ErrorLogger
|
|
143
|
-
};
|
package/dist/chunk-MYLGYX4K.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// src/error/recovery/fallback.ts
|
|
2
|
-
async function withFallback(fn, fallbackValue, options = {}) {
|
|
3
|
-
const { onError, logError = true } = options;
|
|
4
|
-
try {
|
|
5
|
-
return await fn();
|
|
6
|
-
} catch (error) {
|
|
7
|
-
if (logError) {
|
|
8
|
-
console.error("[withFallback] Error occurred, using fallback:", error);
|
|
9
|
-
}
|
|
10
|
-
onError == null ? void 0 : onError(error);
|
|
11
|
-
return fallbackValue;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
async function withFallbackFn(primaryFn, fallbackFn, options = {}) {
|
|
15
|
-
const { onError, logError = true } = options;
|
|
16
|
-
try {
|
|
17
|
-
return await primaryFn();
|
|
18
|
-
} catch (error) {
|
|
19
|
-
if (logError) {
|
|
20
|
-
console.error("[withFallbackFn] Primary failed, trying fallback:", error);
|
|
21
|
-
}
|
|
22
|
-
onError == null ? void 0 : onError(error);
|
|
23
|
-
try {
|
|
24
|
-
return await fallbackFn();
|
|
25
|
-
} catch (fallbackError) {
|
|
26
|
-
console.error("[withFallbackFn] Fallback also failed:", fallbackError);
|
|
27
|
-
throw fallbackError;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async function withFallbackChain(fns, options = {}) {
|
|
32
|
-
const { onError, logError = true } = options;
|
|
33
|
-
const errors = [];
|
|
34
|
-
for (let i = 0; i < fns.length; i++) {
|
|
35
|
-
try {
|
|
36
|
-
return await fns[i]();
|
|
37
|
-
} catch (error) {
|
|
38
|
-
errors.push(error);
|
|
39
|
-
if (logError) {
|
|
40
|
-
console.error(`[withFallbackChain] Attempt ${i + 1} failed:`, error);
|
|
41
|
-
}
|
|
42
|
-
onError == null ? void 0 : onError(error);
|
|
43
|
-
if (i === fns.length - 1) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
`All ${fns.length} attempts failed. Last error: ${error}`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
throw new Error("No functions provided");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export {
|
|
54
|
-
withFallback,
|
|
55
|
-
withFallbackFn,
|
|
56
|
-
withFallbackChain
|
|
57
|
-
};
|
package/dist/chunk-TDZJ6SAI.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// src/utils/format-number.ts
|
|
2
|
-
function formatNumber(num) {
|
|
3
|
-
if (num === null || num === void 0) {
|
|
4
|
-
return "-";
|
|
5
|
-
}
|
|
6
|
-
const numericValue = typeof num === "string" ? parseFloat(num) : num;
|
|
7
|
-
if (isNaN(numericValue)) {
|
|
8
|
-
return "NaN";
|
|
9
|
-
}
|
|
10
|
-
if (!isFinite(numericValue)) {
|
|
11
|
-
return numericValue > 0 ? "Infinity" : "-Infinity";
|
|
12
|
-
}
|
|
13
|
-
const isNegative = numericValue < 0;
|
|
14
|
-
const absNum = Math.abs(numericValue);
|
|
15
|
-
if (absNum < 1e3) {
|
|
16
|
-
return numericValue.toString();
|
|
17
|
-
}
|
|
18
|
-
if (absNum < 1e6) {
|
|
19
|
-
return numericValue.toLocaleString();
|
|
20
|
-
}
|
|
21
|
-
if (absNum < 1e7) {
|
|
22
|
-
return numericValue.toLocaleString();
|
|
23
|
-
}
|
|
24
|
-
const formatted = (absNum / 1e6).toFixed(1) + "M";
|
|
25
|
-
return isNegative ? "-" + formatted : formatted;
|
|
26
|
-
}
|
|
27
|
-
function formatChartNumber(num) {
|
|
28
|
-
return formatNumber(num);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export {
|
|
32
|
-
formatNumber,
|
|
33
|
-
formatChartNumber
|
|
34
|
-
};
|
package/dist/chunk-TEIYA7U4.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__spreadValues
|
|
3
|
-
} from "./chunk-ORMEWXMH.js";
|
|
4
|
-
|
|
5
|
-
// src/error/recovery/degradation.ts
|
|
6
|
-
var FeatureDegradation = class {
|
|
7
|
-
/**
|
|
8
|
-
* 기능 실행 (실패해도 앱은 계속)
|
|
9
|
-
*/
|
|
10
|
-
static async execute(featureName, fn, fallbackValue) {
|
|
11
|
-
try {
|
|
12
|
-
const data = await fn();
|
|
13
|
-
return {
|
|
14
|
-
success: true,
|
|
15
|
-
data
|
|
16
|
-
};
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.warn(`[FeatureDegradation] Feature "${featureName}" failed:`, error);
|
|
19
|
-
return {
|
|
20
|
-
success: false,
|
|
21
|
-
data: fallbackValue,
|
|
22
|
-
error
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 여러 기능을 병렬로 실행 (일부 실패해도 계속)
|
|
28
|
-
*/
|
|
29
|
-
static async executeAll(features) {
|
|
30
|
-
const promises = features.map(
|
|
31
|
-
(feature) => this.execute(feature.name, feature.fn, feature.fallbackValue).then(
|
|
32
|
-
(result) => __spreadValues({
|
|
33
|
-
name: feature.name
|
|
34
|
-
}, result)
|
|
35
|
-
)
|
|
36
|
-
);
|
|
37
|
-
return await Promise.all(promises);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* 타임아웃 포함 실행
|
|
41
|
-
*/
|
|
42
|
-
static async executeWithTimeout(featureName, fn, timeoutMs, fallbackValue) {
|
|
43
|
-
try {
|
|
44
|
-
const data = await Promise.race([
|
|
45
|
-
fn(),
|
|
46
|
-
new Promise(
|
|
47
|
-
(_, reject) => setTimeout(() => reject(new Error("Timeout")), timeoutMs)
|
|
48
|
-
)
|
|
49
|
-
]);
|
|
50
|
-
return {
|
|
51
|
-
success: true,
|
|
52
|
-
data
|
|
53
|
-
};
|
|
54
|
-
} catch (error) {
|
|
55
|
-
const timedOut = error instanceof Error && error.message === "Timeout";
|
|
56
|
-
console.warn(
|
|
57
|
-
`[FeatureDegradation] Feature "${featureName}" ${timedOut ? "timed out" : "failed"}:`,
|
|
58
|
-
error
|
|
59
|
-
);
|
|
60
|
-
return {
|
|
61
|
-
success: false,
|
|
62
|
-
data: fallbackValue,
|
|
63
|
-
error,
|
|
64
|
-
timedOut
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export {
|
|
71
|
-
FeatureDegradation
|
|
72
|
-
};
|
package/dist/chunk-ULF5RDDX.js
DELETED
|
File without changes
|
package/dist/chunk-VWODEQ5C.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
// src/utils/url-normalizer.ts
|
|
2
|
-
var SUPPORTED_SCHEMES = [
|
|
3
|
-
"http:",
|
|
4
|
-
"https:",
|
|
5
|
-
"mailto:",
|
|
6
|
-
"tel:",
|
|
7
|
-
"sms:",
|
|
8
|
-
"ftp:",
|
|
9
|
-
"ftps:",
|
|
10
|
-
// 'file:' - 보안상 제거 (로컬 파일 접근 방지)
|
|
11
|
-
// 'data:' - XSS 공격 벡터로 제거 (CVSS 7.5)
|
|
12
|
-
// Mobile app schemes
|
|
13
|
-
"intent:",
|
|
14
|
-
"market:",
|
|
15
|
-
"itms:",
|
|
16
|
-
"itms-apps:",
|
|
17
|
-
// Social media apps
|
|
18
|
-
"fb:",
|
|
19
|
-
"instagram:",
|
|
20
|
-
"twitter:",
|
|
21
|
-
"youtube:",
|
|
22
|
-
"linkedin:",
|
|
23
|
-
"tiktok:",
|
|
24
|
-
// Messaging apps
|
|
25
|
-
"whatsapp:",
|
|
26
|
-
"telegram:",
|
|
27
|
-
"line:",
|
|
28
|
-
"kakaotalk:",
|
|
29
|
-
"viber:",
|
|
30
|
-
"wechat:",
|
|
31
|
-
"slack:",
|
|
32
|
-
"discord:",
|
|
33
|
-
// Other apps
|
|
34
|
-
"spotify:",
|
|
35
|
-
"zoom:",
|
|
36
|
-
"skype:",
|
|
37
|
-
"maps:",
|
|
38
|
-
"geo:"
|
|
39
|
-
];
|
|
40
|
-
var CUSTOM_SCHEME_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
|
|
41
|
-
function hasValidScheme(url) {
|
|
42
|
-
try {
|
|
43
|
-
const urlObj = new URL(url);
|
|
44
|
-
const protocol = urlObj.protocol;
|
|
45
|
-
if (SUPPORTED_SCHEMES.includes(protocol)) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
if (CUSTOM_SCHEME_PATTERN.test(url)) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
} catch (e) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function extractScheme(url) {
|
|
57
|
-
const match = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\/?\/?/);
|
|
58
|
-
return match ? match[1] : null;
|
|
59
|
-
}
|
|
60
|
-
function normalizeUrl(url) {
|
|
61
|
-
if (!url) {
|
|
62
|
-
return "";
|
|
63
|
-
}
|
|
64
|
-
let normalized = url.trim();
|
|
65
|
-
if (!normalized) {
|
|
66
|
-
return "";
|
|
67
|
-
}
|
|
68
|
-
const scheme = extractScheme(normalized);
|
|
69
|
-
if (scheme) {
|
|
70
|
-
return normalized;
|
|
71
|
-
}
|
|
72
|
-
if (normalized.startsWith("//")) {
|
|
73
|
-
return `https:${normalized}`;
|
|
74
|
-
}
|
|
75
|
-
return `https://${normalized}`;
|
|
76
|
-
}
|
|
77
|
-
function validateUrl(url, options) {
|
|
78
|
-
if (!url || !url.trim()) {
|
|
79
|
-
return {
|
|
80
|
-
isValid: false,
|
|
81
|
-
message: "URL\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694",
|
|
82
|
-
messageKey: "urlRequired"
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
const normalized = (options == null ? void 0 : options.skipNormalization) ? url.trim() : normalizeUrl(url);
|
|
86
|
-
try {
|
|
87
|
-
const urlObj = new URL(normalized);
|
|
88
|
-
const protocol = urlObj.protocol;
|
|
89
|
-
const isSupported = SUPPORTED_SCHEMES.includes(protocol);
|
|
90
|
-
const isCustom = CUSTOM_SCHEME_PATTERN.test(normalized);
|
|
91
|
-
if (!isSupported && !isCustom) {
|
|
92
|
-
return {
|
|
93
|
-
isValid: false,
|
|
94
|
-
message: `\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD504\uB85C\uD1A0\uCF5C\uC785\uB2C8\uB2E4: ${protocol}`,
|
|
95
|
-
messageKey: "unsupportedProtocol",
|
|
96
|
-
messageParams: { protocol }
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if (protocol === "http:" || protocol === "https:") {
|
|
100
|
-
if (!urlObj.hostname || urlObj.hostname.length < 1) {
|
|
101
|
-
return {
|
|
102
|
-
isValid: false,
|
|
103
|
-
message: "\uC720\uD6A8\uD55C \uB3C4\uBA54\uC778\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694",
|
|
104
|
-
messageKey: "invalidDomain"
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
if (!urlObj.hostname.includes(".") && urlObj.hostname !== "localhost") {
|
|
108
|
-
return {
|
|
109
|
-
isValid: false,
|
|
110
|
-
message: "\uC720\uD6A8\uD55C \uB3C4\uBA54\uC778 \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4",
|
|
111
|
-
messageKey: "invalidDomainFormat"
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (protocol === "mailto:") {
|
|
116
|
-
const email = urlObj.pathname;
|
|
117
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
118
|
-
if (!emailRegex.test(email)) {
|
|
119
|
-
return {
|
|
120
|
-
isValid: false,
|
|
121
|
-
message: "\uC720\uD6A8\uD55C \uC774\uBA54\uC77C \uC8FC\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4",
|
|
122
|
-
messageKey: "invalidEmail"
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (protocol === "tel:") {
|
|
127
|
-
const phone = urlObj.pathname;
|
|
128
|
-
if (!/\d/.test(phone)) {
|
|
129
|
-
return {
|
|
130
|
-
isValid: false,
|
|
131
|
-
message: "\uC720\uD6A8\uD55C \uC804\uD654\uBC88\uD638\uAC00 \uC544\uB2D9\uB2C8\uB2E4",
|
|
132
|
-
messageKey: "invalidPhone"
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (normalized.length > 2048) {
|
|
137
|
-
return {
|
|
138
|
-
isValid: false,
|
|
139
|
-
message: "URL\uC774 \uB108\uBB34 \uAE41\uB2C8\uB2E4 (\uCD5C\uB300 2048\uC790)",
|
|
140
|
-
messageKey: "urlTooLong"
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
isValid: true,
|
|
145
|
-
message: "\uC720\uD6A8\uD55C URL\uC785\uB2C8\uB2E4",
|
|
146
|
-
messageKey: "validUrl",
|
|
147
|
-
normalizedUrl: normalized
|
|
148
|
-
};
|
|
149
|
-
} catch (error) {
|
|
150
|
-
return {
|
|
151
|
-
isValid: false,
|
|
152
|
-
message: "\uC720\uD6A8\uD55C URL \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4",
|
|
153
|
-
messageKey: "invalidUrlFormat"
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function isWebUrl(url) {
|
|
158
|
-
try {
|
|
159
|
-
const urlObj = new URL(url);
|
|
160
|
-
return urlObj.protocol === "http:" || urlObj.protocol === "https:";
|
|
161
|
-
} catch (e) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
function isAppScheme(url) {
|
|
166
|
-
try {
|
|
167
|
-
const urlObj = new URL(url);
|
|
168
|
-
return !["http:", "https:", "ftp:", "ftps:", "file:"].includes(urlObj.protocol);
|
|
169
|
-
} catch (e) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
function getUrlType(url) {
|
|
174
|
-
try {
|
|
175
|
-
const urlObj = new URL(url);
|
|
176
|
-
const protocol = urlObj.protocol;
|
|
177
|
-
if (protocol === "http:" || protocol === "https:") {
|
|
178
|
-
return "web";
|
|
179
|
-
}
|
|
180
|
-
if (protocol === "mailto:") {
|
|
181
|
-
return "email";
|
|
182
|
-
}
|
|
183
|
-
if (protocol === "tel:" || protocol === "sms:") {
|
|
184
|
-
return "tel";
|
|
185
|
-
}
|
|
186
|
-
if (isAppScheme(url)) {
|
|
187
|
-
return "app";
|
|
188
|
-
}
|
|
189
|
-
return "other";
|
|
190
|
-
} catch (e) {
|
|
191
|
-
return "other";
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export {
|
|
196
|
-
SUPPORTED_SCHEMES,
|
|
197
|
-
hasValidScheme,
|
|
198
|
-
extractScheme,
|
|
199
|
-
normalizeUrl,
|
|
200
|
-
validateUrl,
|
|
201
|
-
isWebUrl,
|
|
202
|
-
isAppScheme,
|
|
203
|
-
getUrlType
|
|
204
|
-
};
|
package/dist/chunk-Y2TUZFCP.js
DELETED
|
File without changes
|