@simplysm/core-common 14.0.100 → 14.0.102
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/common.types.d.ts +0 -24
- package/dist/common.types.d.ts.map +1 -1
- package/dist/common.types.js.map +1 -1
- package/dist/errors/argument-error.d.ts +0 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +0 -10
- package/dist/errors/argument-error.js.map +1 -1
- package/dist/errors/not-implemented-error.d.ts +0 -15
- package/dist/errors/not-implemented-error.d.ts.map +1 -1
- package/dist/errors/not-implemented-error.js +0 -15
- package/dist/errors/not-implemented-error.js.map +1 -1
- package/dist/errors/sd-error.d.ts +0 -14
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/sd-error.js +0 -14
- package/dist/errors/sd-error.js.map +1 -1
- package/dist/errors/timeout-error.d.ts +0 -16
- package/dist/errors/timeout-error.d.ts.map +1 -1
- package/dist/errors/timeout-error.js +0 -16
- package/dist/errors/timeout-error.js.map +1 -1
- package/dist/extensions/arr-ext.types.d.ts +0 -24
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/arr-ext.types.js.map +1 -1
- package/dist/extensions/map-ext.d.ts +0 -27
- package/dist/extensions/map-ext.d.ts.map +1 -1
- package/dist/extensions/map-ext.js.map +1 -1
- package/dist/extensions/set-ext.d.ts +0 -12
- package/dist/extensions/set-ext.d.ts.map +1 -1
- package/dist/extensions/set-ext.js.map +1 -1
- package/dist/features/debounce-queue.d.ts +0 -10
- package/dist/features/debounce-queue.d.ts.map +1 -1
- package/dist/features/debounce-queue.js +0 -10
- package/dist/features/debounce-queue.js.map +1 -1
- package/dist/features/event-emitter.d.ts +0 -14
- package/dist/features/event-emitter.d.ts.map +1 -1
- package/dist/features/event-emitter.js +0 -14
- package/dist/features/event-emitter.js.map +1 -1
- package/dist/features/serial-queue.d.ts +0 -10
- package/dist/features/serial-queue.d.ts.map +1 -1
- package/dist/features/serial-queue.js +0 -10
- package/dist/features/serial-queue.js.map +1 -1
- package/dist/types/date-only.d.ts +0 -32
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +0 -32
- package/dist/types/date-only.js.map +1 -1
- package/dist/types/date-time.d.ts +0 -12
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +0 -12
- package/dist/types/date-time.js.map +1 -1
- package/dist/types/lazy-gc-map.d.ts +0 -8
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +0 -8
- package/dist/types/lazy-gc-map.js.map +1 -1
- package/dist/types/time.d.ts +0 -11
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +0 -11
- package/dist/types/time.js.map +1 -1
- package/dist/types/uuid.d.ts +0 -4
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +0 -4
- package/dist/types/uuid.js.map +1 -1
- package/dist/utils/bytes.d.ts +0 -17
- package/dist/utils/bytes.d.ts.map +1 -1
- package/dist/utils/bytes.js +0 -17
- package/dist/utils/bytes.js.map +1 -1
- package/dist/utils/date-format.d.ts +0 -16
- package/dist/utils/date-format.d.ts.map +1 -1
- package/dist/utils/date-format.js +0 -16
- package/dist/utils/date-format.js.map +1 -1
- package/dist/utils/num.d.ts +0 -12
- package/dist/utils/num.d.ts.map +1 -1
- package/dist/utils/num.js +0 -9
- package/dist/utils/num.js.map +1 -1
- package/dist/utils/obj.d.ts +0 -39
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +0 -35
- package/dist/utils/obj.js.map +1 -1
- package/dist/utils/primitive.d.ts +0 -6
- package/dist/utils/primitive.d.ts.map +1 -1
- package/dist/utils/primitive.js +0 -6
- package/dist/utils/primitive.js.map +1 -1
- package/dist/utils/str.d.ts +0 -43
- package/dist/utils/str.d.ts.map +1 -1
- package/dist/utils/str.js +0 -43
- package/dist/utils/str.js.map +1 -1
- package/dist/utils/template-strings.d.ts +0 -37
- package/dist/utils/template-strings.d.ts.map +1 -1
- package/dist/utils/template-strings.js +0 -37
- package/dist/utils/template-strings.js.map +1 -1
- package/dist/utils/transferable.d.ts +0 -8
- package/dist/utils/transferable.d.ts.map +1 -1
- package/dist/utils/transferable.js +0 -8
- package/dist/utils/transferable.js.map +1 -1
- package/dist/utils/wait.d.ts +0 -3
- package/dist/utils/wait.d.ts.map +1 -1
- package/dist/utils/wait.js +0 -3
- package/dist/utils/wait.js.map +1 -1
- package/dist/utils/xml.d.ts +0 -11
- package/dist/utils/xml.d.ts.map +1 -1
- package/dist/utils/xml.js +0 -11
- package/dist/utils/xml.js.map +1 -1
- package/dist/utils/zip.d.ts +0 -31
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js +0 -31
- package/dist/utils/zip.js.map +1 -1
- package/package.json +1 -1
- package/src/common.types.ts +0 -24
- package/src/errors/argument-error.ts +0 -10
- package/src/errors/not-implemented-error.ts +0 -15
- package/src/errors/sd-error.ts +0 -14
- package/src/errors/timeout-error.ts +0 -16
- package/src/extensions/arr-ext.types.ts +0 -24
- package/src/extensions/map-ext.ts +0 -27
- package/src/extensions/set-ext.ts +0 -12
- package/src/features/debounce-queue.ts +0 -10
- package/src/features/event-emitter.ts +0 -14
- package/src/features/serial-queue.ts +0 -10
- package/src/types/date-only.ts +0 -32
- package/src/types/date-time.ts +0 -12
- package/src/types/lazy-gc-map.ts +0 -8
- package/src/types/time.ts +0 -11
- package/src/types/uuid.ts +0 -4
- package/src/utils/bytes.ts +0 -17
- package/src/utils/date-format.ts +0 -16
- package/src/utils/num.ts +0 -12
- package/src/utils/obj.ts +0 -39
- package/src/utils/primitive.ts +0 -6
- package/src/utils/str.ts +0 -43
- package/src/utils/template-strings.ts +0 -37
- package/src/utils/transferable.ts +0 -8
- package/src/utils/wait.ts +0 -3
- package/src/utils/xml.ts +0 -11
- package/src/utils/zip.ts +0 -31
|
@@ -5,21 +5,6 @@ import { SdError } from "./sd-error";
|
|
|
5
5
|
*
|
|
6
6
|
* 아직 구현되지 않은 기능이 호출되었을 때 발생하는 에러.
|
|
7
7
|
* 추상 메서드 스텁, 향후 구현 예정인 분기 등에 사용된다.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* // 추상 메서드 구현 전
|
|
11
|
-
* class BaseService {
|
|
12
|
-
* process(): void {
|
|
13
|
-
* throw new NotImplementedError("서브클래스에서 구현 필요");
|
|
14
|
-
* }
|
|
15
|
-
* }
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* // 향후 구현 예정인 분기
|
|
19
|
-
* switch (type) {
|
|
20
|
-
* case "A": return handleA();
|
|
21
|
-
* case "B": throw new NotImplementedError(`타입 ${type} 처리`);
|
|
22
|
-
* }
|
|
23
8
|
*/
|
|
24
9
|
export class NotImplementedError extends SdError {
|
|
25
10
|
/**
|
package/src/errors/sd-error.ts
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 트리 구조 조합을 지원하는 에러 클래스
|
|
3
3
|
* ES2024 cause 속성을 활용
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* // 원인 에러를 감싸기
|
|
7
|
-
* try {
|
|
8
|
-
* await fetch(url);
|
|
9
|
-
* } catch (err) {
|
|
10
|
-
* throw new SdError(err, "API 호출 실패", "사용자 로드 실패");
|
|
11
|
-
* }
|
|
12
|
-
* // 결과 메시지: "사용자 로드 실패 => API 호출 실패 => 원본 에러 메시지"
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* // 메시지만으로 생성
|
|
16
|
-
* throw new SdError("잘못된 상태", "처리 불가");
|
|
17
|
-
* // 결과 메시지: "처리 불가 => 잘못된 상태"
|
|
18
4
|
*/
|
|
19
5
|
export class SdError extends Error {
|
|
20
6
|
override cause?: Error;
|
|
@@ -5,22 +5,6 @@ import { SdError } from "./sd-error";
|
|
|
5
5
|
*
|
|
6
6
|
* 대기 시간이 초과되었을 때 발생하는 에러.
|
|
7
7
|
* Wait.until() 같은 비동기 대기 함수에서 최대 시도 횟수를 초과하면 자동으로 발생한다.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* // Wait.until에서 자동 발생
|
|
11
|
-
* try {
|
|
12
|
-
* await Wait.until(() => isReady, 100, 50); // 100ms 간격, 최대 50회 시도
|
|
13
|
-
* } catch (err) {
|
|
14
|
-
* if (err instanceof TimeoutError) {
|
|
15
|
-
* console.log("타임아웃 초과");
|
|
16
|
-
* }
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // 직접 발생
|
|
21
|
-
* if (elapsed > maxTime) {
|
|
22
|
-
* throw new TimeoutError(undefined, "API 응답 대기 초과");
|
|
23
|
-
* }
|
|
24
8
|
*/
|
|
25
9
|
export class TimeoutError extends SdError {
|
|
26
10
|
/**
|
|
@@ -131,30 +131,6 @@ export interface ReadonlyArrayExt<TItem> {
|
|
|
131
131
|
* - parentKey 값이 null/undefined인 항목이 루트가 됨
|
|
132
132
|
* - 내부적으로 toArrayMap을 사용하여 O(n) 복잡도
|
|
133
133
|
* - 원본 항목은 복사되고 children 속성이 추가됨
|
|
134
|
-
*
|
|
135
|
-
* @example
|
|
136
|
-
* ```typescript
|
|
137
|
-
* interface Item {
|
|
138
|
-
* id: number;
|
|
139
|
-
* parentId?: number;
|
|
140
|
-
* name: string;
|
|
141
|
-
* }
|
|
142
|
-
*
|
|
143
|
-
* const items: Item[] = [
|
|
144
|
-
* { id: 1, name: "root" },
|
|
145
|
-
* { id: 2, parentId: 1, name: "child1" },
|
|
146
|
-
* { id: 3, parentId: 1, name: "child2" },
|
|
147
|
-
* { id: 4, parentId: 2, name: "grandchild" },
|
|
148
|
-
* ];
|
|
149
|
-
*
|
|
150
|
-
* const tree = items.toTree("id", "parentId");
|
|
151
|
-
* // [{ id: 1, name: "root", children: [
|
|
152
|
-
* // { id: 2, name: "child1", children: [
|
|
153
|
-
* // { id: 4, name: "grandchild", children: [] }
|
|
154
|
-
* // ]},
|
|
155
|
-
* // { id: 3, name: "child2", children: [] }
|
|
156
|
-
* // ]}]
|
|
157
|
-
* ```
|
|
158
134
|
*/
|
|
159
135
|
toTree<K extends keyof TItem, P extends keyof TItem>(
|
|
160
136
|
keyProp: K,
|
|
@@ -11,21 +11,6 @@ declare global {
|
|
|
11
11
|
* **주의**: V 타입이 함수인 경우 (예: `Map<string, () => void>`),
|
|
12
12
|
* 함수를 두 번째 인자로 직접 전달하면 팩토리로 인식되어 호출됨.
|
|
13
13
|
* 함수 자체를 값으로 저장하려면 팩토리로 감싸야 함.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* // 일반 값
|
|
18
|
-
* map.getOrCreate("key", 0);
|
|
19
|
-
* map.getOrCreate("key", []);
|
|
20
|
-
*
|
|
21
|
-
* // 팩토리 함수 (비용이 큰 연산에 사용)
|
|
22
|
-
* map.getOrCreate("key", () => expensiveComputation());
|
|
23
|
-
*
|
|
24
|
-
* // 함수를 값으로 저장
|
|
25
|
-
* const fnMap = new Map<string, () => void>();
|
|
26
|
-
* const myFn = () => console.log("hello");
|
|
27
|
-
* fnMap.getOrCreate("key", () => myFn); // 팩토리로 감싸기
|
|
28
|
-
* ```
|
|
29
14
|
*/
|
|
30
15
|
getOrCreate(key: K, newValue: V): V;
|
|
31
16
|
getOrCreate(key: K, newValueFn: () => V): V;
|
|
@@ -39,18 +24,6 @@ declare global {
|
|
|
39
24
|
* @remarks
|
|
40
25
|
* key가 존재하지 않아도 updateFn이 호출되어 새 값이 설정됨.
|
|
41
26
|
* 기존 값 기반 계산(카운터 증가, array에 추가 등)에 유용함.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```typescript
|
|
45
|
-
* const countMap = new Map<string, number>();
|
|
46
|
-
*
|
|
47
|
-
* // 카운터 증가
|
|
48
|
-
* countMap.update("key", (v) => (v ?? 0) + 1);
|
|
49
|
-
*
|
|
50
|
-
* // array에 항목 추가
|
|
51
|
-
* const arrayMap = new Map<string, string[]>();
|
|
52
|
-
* arrayMap.update("key", (v) => [...(v ?? []), "item"]);
|
|
53
|
-
* ```
|
|
54
27
|
*/
|
|
55
28
|
update(key: K, updateFn: (v: V | undefined) => V): void;
|
|
56
29
|
}
|
|
@@ -18,18 +18,6 @@ declare global {
|
|
|
18
18
|
*
|
|
19
19
|
* @remarks
|
|
20
20
|
* addOrDel 매개변수로 조건부 추가/제거를 간결하게 표현할 수 있음.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* const set = new Set<number>([1, 2, 3]);
|
|
25
|
-
*
|
|
26
|
-
* set.toggle(2); // 2가 있으므로 제거 → {1, 3}
|
|
27
|
-
* set.toggle(4); // 4가 없으므로 추가 → {1, 3, 4}
|
|
28
|
-
*
|
|
29
|
-
* // 조건부 토글
|
|
30
|
-
* const isAdmin = true;
|
|
31
|
-
* set.toggle(5, isAdmin ? "add" : "del"); // 강제 추가
|
|
32
|
-
* ```
|
|
33
21
|
*/
|
|
34
22
|
toggle(value: T, addOrDel?: "add" | "del"): this;
|
|
35
23
|
}
|
|
@@ -9,16 +9,6 @@
|
|
|
9
9
|
* 실행 중에 추가된 요청은 디바운스 지연 없이 현재 실행이
|
|
10
10
|
* 완료된 직후 즉시 처리됨. 이는 실행 완료 전에 도착한
|
|
11
11
|
* 요청을 놓치지 않기 위한 의도적인 설계임.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* const queue = new DebounceQueue(300); // 300ms 지연
|
|
15
|
-
* queue.run(() => console.log("1")); // 무시됨
|
|
16
|
-
* queue.run(() => console.log("2")); // 무시됨
|
|
17
|
-
* queue.run(() => console.log("3")); // 300ms 후 실행
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // 에러 처리
|
|
21
|
-
* queue.on("error", (err) => console.error(err));
|
|
22
12
|
*/
|
|
23
13
|
import { SdError } from "../errors/sd-error";
|
|
24
14
|
import { EventEmitter } from "./event-emitter";
|
|
@@ -5,20 +5,6 @@
|
|
|
5
5
|
* 내부적으로 EventTarget을 사용하여 구현됨.
|
|
6
6
|
*
|
|
7
7
|
* @typeParam TEvents 이벤트 타입 맵. key는 이벤트 이름, value는 이벤트 데이터 타입
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* interface MyEvents {
|
|
11
|
-
* data: string;
|
|
12
|
-
* error: Error;
|
|
13
|
-
* done: void;
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* class MyEmitter extends EventEmitter<MyEvents> {}
|
|
17
|
-
*
|
|
18
|
-
* const emitter = new MyEmitter();
|
|
19
|
-
* emitter.on("data", (data) => console.log(data)); // data: string
|
|
20
|
-
* emitter.emit("data", "hello");
|
|
21
|
-
* emitter.emit("done"); // void 타입은 인자 없이 호출
|
|
22
8
|
*/
|
|
23
9
|
export class EventEmitter<
|
|
24
10
|
TEvents extends { [K in keyof TEvents]: unknown } = Record<string, unknown>,
|
|
@@ -4,16 +4,6 @@
|
|
|
4
4
|
* 큐에 추가된 함수들은 순차적으로 실행됨.
|
|
5
5
|
* 하나의 작업이 완료된 후에야 다음 작업이 시작됨.
|
|
6
6
|
* 에러가 발생해도 후속 작업은 계속 실행됨.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* const queue = new SerialQueue();
|
|
10
|
-
* queue.run(async () => { await fetch("/api/1"); });
|
|
11
|
-
* queue.run(async () => { await fetch("/api/2"); }); // 1 완료 후 실행
|
|
12
|
-
* queue.run(async () => { await fetch("/api/3"); }); // 2 완료 후 실행
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* // 에러 처리
|
|
16
|
-
* queue.on("error", (err) => console.error(err));
|
|
17
7
|
*/
|
|
18
8
|
import { SdError } from "../errors/sd-error";
|
|
19
9
|
import { EventEmitter } from "./event-emitter";
|
package/src/types/date-only.ts
CHANGED
|
@@ -6,11 +6,6 @@ import { format, normalizeMonth } from "../utils/date-format";
|
|
|
6
6
|
*
|
|
7
7
|
* 시간 정보 없이 날짜만 저장하는 불변 클래스.
|
|
8
8
|
* 로컬 타임존 기준으로 동작함.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* const today = new DateOnly();
|
|
12
|
-
* const specific = new DateOnly(2025, 1, 15);
|
|
13
|
-
* const parsed = DateOnly.parse("2025-01-15");
|
|
14
9
|
*/
|
|
15
10
|
export class DateOnly {
|
|
16
11
|
private static readonly _MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
@@ -99,12 +94,6 @@ export class DateOnly {
|
|
|
99
94
|
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
100
95
|
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
101
96
|
* @returns 이 날짜가 포함된 주의 기준 연도와 월
|
|
102
|
-
*
|
|
103
|
-
* @example
|
|
104
|
-
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
105
|
-
* new DateOnly(2024, 1, 1).getBaseYearMonthSeqForWeekSeq(1, 4)
|
|
106
|
-
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
107
|
-
* new DateOnly(2024, 1, 1).getBaseYearMonthSeqForWeekSeq(0, 1)
|
|
108
97
|
*/
|
|
109
98
|
getBaseYearMonthSeqForWeekSeq(weekStartDay: number = 1, minDaysInFirstWeek: number = 4) {
|
|
110
99
|
// 주 시작 요일 기준 요일 인덱스 계산 (0 = 주 시작 요일)
|
|
@@ -155,13 +144,6 @@ export class DateOnly {
|
|
|
155
144
|
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
156
145
|
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
157
146
|
* @returns 해당 연도와 그 연도 내의 주차 번호
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
161
|
-
* new DateOnly(2025, 1, 6).getWeekSeqOfYear(); // { year: 2025, weekSeq: 2 }
|
|
162
|
-
*
|
|
163
|
-
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
164
|
-
* new DateOnly(2025, 1, 1).getWeekSeqOfYear(0, 1); // { year: 2025, weekSeq: 1 }
|
|
165
147
|
*/
|
|
166
148
|
getWeekSeqOfYear(
|
|
167
149
|
weekStartDay: number = 1,
|
|
@@ -186,13 +168,6 @@ export class DateOnly {
|
|
|
186
168
|
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
187
169
|
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
188
170
|
* @returns 연도, 월, 해당 월 내의 주차 번호
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
192
|
-
* new DateOnly(2025, 1, 15).getWeekSeqOfMonth(); // { year: 2025, monthSeq: 1, weekSeq: 3 }
|
|
193
|
-
*
|
|
194
|
-
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
195
|
-
* new DateOnly(2025, 1, 15).getWeekSeqOfMonth(0, 1); // { year: 2025, monthSeq: 1, weekSeq: 3 }
|
|
196
171
|
*/
|
|
197
172
|
getWeekSeqOfMonth(
|
|
198
173
|
weekStartDay: number = 1,
|
|
@@ -219,13 +194,6 @@ export class DateOnly {
|
|
|
219
194
|
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
220
195
|
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
221
196
|
* @returns 지정된 주의 시작 날짜
|
|
222
|
-
*
|
|
223
|
-
* @example
|
|
224
|
-
* // 2025년 2주차 시작 날짜 (ISO 8601 표준)
|
|
225
|
-
* DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 2 }); // 2025-01-06 (월요일)
|
|
226
|
-
*
|
|
227
|
-
* // 2025년 1월 3주차 시작 날짜
|
|
228
|
-
* DateOnly.getDateByYearWeekSeq({ year: 2025, month: 1, weekSeq: 3 }); // 2025-01-13 (월요일)
|
|
229
197
|
*/
|
|
230
198
|
static getDateByYearWeekSeq(
|
|
231
199
|
arg: { year: number; month?: number; weekSeq: number },
|
package/src/types/date-time.ts
CHANGED
|
@@ -6,11 +6,6 @@ import { convert12To24, format, normalizeMonth } from "../utils/date-format";
|
|
|
6
6
|
*
|
|
7
7
|
* JavaScript Date 객체를 래핑하여 불변성과 편리한 API를 제공.
|
|
8
8
|
* 밀리초 정밀도를 지원하고 로컬 타임존 기준으로 동작함.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* const now = new DateTime();
|
|
12
|
-
* const specific = new DateTime(2025, 1, 15, 10, 30, 0);
|
|
13
|
-
* const parsed = DateTime.parse("2025-01-15 10:30:00");
|
|
14
9
|
*/
|
|
15
10
|
export class DateTime {
|
|
16
11
|
readonly date: Date;
|
|
@@ -65,13 +60,6 @@ export class DateTime {
|
|
|
65
60
|
* @param str DateTime 문자열
|
|
66
61
|
* @returns 파싱된 DateTime 인스턴스
|
|
67
62
|
* @throws ArgumentError 지원하지 않는 형식인 경우
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* DateTime.parse("2025-01-15 10:30:00") // yyyy-MM-dd HH:mm:ss
|
|
71
|
-
* DateTime.parse("2025-01-15 10:30:00.123") // yyyy-MM-dd HH:mm:ss.fff
|
|
72
|
-
* DateTime.parse("20250115103000") // yyyyMMddHHmmss
|
|
73
|
-
* DateTime.parse("2025-01-15 AM 10:30:00") // yyyy-MM-dd AM/PM HH:mm:ss
|
|
74
|
-
* DateTime.parse("2025-01-15T10:30:00Z") // ISO 8601
|
|
75
63
|
*/
|
|
76
64
|
static parse(str: string): DateTime {
|
|
77
65
|
const parsedTick = Date.parse(str);
|
package/src/types/lazy-gc-map.ts
CHANGED
|
@@ -6,14 +6,6 @@ import { createLogger } from "../features/logger";
|
|
|
6
6
|
*
|
|
7
7
|
* @note 사용 후 반드시 dispose()를 호출해야 함.
|
|
8
8
|
* 그렇지 않으면 GC 타이머가 계속 실행되어 메모리 누수 발생.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* const map = new LazyGcMap({ gcInterval: 10000, expireTime: 60000 });
|
|
12
|
-
* try {
|
|
13
|
-
* // ... 사용
|
|
14
|
-
* } finally {
|
|
15
|
-
* map.dispose();
|
|
16
|
-
* }
|
|
17
9
|
*/
|
|
18
10
|
export class LazyGcMap<TKey, TValue> {
|
|
19
11
|
private static readonly _logger = createLogger("LazyGcMap");
|
package/src/types/time.ts
CHANGED
|
@@ -6,11 +6,6 @@ import { convert12To24, format } from "../utils/date-format";
|
|
|
6
6
|
*
|
|
7
7
|
* 날짜 정보 없이 시간만 저장하는 불변 클래스.
|
|
8
8
|
* 24시간을 초과하거나 음수인 값은 자동으로 정규화됨.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* const now = new Time();
|
|
12
|
-
* const specific = new Time(10, 30, 0);
|
|
13
|
-
* const parsed = Time.parse("10:30:00");
|
|
14
9
|
*/
|
|
15
10
|
export class Time {
|
|
16
11
|
private static readonly _MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
@@ -60,12 +55,6 @@ export class Time {
|
|
|
60
55
|
* @param str 시간 문자열
|
|
61
56
|
* @returns 파싱된 Time 인스턴스
|
|
62
57
|
* @throws ArgumentError 지원하지 않는 형식인 경우
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* Time.parse("10:30:00") // HH:mm:ss
|
|
66
|
-
* Time.parse("10:30:00.123") // HH:mm:ss.fff
|
|
67
|
-
* Time.parse("AM 10:30:00") // AM/PM HH:mm:ss
|
|
68
|
-
* Time.parse("2025-01-15T10:30:00") // ISO 8601 (extract time part only)
|
|
69
58
|
*/
|
|
70
59
|
static parse(str: string): Time {
|
|
71
60
|
const match1 = /(AM|PM) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})(\.([0-9]{1,3}))?$/i.exec(str);
|
package/src/types/uuid.ts
CHANGED
|
@@ -5,10 +5,6 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
5
5
|
* UUID v4 클래스
|
|
6
6
|
*
|
|
7
7
|
* crypto.getRandomValues 기반으로 암호학적으로 안전한 UUID를 생성. (Chrome 79+, Node.js 호환)
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* const id = Uuid.generate();
|
|
11
|
-
* const fromStr = new Uuid("550e8400-e29b-41d4-a716-446655440000");
|
|
12
8
|
*/
|
|
13
9
|
export class Uuid {
|
|
14
10
|
// 0x00 ~ 0xFF에 대한 hex 문자열 사전 계산 (256개 항목)
|
package/src/utils/bytes.ts
CHANGED
|
@@ -28,11 +28,6 @@ const BASE64_LOOKUP: number[] = Array.from({ length: 256 }, (_, i) => {
|
|
|
28
28
|
* 여러 Uint8Array 결합
|
|
29
29
|
* @param arrays 결합할 Uint8Array 배열
|
|
30
30
|
* @returns 결합된 새 Uint8Array
|
|
31
|
-
* @example
|
|
32
|
-
* const a = new Uint8Array([1, 2]);
|
|
33
|
-
* const b = new Uint8Array([3, 4]);
|
|
34
|
-
* concat([a, b]);
|
|
35
|
-
* // Uint8Array([1, 2, 3, 4])
|
|
36
31
|
*/
|
|
37
32
|
export function concat(arrays: Bytes[]): Bytes {
|
|
38
33
|
const total = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
@@ -49,9 +44,6 @@ export function concat(arrays: Bytes[]): Bytes {
|
|
|
49
44
|
* hex 문자열로 변환
|
|
50
45
|
* @param bytes 변환할 Uint8Array
|
|
51
46
|
* @returns 소문자 hex 문자열
|
|
52
|
-
* @example
|
|
53
|
-
* toHex(new Uint8Array([255, 0, 127]));
|
|
54
|
-
* // "ff007f"
|
|
55
47
|
*/
|
|
56
48
|
export function toHex(bytes: Bytes): string {
|
|
57
49
|
const h = hexTable;
|
|
@@ -67,9 +59,6 @@ export function toHex(bytes: Bytes): string {
|
|
|
67
59
|
* @param hex 변환할 hex 문자열 (대소문자 허용)
|
|
68
60
|
* @returns 변환된 Uint8Array
|
|
69
61
|
* @throws {ArgumentError} 홀수 길이이거나 유효하지 않은 hex 문자가 포함된 경우
|
|
70
|
-
* @example
|
|
71
|
-
* fromHex("ff007f");
|
|
72
|
-
* // Uint8Array([255, 0, 127])
|
|
73
62
|
*/
|
|
74
63
|
export function fromHex(hex: string): Bytes {
|
|
75
64
|
if (hex.length % 2 !== 0) {
|
|
@@ -89,9 +78,6 @@ export function fromHex(hex: string): Bytes {
|
|
|
89
78
|
* Bytes를 base64 문자열로 변환
|
|
90
79
|
* @param bytes 변환할 Uint8Array
|
|
91
80
|
* @returns Base64 인코딩된 문자열
|
|
92
|
-
* @example
|
|
93
|
-
* toBase64(new Uint8Array([72, 101, 108, 108, 111]));
|
|
94
|
-
* // "SGVsbG8="
|
|
95
81
|
*/
|
|
96
82
|
export function toBase64(bytes: Bytes): string {
|
|
97
83
|
if (bytes.length === 0) {
|
|
@@ -117,9 +103,6 @@ export function toBase64(bytes: Bytes): string {
|
|
|
117
103
|
* @param base64 변환할 base64 문자열
|
|
118
104
|
* @returns 디코딩된 Uint8Array
|
|
119
105
|
* @throws {ArgumentError} 유효하지 않은 base64 문자가 포함된 경우
|
|
120
|
-
* @example
|
|
121
|
-
* fromBase64("SGVsbG8=");
|
|
122
|
-
* // Uint8Array([72, 101, 108, 108, 111])
|
|
123
106
|
*/
|
|
124
107
|
export function fromBase64(base64: string): Bytes {
|
|
125
108
|
// 공백 제거 및 패딩 정규화
|
package/src/utils/date-format.ts
CHANGED
|
@@ -16,10 +16,6 @@ export interface DtNormalizedMonth {
|
|
|
16
16
|
* @param month 설정할 월 (1-12 범위 밖의 값 허용)
|
|
17
17
|
* @param day 기준 일
|
|
18
18
|
* @returns 정규화된 연도, 월, 일
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* normalizeMonth(2025, 13, 15) // { year: 2026, month: 1, day: 15 }
|
|
22
|
-
* normalizeMonth(2025, 2, 31) // { year: 2025, month: 2, day: 28 }
|
|
23
19
|
*/
|
|
24
20
|
export function normalizeMonth(year: number, month: number, day: number): DtNormalizedMonth {
|
|
25
21
|
// 월 오버플로우/언더플로우 정규화
|
|
@@ -123,18 +119,6 @@ const weekStrings = ["일", "월", "화", "수", "목", "금", "토"];
|
|
|
123
119
|
* | zzz | 타임존 오프셋 (±HH:mm) | +09:00 |
|
|
124
120
|
* | zz | 타임존 오프셋 (±HH) | +09 |
|
|
125
121
|
* | z | 타임존 오프셋 (±H) | +9 |
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```typescript
|
|
129
|
-
* formatDate("yyyy-MM-dd", { year: 2024, month: 3, day: 15 });
|
|
130
|
-
* // "2024-03-15"
|
|
131
|
-
*
|
|
132
|
-
* formatDate("yyyy-M-d (ddd)", { year: 2024, month: 3, day: 15 });
|
|
133
|
-
* // "2024-3-15 (Fri)"
|
|
134
|
-
*
|
|
135
|
-
* formatDate("tt h:mm:ss", { hour: 14, minute: 30, second: 45 });
|
|
136
|
-
* // "PM 2:30:45"
|
|
137
|
-
* ```
|
|
138
122
|
*/
|
|
139
123
|
export function format(
|
|
140
124
|
formatString: string,
|
package/src/utils/num.ts
CHANGED
|
@@ -59,15 +59,6 @@ export function parseFloat(text: unknown): number | undefined {
|
|
|
59
59
|
*
|
|
60
60
|
* @param val 검사할 값
|
|
61
61
|
* @returns undefined, null, 또는 0이면 true
|
|
62
|
-
* @example
|
|
63
|
-
* const count: number | undefined = getValue();
|
|
64
|
-
* if (isNullOrEmpty(count)) {
|
|
65
|
-
* // count: 0 | undefined
|
|
66
|
-
* console.log("Empty");
|
|
67
|
-
* } else {
|
|
68
|
-
* // count: number (non-zero value)
|
|
69
|
-
* console.log(`Count: ${count}`);
|
|
70
|
-
* }
|
|
71
62
|
*/
|
|
72
63
|
export function isNullOrEmpty(val: number | undefined): val is 0 | undefined {
|
|
73
64
|
return val == null || val === 0;
|
|
@@ -83,9 +74,6 @@ export function isNullOrEmpty(val: number | undefined): val is 0 | undefined {
|
|
|
83
74
|
* @param digit 소수점 옵션
|
|
84
75
|
* @param digit.max 최대 소수점 자릿수
|
|
85
76
|
* @param digit.min 최소 소수점 자릿수 (부족하면 0으로 채움)
|
|
86
|
-
* @example
|
|
87
|
-
* format(1234.567, { max: 2 }) // "1,234.57"
|
|
88
|
-
* format(1234, { min: 2 }) // "1,234.00"
|
|
89
77
|
*/
|
|
90
78
|
export function format(val: number, digit?: { max?: number; min?: number }): string;
|
|
91
79
|
export function format(
|
package/src/utils/obj.ts
CHANGED
|
@@ -153,9 +153,7 @@ export interface EqualOptions {
|
|
|
153
153
|
* @param target 비교 대상 2
|
|
154
154
|
* @param options 비교 옵션
|
|
155
155
|
* @param options.topLevelIncludes 비교할 key 목록. 지정 시 해당 key만 비교 (최상위 레벨에만 적용)
|
|
156
|
-
* @example `{ topLevelIncludes: ["id", "name"] }` - id와 name key만 비교
|
|
157
156
|
* @param options.topLevelExcludes 비교에서 제외할 key 목록 (최상위 레벨에만 적용)
|
|
158
|
-
* @example `{ topLevelExcludes: ["updatedAt"] }` - updatedAt key를 제외하고 비교
|
|
159
157
|
* @param options.ignoreArrayIndex array 순서를 무시할지 여부. true면 O(n²) 복잡도
|
|
160
158
|
* @param options.shallow 얕은 비교 여부. true면 1단계만 비교 (참조 비교)
|
|
161
159
|
*
|
|
@@ -549,14 +547,6 @@ export interface Merge3KeyOptions {
|
|
|
549
547
|
* - `excludes`: 비교에서 제외할 하위 key 목록
|
|
550
548
|
* - `ignoreArrayIndex`: array 순서를 무시할지 여부
|
|
551
549
|
* @returns conflict: 충돌 발생 여부, result: 병합 결과
|
|
552
|
-
*
|
|
553
|
-
* @example
|
|
554
|
-
* const { conflict, result } = merge3(
|
|
555
|
-
* { a: 1, b: 2 }, // source
|
|
556
|
-
* { a: 1, b: 1 }, // origin
|
|
557
|
-
* { a: 2, b: 1 }, // target
|
|
558
|
-
* );
|
|
559
|
-
* // conflict: false, result: { a: 2, b: 2 }
|
|
560
550
|
*/
|
|
561
551
|
export function merge3<
|
|
562
552
|
S extends Record<string, unknown>,
|
|
@@ -601,10 +591,6 @@ export function merge3<
|
|
|
601
591
|
* @param item 원본 객체
|
|
602
592
|
* @param omitKeys 제외할 key 배열
|
|
603
593
|
* @returns 지정된 key가 제외된 새 객체
|
|
604
|
-
* @example
|
|
605
|
-
* const user = { name: "Alice", age: 30, email: "alice@example.com" };
|
|
606
|
-
* omit(user, ["email"]);
|
|
607
|
-
* // { name: "Alice", age: 30 }
|
|
608
594
|
*/
|
|
609
595
|
export function omit<T extends Record<string, unknown>, K extends keyof T>(
|
|
610
596
|
item: T,
|
|
@@ -625,10 +611,6 @@ export function omit<T extends Record<string, unknown>, K extends keyof T>(
|
|
|
625
611
|
* @param item 원본 객체
|
|
626
612
|
* @param omitKeyFn key를 받아 제외 여부를 반환하는 함수 (true면 제외)
|
|
627
613
|
* @returns 조건에 맞는 key가 제외된 새 객체
|
|
628
|
-
* @example
|
|
629
|
-
* const data = { name: "Alice", _internal: "secret", age: 30 };
|
|
630
|
-
* omitByFilter(data, (key) => key.startsWith("_"));
|
|
631
|
-
* // { name: "Alice", age: 30 }
|
|
632
614
|
*/
|
|
633
615
|
export function omitByFilter<T extends Record<string, unknown>>(
|
|
634
616
|
item: T,
|
|
@@ -648,10 +630,6 @@ export function omitByFilter<T extends Record<string, unknown>>(
|
|
|
648
630
|
* @param item 원본 객체
|
|
649
631
|
* @param keys 선택할 key 배열
|
|
650
632
|
* @returns 지정된 key만 포함된 새 객체
|
|
651
|
-
* @example
|
|
652
|
-
* const user = { name: "Alice", age: 30, email: "alice@example.com" };
|
|
653
|
-
* pick(user, ["name", "age"]);
|
|
654
|
-
* // { name: "Alice", age: 30 }
|
|
655
633
|
*/
|
|
656
634
|
export function pick<T extends Record<string, unknown>, K extends keyof T>(
|
|
657
635
|
item: T,
|
|
@@ -692,7 +670,6 @@ function getChainSplits(chain: string): (string | number)[] {
|
|
|
692
670
|
|
|
693
671
|
/**
|
|
694
672
|
* 체인 경로로 값 조회
|
|
695
|
-
* @example getChainValue(obj, "a.b[0].c")
|
|
696
673
|
*/
|
|
697
674
|
export function getChainValue(obj: unknown, chain: string, optional: true): unknown | undefined;
|
|
698
675
|
export function getChainValue(obj: unknown, chain: string): unknown;
|
|
@@ -721,7 +698,6 @@ export function getChainValue(
|
|
|
721
698
|
* @param depth 하강 깊이 (1 이상)
|
|
722
699
|
* @param optional true이면 중간에 null/undefined를 만나도 에러 없이 undefined 반환
|
|
723
700
|
* @throws ArgumentError depth가 1 미만인 경우
|
|
724
|
-
* @example getChainValueByDepth({ parent: { parent: { name: 'a' } } }, 'parent', 2) => { name: 'a' }
|
|
725
701
|
*/
|
|
726
702
|
export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
|
|
727
703
|
obj: TObject,
|
|
@@ -756,7 +732,6 @@ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
|
|
|
756
732
|
|
|
757
733
|
/**
|
|
758
734
|
* 체인 경로로 값 설정
|
|
759
|
-
* @example setChainValue(obj, "a.b[0].c", value)
|
|
760
735
|
*/
|
|
761
736
|
export function setChainValue(obj: unknown, chain: string, value: unknown): void {
|
|
762
737
|
const splits = getChainSplits(chain);
|
|
@@ -776,7 +751,6 @@ export function setChainValue(obj: unknown, chain: string, value: unknown): void
|
|
|
776
751
|
|
|
777
752
|
/**
|
|
778
753
|
* 체인 경로로 값 삭제
|
|
779
|
-
* @example deleteChainValue(obj, "a.b[0].c")
|
|
780
754
|
*/
|
|
781
755
|
export function deleteChainValue(obj: unknown, chain: string): void {
|
|
782
756
|
const splits = getChainSplits(chain);
|
|
@@ -882,7 +856,6 @@ function nullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): TObj
|
|
|
882
856
|
/**
|
|
883
857
|
* 평탄화된 객체를 중첩 객체로 변환
|
|
884
858
|
* @internal
|
|
885
|
-
* @example unflatten({ "a.b.c": 1 }) => { a: { b: { c: 1 } } }
|
|
886
859
|
*/
|
|
887
860
|
export function unflatten(flatObj: Record<string, unknown>): Record<string, unknown> {
|
|
888
861
|
const result: Record<string, unknown> = {};
|
|
@@ -914,7 +887,6 @@ export function unflatten(flatObj: Record<string, unknown>): Record<string, unkn
|
|
|
914
887
|
|
|
915
888
|
/**
|
|
916
889
|
* undefined를 가진 속성을 optional로 변환
|
|
917
|
-
* @example { a: string; b: string | undefined } → { a: string; b?: string | undefined }
|
|
918
890
|
*/
|
|
919
891
|
export type UndefToOptional<TObject> = {
|
|
920
892
|
[K in keyof TObject as undefined extends TObject[K] ? K : never]?: TObject[K];
|
|
@@ -922,7 +894,6 @@ export type UndefToOptional<TObject> = {
|
|
|
922
894
|
|
|
923
895
|
/**
|
|
924
896
|
* optional 속성을 필수 + undefined 유니온으로 변환
|
|
925
|
-
* @example { a: string; b?: string } → { a: string; b: string | undefined }
|
|
926
897
|
*/
|
|
927
898
|
export type OptionalToUndef<TObject> = {
|
|
928
899
|
[K in keyof TObject]-?: {} extends Pick<TObject, K> ? TObject[K] | undefined : TObject[K];
|
|
@@ -964,16 +935,6 @@ type Entries<TObject> = { [K in keyof TObject]: [K, TObject[K]] }[keyof TObject]
|
|
|
964
935
|
* @param obj 변환할 객체
|
|
965
936
|
* @param fn 변환 함수 (key, value) => [newKey, newValue]
|
|
966
937
|
* @returns key와 value가 변환된 새 객체
|
|
967
|
-
* @example
|
|
968
|
-
* const colors = { primary: "255, 0, 0", secondary: "0, 255, 0" };
|
|
969
|
-
*
|
|
970
|
-
* // 값만 변환
|
|
971
|
-
* map(colors, (key, rgb) => [null, `rgb(${rgb})`]);
|
|
972
|
-
* // { primary: "rgb(255, 0, 0)", secondary: "rgb(0, 255, 0)" }
|
|
973
|
-
*
|
|
974
|
-
* // key와 값 모두 변환
|
|
975
|
-
* map(colors, (key, rgb) => [`${key}Light`, `rgb(${rgb})`]);
|
|
976
|
-
* // { primaryLight: "rgb(255, 0, 0)", secondaryLight: "rgb(0, 255, 0)" }
|
|
977
938
|
*/
|
|
978
939
|
export function map<TSource extends object, TNewKey extends string, TNewValue>(
|
|
979
940
|
obj: TSource,
|
package/src/utils/primitive.ts
CHANGED
|
@@ -13,12 +13,6 @@ import type { PrimitiveTypeMap, PrimitiveTypeStr } from "../common.types";
|
|
|
13
13
|
* @param value 타입을 추론할 값
|
|
14
14
|
* @returns 값에 해당하는 PrimitiveTypeStr
|
|
15
15
|
* @throws ArgumentError 지원하지 않는 타입인 경우
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* getPrimitiveTypeStr("hello") // "string"
|
|
19
|
-
* getPrimitiveTypeStr(123) // "number"
|
|
20
|
-
* getPrimitiveTypeStr(new DateTime()) // "DateTime"
|
|
21
|
-
* getPrimitiveTypeStr(new Uint8Array()) // "Bytes"
|
|
22
16
|
*/
|
|
23
17
|
export function typeStr(value: PrimitiveTypeMap[PrimitiveTypeStr]): PrimitiveTypeStr {
|
|
24
18
|
if (typeof value === "string") return "string";
|