@simplysm/core-common 14.0.51 → 14.0.53

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/docs/utils/num.md DELETED
@@ -1,56 +0,0 @@
1
- # num
2
-
3
- 숫자 유틸리티 네임스페이스.
4
-
5
- ```typescript
6
- import { num } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `parseInt` | `(text: unknown) => number \| undefined` | 문자열을 정수로 파싱. 비숫자 문자 제거 후 파싱. 소수점 이하 버림 |
14
- | `parseFloat` | `(text: unknown) => number \| undefined` | 문자열을 float로 파싱. 비숫자 문자 제거 후 파싱 |
15
- | `parseRoundedInt` | `(text: unknown) => number \| undefined` | 문자열을 float로 파싱한 후 반올림하여 정수 반환 |
16
- | `isNullOrEmpty` | `(val: number \| undefined) => val is 0 \| undefined` | 타입 가드: undefined, null, 0이면 true |
17
- | `format` | `(val: number, digit?) => string` | 천 단위 구분자 포함 문자열로 포맷 |
18
- | `format` | `(val: number \| undefined, digit?) => string \| undefined` | undefined이면 undefined 반환 |
19
-
20
- ## `parseInt` / `parseFloat` 동작
21
-
22
- - 숫자, `-`, `.` 이외의 문자 제거 후 파싱
23
- - 선행 `-`만 음수 부호로 유지 (중간 `-`는 제거)
24
- - 파싱 실패 시 `undefined` 반환
25
-
26
- ## `format` — `digit` 옵션
27
-
28
- | Field | Type | Description |
29
- |-------|------|-------------|
30
- | `max` | `number` | 최대 소수점 자릿수 |
31
- | `min` | `number` | 최소 소수점 자릿수 (부족하면 0으로 채움) |
32
-
33
- ## Usage
34
-
35
- ```typescript
36
- import { num } from "@simplysm/core-common";
37
-
38
- num.parseInt("1,234.56"); // 1234
39
- num.parseInt("-123"); // -123
40
- num.parseInt("010-1234-5678"); // 1012345678 (중간 - 제거)
41
- num.parseInt("abc"); // undefined
42
-
43
- num.parseFloat("1,234.56"); // 1234.56
44
- num.parseRoundedInt("1.7"); // 2
45
-
46
- // null/zero 검사 (타입 가드)
47
- const count: number | undefined = getValue();
48
- if (num.isNullOrEmpty(count)) {
49
- // count: 0 | undefined
50
- } else {
51
- // count: number (non-zero)
52
- }
53
-
54
- num.format(1234567.89, { max: 2 }); // "1,234,567.89"
55
- num.format(1234, { min: 2 }); // "1,234.00"
56
- ```
package/docs/utils/obj.md DELETED
@@ -1,107 +0,0 @@
1
- # obj
2
-
3
- 객체 유틸리티 네임스페이스. 깊은 복사, 비교, 병합, key 조작 등을 제공한다.
4
-
5
- ```typescript
6
- import { obj } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `clone` | `<T>(source: T) => T` | 깊은 복사. 순환 참조, 커스텀 타입(`DateTime`, `DateOnly`, `Time`, `Uuid`, `Uint8Array`) 지원 |
14
- | `equal` | `(source, target, options?) => boolean` | 깊은 동등성 비교 |
15
- | `merge` | `<S, T>(source: S, target: T, opt?) => S & T` | 깊은 병합. source를 기반으로 target을 병합하여 새 객체 반환 |
16
- | `merge3` | `(source, origin, target, optionsObj?) => { conflict, result }` | 3-way 병합 |
17
- | `omit` | `<T, K>(item: T, omitKeys: K[]) => Omit<T, K>` | 특정 key 제외 |
18
- | `omitByFilter` | `<T>(item: T, omitKeyFn) => T` | 조건에 맞는 key 제외 |
19
- | `pick` | `<T, K>(item: T, pickKeys: K[]) => Pick<T, K>` | 특정 key만 선택 |
20
- | `getChainValue` | `(obj, chain, optional?) => unknown` | 체인 경로로 값 조회 (예: `"a.b[0].c"`) |
21
- | `getChainValueByDepth` | `(obj, key, depth, optional?) => TObject[TKey]` | 같은 key로 지정된 깊이만큼 하강 |
22
- | `setChainValue` | `(obj, chain, value) => void` | 체인 경로로 값 설정 |
23
- | `deleteChainValue` | `(obj, chain) => void` | 체인 경로로 값 삭제 |
24
- | `clearUndefined` | `<T>(obj: T) => T` | 객체에서 undefined/null 값을 가진 key 삭제 (원본 수정) |
25
- | `clear` | `<T>(obj: T) => Record<string, never>` | 객체의 모든 key 삭제 (원본 수정) |
26
- | `nullToUndefined` | `<T>(obj: T) => T \| undefined` | null을 undefined로 변환 (재귀, 원본 수정) |
27
- | `unflatten` | `(flatObj) => Record<string, unknown>` | 평탄화된 객체를 중첩 객체로 변환 (`"a.b.c": 1` → `{ a: { b: { c: 1 } } }`) |
28
- | `keys` | `<T>(obj: T) => (keyof T)[]` | 타입 안전한 `Object.keys` |
29
- | `entries` | `<T>(obj: T) => Entries<T>` | 타입 안전한 `Object.entries` |
30
- | `fromEntries` | `<T>(entryPairs: T[]) => { [K in T[0]]: T[1] }` | 타입 안전한 `Object.fromEntries` |
31
- | `map` | `(obj, fn) => Record<string, TNewValue>` | 각 엔트리를 변환하여 새 객체 반환 |
32
-
33
- ## Related Types
34
-
35
- ### `EqualOptions`
36
-
37
- `equal()` 옵션:
38
-
39
- | Field | Type | Description |
40
- |-------|------|-------------|
41
- | `topLevelIncludes` | `string[]` | 비교할 key 목록 (최상위 레벨에만 적용) |
42
- | `topLevelExcludes` | `string[]` | 비교에서 제외할 key 목록 (최상위 레벨에만 적용) |
43
- | `ignoreArrayIndex` | `boolean` | 배열 순서를 무시할지 여부. `true`면 O(n²) 복잡도 |
44
- | `shallow` | `boolean` | 얕은 비교 여부. `true`면 1단계만 비교 (참조 비교) |
45
-
46
- ### `MergeOptions`
47
-
48
- `merge()` 옵션:
49
-
50
- | Field | Type | Description |
51
- |-------|------|-------------|
52
- | `arrayProcess` | `"replace" \| "concat"` | 배열 처리 방식. `"replace"`: target으로 교체 (기본값), `"concat"`: 병합 (중복 제거) |
53
- | `useDelTargetNull` | `boolean` | target이 null일 때 해당 key를 삭제할지 여부 |
54
-
55
- ### `Merge3KeyOptions`
56
-
57
- `merge3()` key별 옵션:
58
-
59
- | Field | Type | Description |
60
- |-------|------|-------------|
61
- | `keys` | `string[]` | 비교할 하위 key 목록 |
62
- | `excludes` | `string[]` | 비교에서 제외할 하위 key 목록 |
63
- | `ignoreArrayIndex` | `boolean` | 배열 순서를 무시할지 여부 |
64
-
65
- ### `UndefToOptional<T>`
66
-
67
- `undefined` 타입을 가진 속성을 optional로 변환:
68
-
69
- ```typescript
70
- // { a: string; b: string | undefined } → { a: string; b?: string | undefined }
71
- export type UndefToOptional<TObject> = ...
72
- ```
73
-
74
- ### `OptionalToUndef<T>`
75
-
76
- optional 속성을 필수 + `undefined` 유니온으로 변환:
77
-
78
- ```typescript
79
- // { a: string; b?: string } → { a: string; b: string | undefined }
80
- export type OptionalToUndef<TObject> = ...
81
- ```
82
-
83
- ## Usage
84
-
85
- ```typescript
86
- import { obj } from "@simplysm/core-common";
87
-
88
- // 깊은 복사
89
- const copied = obj.clone({ nested: { data: [1, 2, 3] } });
90
-
91
- // 깊은 비교
92
- const isEqual = obj.equal(a, b, { topLevelExcludes: ["updatedAt"] });
93
-
94
- // 깊은 병합
95
- const merged = obj.merge(defaults, overrides);
96
-
97
- // omit / pick
98
- const noId = obj.omit(user, ["id"]);
99
- const onlyName = obj.pick(user, ["name", "email"]);
100
-
101
- // 체인 경로
102
- const val = obj.getChainValue(data, "user.address[0].city");
103
- obj.setChainValue(data, "user.name", "Alice");
104
-
105
- // 객체 변환
106
- const mapped = obj.map(colors, (key, rgb) => [null, `rgb(${rgb})`]);
107
- ```
@@ -1,30 +0,0 @@
1
- # path
2
-
3
- 경로 유틸리티 네임스페이스. Node.js `path` 모듈 대체 (브라우저 환경 지원). POSIX 스타일 경로(슬래시 `/`)만 지원한다. Windows 백슬래시(`\`)는 지원하지 않는다.
4
-
5
- ```typescript
6
- import { path } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `join` | `(...segments: string[]) => string` | 경로 결합 (`path.join` 대체) |
14
- | `basename` | `(filePath: string, ext?: string) => string` | 파일명 추출 (`path.basename` 대체). ext 지정 시 해당 확장자 제거 |
15
- | `extname` | `(filePath: string) => string` | 파일 확장자 추출 (`path.extname` 대체). 숨김 파일(`.gitignore`)은 빈 문자열 반환 |
16
-
17
- ## Usage
18
-
19
- ```typescript
20
- import { path } from "@simplysm/core-common";
21
-
22
- path.join("/foo", "bar", "baz"); // "/foo/bar/baz"
23
- path.join("/foo/", "/bar/"); // "/foo/bar"
24
-
25
- path.basename("/foo/bar/file.txt"); // "file.txt"
26
- path.basename("/foo/bar/file.txt", ".txt"); // "file"
27
-
28
- path.extname("/foo/bar/file.txt"); // ".txt"
29
- path.extname("/foo/.gitignore"); // ""
30
- ```
@@ -1,28 +0,0 @@
1
- # primitive
2
-
3
- 원시 타입 변환 유틸리티 네임스페이스.
4
-
5
- ```typescript
6
- import { primitive } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `typeStr` | `(value: PrimitiveTypeMap[PrimitiveTypeStr]) => PrimitiveTypeStr` | 값으로부터 `PrimitiveTypeStr` 추론. 지원하지 않는 타입이면 `ArgumentError` 발생 |
14
-
15
- ## Usage
16
-
17
- ```typescript
18
- import { primitive } from "@simplysm/core-common";
19
-
20
- primitive.typeStr("hello"); // "string"
21
- primitive.typeStr(123); // "number"
22
- primitive.typeStr(true); // "boolean"
23
- primitive.typeStr(new DateTime()); // "DateTime"
24
- primitive.typeStr(new DateOnly()); // "DateOnly"
25
- primitive.typeStr(new Time()); // "Time"
26
- primitive.typeStr(Uuid.generate()); // "Uuid"
27
- primitive.typeStr(new Uint8Array()); // "Bytes"
28
- ```
package/docs/utils/str.md DELETED
@@ -1,63 +0,0 @@
1
- # str
2
-
3
- 문자열 유틸리티 네임스페이스.
4
-
5
- ```typescript
6
- import { str } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `getKoreanSuffix` | `(text, type) => string` | 받침 유무에 따라 적절한 한국어 조사 반환 |
14
- | `replaceFullWidth` | `(str) => string` | 전각 문자(A-Z, a-z, 0-9, 전각 공백, 전각 괄호)를 반각 문자로 변환 |
15
- | `toPascalCase` | `(str) => string` | PascalCase로 변환 (`-`, `_`, `.` 구분자 지원) |
16
- | `toCamelCase` | `(str) => string` | camelCase로 변환 |
17
- | `toKebabCase` | `(str) => string` | kebab-case로 변환 |
18
- | `toSnakeCase` | `(str) => string` | snake_case로 변환 |
19
- | `isNullOrEmpty` | `(str: string \| undefined) => str is "" \| undefined` | 타입 가드: undefined, null, 빈 문자열이면 true |
20
- | `insert` | `(str, index, insertString) => string` | 특정 위치에 문자열 삽입 |
21
-
22
- ## `getKoreanSuffix` — 조사 타입
23
-
24
- | `type` | 받침 있음 | 받침 없음 | 설명 |
25
- |--------|----------|----------|------|
26
- | `"을"` | 을 | 를 | 목적격 조사 |
27
- | `"은"` | 은 | 는 | 주격 보조사 |
28
- | `"이"` | 이 | 가 | 주격 조사 |
29
- | `"와"` | 과 | 와 | 접속 조사 |
30
- | `"랑"` | 이랑 | 랑 | 접속 조사 |
31
- | `"로"` | 으로 (ㄹ 받침은 "로") | 로 | 도구격 조사 |
32
- | `"라"` | 이라 | 라 | 서술격 조사 |
33
-
34
- ## Usage
35
-
36
- ```typescript
37
- import { str } from "@simplysm/core-common";
38
-
39
- // 한국어 조사
40
- str.getKoreanSuffix("Apple", "을"); // "를"
41
- str.getKoreanSuffix("책", "이"); // "이"
42
- str.getKoreanSuffix("파일", "을"); // "을"
43
-
44
- // 전각 → 반각
45
- str.replaceFullWidth("A123"); // "A123"
46
-
47
- // 케이스 변환
48
- str.toPascalCase("hello-world"); // "HelloWorld"
49
- str.toCamelCase("HelloWorld"); // "helloWorld"
50
- str.toKebabCase("HelloWorld"); // "hello-world"
51
- str.toSnakeCase("HelloWorld"); // "hello_world"
52
-
53
- // null/empty 검사 (타입 가드)
54
- const name: string | undefined = getValue();
55
- if (str.isNullOrEmpty(name)) {
56
- // name: "" | undefined
57
- } else {
58
- // name: string (non-empty)
59
- }
60
-
61
- // 문자열 삽입
62
- str.insert("Hello World", 5, ","); // "Hello, World"
63
- ```
@@ -1,49 +0,0 @@
1
- # Template Strings
2
-
3
- IDE 코드 하이라이팅 지원용 태그드 템플릿 리터럴 함수. 실제 동작은 문자열 결합 + 들여쓰기 정규화(앞뒤 빈 줄 제거, 공통 들여쓰기 제거)이다.
4
-
5
- ```typescript
6
- export function js(strings: TemplateStringsArray, ...values: unknown[]): string;
7
- export function ts(strings: TemplateStringsArray, ...values: unknown[]): string;
8
- export function html(strings: TemplateStringsArray, ...values: unknown[]): string;
9
- export function tsql(strings: TemplateStringsArray, ...values: unknown[]): string;
10
- export function mysql(strings: TemplateStringsArray, ...values: unknown[]): string;
11
- export function pgsql(strings: TemplateStringsArray, ...values: unknown[]): string;
12
- ```
13
-
14
- 직접 named import로 사용한다 (네임스페이스 아님):
15
-
16
- ```typescript
17
- import { js, ts, html, tsql, mysql, pgsql } from "@simplysm/core-common";
18
- ```
19
-
20
- ## Functions
21
-
22
- | Function | Description |
23
- |----------|-------------|
24
- | `js` | JavaScript 코드 하이라이팅용 |
25
- | `ts` | TypeScript 코드 하이라이팅용 |
26
- | `html` | HTML 마크업 하이라이팅용 |
27
- | `tsql` | MSSQL T-SQL 하이라이팅용 |
28
- | `mysql` | MySQL SQL 하이라이팅용 |
29
- | `pgsql` | PostgreSQL SQL 하이라이팅용 |
30
-
31
- ## Usage
32
-
33
- ```typescript
34
- import { ts, tsql } from "@simplysm/core-common";
35
-
36
- const code = ts`
37
- interface User {
38
- name: string;
39
- age: number;
40
- }
41
- `;
42
- // "interface User {\n name: string;\n age: number;\n}"
43
-
44
- const query = tsql`
45
- SELECT TOP 10 *
46
- FROM Users
47
- WHERE Name = ${keyword}
48
- `;
49
- ```
@@ -1,35 +0,0 @@
1
- # transfer
2
-
3
- Worker 간 전송 가능한 객체 변환 유틸리티 네임스페이스. `structuredClone`이 지원하지 않는 커스텀 타입을 처리한다.
4
-
5
- ```typescript
6
- import { transfer } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `encode` | `(obj) => { result: unknown; transferList: ArrayBuffer[] }` | Simplysm 타입을 포함한 객체를 Worker 전송 가능한 형태로 변환. 순환 참조 시 `TypeError` 발생 |
14
- | `decode` | `(obj) => unknown` | `encode()`로 변환된 객체를 원래 Simplysm 타입으로 복원 |
15
-
16
- ## 지원 타입
17
-
18
- `Date`, `DateTime`, `DateOnly`, `Time`, `Uuid`, `RegExp`, `Error` (cause, code, detail 포함), `Uint8Array`, `Array`, `Map`, `Set`, 일반 객체
19
-
20
- `Uint8Array`는 zero-copy 전송을 위해 `ArrayBuffer`를 `transferList`에 추가한다. `SharedArrayBuffer`는 이미 공유 메모리이므로 `transferList`에 추가하지 않는다.
21
-
22
- ## Usage
23
-
24
- ```typescript
25
- import { transfer } from "@simplysm/core-common";
26
-
27
- // Worker로 데이터 전송
28
- const { result, transferList } = transfer.encode(data);
29
- worker.postMessage(result, transferList);
30
-
31
- // Worker에서 데이터 수신
32
- self.onmessage = (event) => {
33
- const decoded = transfer.decode(event.data);
34
- };
35
- ```
@@ -1,35 +0,0 @@
1
- # wait
2
-
3
- 비동기 대기 유틸리티 네임스페이스.
4
-
5
- ```typescript
6
- import { wait } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `until` | `(forwarder, milliseconds?, maxCount?) => Promise<void>` | 조건이 true가 될 때까지 대기 |
14
- | `time` | `(millisecond: number) => Promise<void>` | 지정된 시간만큼 대기 |
15
-
16
- ## `until` — Parameters
17
-
18
- | Param | Type | Default | Description |
19
- |-------|------|---------|-------------|
20
- | `forwarder` | `() => boolean \| Promise<boolean>` | - | 조건 함수. 첫 번째 호출에서 true이면 즉시 반환 |
21
- | `milliseconds` | `number` | `100` | 확인 간격 (ms) |
22
- | `maxCount` | `number` | `undefined` | 최대 시도 횟수. 초과 시 `TimeoutError` 발생. 미지정 시 무제한 |
23
-
24
- ## Usage
25
-
26
- ```typescript
27
- import { wait } from "@simplysm/core-common";
28
-
29
- // 조건 대기
30
- await wait.until(() => isReady);
31
- await wait.until(() => isReady, 100, 50); // 100ms 간격, 최대 50회
32
-
33
- // 시간 대기
34
- await wait.time(1000); // 1초 대기
35
- ```
package/docs/utils/xml.md DELETED
@@ -1,49 +0,0 @@
1
- # xml
2
-
3
- XML 변환 유틸리티 네임스페이스. `fast-xml-parser` 기반.
4
-
5
- ```typescript
6
- import { xml } from "@simplysm/core-common";
7
- ```
8
-
9
- ## Functions
10
-
11
- | Function | Signature | Description |
12
- |----------|-----------|-------------|
13
- | `parse` | `(str, options?) => unknown` | XML 문자열을 객체로 파싱 |
14
- | `stringify` | `(obj, options?) => string` | 객체를 XML 문자열로 직렬화 |
15
-
16
- ## `parse` — 파싱 규칙
17
-
18
- - 속성: `$` 객체에 그룹화
19
- - 텍스트 노드: `_` key에 저장
20
- - 자식 요소: 배열로 변환 (루트 요소 제외)
21
-
22
- ## `parse` — options
23
-
24
- | Field | Type | Description |
25
- |-------|------|-------------|
26
- | `stripTagPrefix` | `boolean` | 태그 접두사(네임스페이스) 제거 여부. 속성은 접두사 유지 |
27
-
28
- ## Usage
29
-
30
- ```typescript
31
- import { xml } from "@simplysm/core-common";
32
-
33
- // 파싱
34
- const result = xml.parse('<root id="1"><item>hello</item></root>');
35
- // { root: { $: { id: "1" }, item: [{ _: "hello" }] } }
36
-
37
- // 네임스페이스 제거
38
- const clean = xml.parse('<ns:root><ns:item>hello</ns:item></ns:root>', { stripTagPrefix: true });
39
- // { root: { item: [{ _: "hello" }] } }
40
-
41
- // 직렬화
42
- const str = xml.stringify({
43
- root: {
44
- $: { id: "1" },
45
- item: [{ _: "hello" }, { _: "world" }],
46
- },
47
- });
48
- // '<root id="1"><item>hello</item><item>world</item></root>'
49
- ```
@@ -1,77 +0,0 @@
1
- # ZipArchive
2
-
3
- ZIP 파일 처리 클래스. ZIP 파일의 읽기, 쓰기, 압축, 해제를 처리한다. 동일 파일의 중복 해제를 방지하기 위해 내부 캐싱을 사용한다. `@zip.js/zip.js` 기반.
4
-
5
- ```typescript
6
- import { ZipArchive } from "@simplysm/core-common";
7
-
8
- export class ZipArchive {
9
- constructor(data?: Blob | Bytes);
10
- }
11
- ```
12
-
13
- ## Members
14
-
15
- | Member | Kind | Type | Description |
16
- |--------|------|------|-------------|
17
- | `extractAll` | method | `(progressCallback?) => Promise<Map<string, Bytes \| undefined>>` | 모든 파일 추출 |
18
- | `get` | method | `(fileName: string) => Promise<Bytes \| undefined>` | 특정 파일 추출. 내부 캐시 활용 |
19
- | `exists` | method | `(fileName: string) => Promise<boolean>` | 파일 존재 여부 확인 |
20
- | `write` | method | `(fileName: string, bytes: Bytes) => void` | 파일 쓰기 (캐시에 저장) |
21
- | `compress` | method | `() => Promise<Bytes>` | 캐시된 파일을 ZIP으로 압축 |
22
- | `close` | method | `() => Promise<void>` | 리더 닫기 및 캐시 비우기 |
23
-
24
- ## Related Types
25
-
26
- ### `ZipArchiveProgress`
27
-
28
- `extractAll()` 진행률 콜백의 파라미터 타입:
29
-
30
- ```typescript
31
- export interface ZipArchiveProgress {
32
- fileName: string;
33
- totalSize: number;
34
- extractedSize: number;
35
- }
36
- ```
37
-
38
- | Field | Type | Description |
39
- |-------|------|-------------|
40
- | `fileName` | `string` | 현재 처리 중인 파일명 |
41
- | `totalSize` | `number` | 전체 파일 크기 (바이트) |
42
- | `extractedSize` | `number` | 현재까지 추출된 크기 (바이트) |
43
-
44
- ## Usage
45
-
46
- ```typescript
47
- import { ZipArchive } from "@simplysm/core-common";
48
-
49
- // ZIP 파일 읽기
50
- const archive = new ZipArchive(zipBytes);
51
- try {
52
- const content = await archive.get("file.txt");
53
- } finally {
54
- await archive.close();
55
- }
56
-
57
- // ZIP 파일 생성
58
- const newArchive = new ZipArchive();
59
- try {
60
- newArchive.write("file.txt", textBytes);
61
- newArchive.write("data.json", jsonBytes);
62
- const zipBytes = await newArchive.compress();
63
- } finally {
64
- await newArchive.close();
65
- }
66
-
67
- // 모든 파일 추출 (진행률 보고 포함)
68
- const archive2 = new ZipArchive(zipBytes);
69
- try {
70
- const files = await archive2.extractAll((progress) => {
71
- const pct = (progress.extractedSize / progress.totalSize * 100).toFixed(1);
72
- console.log(`${progress.fileName}: ${pct}%`);
73
- });
74
- } finally {
75
- await archive2.close();
76
- }
77
- ```