@simplysm/core-common 13.0.99 → 14.0.1
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 +14 -14
- package/dist/common.types.js +2 -1
- package/dist/common.types.js.map +1 -6
- package/dist/env.d.ts +5 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +12 -8
- package/dist/env.js.map +1 -6
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +31 -14
- package/dist/errors/argument-error.js.map +1 -6
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +30 -12
- package/dist/errors/not-implemented-error.js.map +1 -6
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/sd-error.js +45 -24
- package/dist/errors/sd-error.js.map +1 -6
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +34 -15
- package/dist/errors/timeout-error.js.map +1 -6
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +10 -10
- package/dist/extensions/arr-ext.helpers.js +112 -89
- package/dist/extensions/arr-ext.helpers.js.map +1 -6
- package/dist/extensions/arr-ext.js +458 -422
- package/dist/extensions/arr-ext.js.map +1 -6
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/arr-ext.types.js +6 -1
- package/dist/extensions/arr-ext.types.js.map +1 -6
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/map-ext.js +27 -22
- package/dist/extensions/map-ext.js.map +1 -6
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/extensions/set-ext.js +32 -25
- package/dist/extensions/set-ext.js.map +1 -6
- package/dist/features/debounce-queue.d.ts +17 -17
- package/dist/features/debounce-queue.js +98 -70
- package/dist/features/debounce-queue.js.map +1 -6
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +101 -78
- package/dist/features/event-emitter.js.map +1 -6
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +78 -57
- package/dist/features/serial-queue.js.map +1 -6
- package/dist/globals.d.ts +4 -4
- package/dist/globals.js +9 -1
- package/dist/globals.js.map +1 -6
- package/dist/index.js +28 -27
- package/dist/index.js.map +1 -6
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +263 -252
- package/dist/types/date-only.js.map +1 -6
- package/dist/types/date-time.d.ts +36 -36
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +196 -288
- package/dist/types/date-time.js.map +1 -6
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +202 -159
- package/dist/types/lazy-gc-map.js.map +1 -6
- package/dist/types/time.d.ts +23 -23
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +169 -158
- package/dist/types/time.js.map +1 -6
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +95 -70
- package/dist/types/uuid.js.map +1 -6
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +137 -81
- package/dist/utils/bytes.js.map +1 -6
- package/dist/utils/date-format.d.ts +40 -40
- package/dist/utils/date-format.js +187 -101
- package/dist/utils/date-format.js.map +1 -6
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/error.js +11 -6
- package/dist/utils/error.js.map +1 -6
- package/dist/utils/json.d.ts +19 -19
- package/dist/utils/json.js +187 -135
- package/dist/utils/json.js.map +1 -6
- package/dist/utils/num.d.ts +20 -20
- package/dist/utils/num.js +76 -34
- package/dist/utils/num.js.map +1 -6
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +706 -496
- package/dist/utils/obj.js.map +1 -6
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/path.js +35 -18
- package/dist/utils/path.js.map +1 -6
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +34 -14
- package/dist/utils/primitive.js.map +1 -6
- package/dist/utils/str.d.ts +38 -38
- package/dist/utils/str.js +217 -113
- package/dist/utils/str.js.map +1 -6
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/template-strings.js +113 -40
- package/dist/utils/template-strings.js.map +1 -6
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +218 -151
- package/dist/utils/transferable.js.map +1 -6
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/wait.js +30 -15
- package/dist/utils/wait.js.map +1 -6
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.js +84 -46
- package/dist/utils/xml.js.map +1 -6
- package/dist/utils/zip.d.ts +22 -22
- package/dist/utils/zip.js +172 -148
- package/dist/utils/zip.js.map +1 -6
- package/package.json +5 -7
- package/src/common.types.ts +14 -14
- package/src/env.ts +9 -1
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +16 -16
- package/src/extensions/arr-ext.ts +35 -35
- package/src/extensions/arr-ext.types.ts +57 -57
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +23 -23
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +5 -5
- package/src/types/date-only.ts +84 -83
- package/src/types/date-time.ts +43 -42
- package/src/types/lazy-gc-map.ts +44 -44
- package/src/types/time.ts +29 -29
- package/src/types/uuid.ts +15 -15
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +59 -59
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +41 -41
- package/src/utils/num.ts +20 -20
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +48 -48
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +38 -38
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +19 -19
- package/src/utils/zip.ts +25 -25
- package/README.md +0 -160
- package/docs/errors.md +0 -119
- package/docs/extensions.md +0 -387
- package/docs/features.md +0 -143
- package/docs/types.md +0 -287
- package/docs/utils.md +0 -757
- package/tests/errors/errors.spec.ts +0 -80
- package/tests/extensions/array-extension.spec.ts +0 -654
- package/tests/extensions/map-extension.spec.ts +0 -117
- package/tests/extensions/set-extension.spec.ts +0 -67
- package/tests/types/date-only.spec.ts +0 -533
- package/tests/types/date-time.spec.ts +0 -246
- package/tests/types/lazy-gc-map.spec.ts +0 -606
- package/tests/types/time.spec.ts +0 -428
- package/tests/types/uuid.spec.ts +0 -74
- package/tests/utils/bytes-utils.spec.ts +0 -197
- package/tests/utils/date-format.spec.ts +0 -350
- package/tests/utils/debounce-queue.spec.ts +0 -226
- package/tests/utils/json.spec.ts +0 -400
- package/tests/utils/number.spec.ts +0 -136
- package/tests/utils/object.spec.ts +0 -810
- package/tests/utils/path.spec.ts +0 -70
- package/tests/utils/primitive.spec.ts +0 -43
- package/tests/utils/sd-event-emitter.spec.ts +0 -189
- package/tests/utils/serial-queue.spec.ts +0 -305
- package/tests/utils/string.spec.ts +0 -265
- package/tests/utils/template-strings.spec.ts +0 -48
- package/tests/utils/transferable.spec.ts +0 -639
- package/tests/utils/wait.spec.ts +0 -123
- package/tests/utils/xml.spec.ts +0 -146
- package/tests/utils/zip.spec.ts +0 -221
package/tests/utils/wait.spec.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { wait, TimeoutError } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
describe("Wait", () => {
|
|
5
|
-
//#region time
|
|
6
|
-
|
|
7
|
-
describe("time()", () => {
|
|
8
|
-
it("Waits for specified time", async () => {
|
|
9
|
-
const start = Date.now();
|
|
10
|
-
await wait.time(100);
|
|
11
|
-
const elapsed = Date.now() - start;
|
|
12
|
-
|
|
13
|
-
// 100ms ± tolerance - CI environment load and timer precision considered
|
|
14
|
-
expect(elapsed).toBeGreaterThanOrEqual(95);
|
|
15
|
-
expect(elapsed).toBeLessThan(250);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
|
|
21
|
-
//#region until
|
|
22
|
-
|
|
23
|
-
describe("until()", () => {
|
|
24
|
-
it("Waits until condition becomes true", async () => {
|
|
25
|
-
let count = 0;
|
|
26
|
-
|
|
27
|
-
await wait.until(() => {
|
|
28
|
-
count++;
|
|
29
|
-
return count >= 3;
|
|
30
|
-
}, 10);
|
|
31
|
-
|
|
32
|
-
expect(count).toBe(3);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("Supports async condition function", async () => {
|
|
36
|
-
let count = 0;
|
|
37
|
-
|
|
38
|
-
await wait.until(async () => {
|
|
39
|
-
await wait.time(10);
|
|
40
|
-
count++;
|
|
41
|
-
return count >= 3;
|
|
42
|
-
}, 10);
|
|
43
|
-
|
|
44
|
-
expect(count).toBe(3);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("Returns immediately if condition already true", async () => {
|
|
48
|
-
const start = Date.now();
|
|
49
|
-
await wait.until(() => true, 100);
|
|
50
|
-
const elapsed = Date.now() - start;
|
|
51
|
-
|
|
52
|
-
expect(elapsed).toBeLessThan(50);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("Throws TimeoutError on max attempts exceeded", async () => {
|
|
56
|
-
let count = 0;
|
|
57
|
-
|
|
58
|
-
await expect(async () => {
|
|
59
|
-
await wait.until(
|
|
60
|
-
() => {
|
|
61
|
-
count++;
|
|
62
|
-
return false;
|
|
63
|
-
},
|
|
64
|
-
10,
|
|
65
|
-
5,
|
|
66
|
-
);
|
|
67
|
-
}).rejects.toThrow(TimeoutError);
|
|
68
|
-
|
|
69
|
-
expect(count).toBe(5);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("Waits indefinitely if maxCount undefined", async () => {
|
|
73
|
-
let count = 0;
|
|
74
|
-
|
|
75
|
-
// Unlimited wait but returns when condition true
|
|
76
|
-
await wait.until(
|
|
77
|
-
() => {
|
|
78
|
-
count++;
|
|
79
|
-
return count >= 10;
|
|
80
|
-
},
|
|
81
|
-
10,
|
|
82
|
-
undefined,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
expect(count).toBe(10);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("Default milliseconds is 100ms", async () => {
|
|
89
|
-
let count = 0;
|
|
90
|
-
const start = Date.now();
|
|
91
|
-
|
|
92
|
-
await wait.until(() => {
|
|
93
|
-
count++;
|
|
94
|
-
return count >= 3;
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const elapsed = Date.now() - start;
|
|
98
|
-
// 100ms * 2 waits = 200ms (first check immediate), timer tolerance considered
|
|
99
|
-
expect(elapsed).toBeGreaterThanOrEqual(190);
|
|
100
|
-
expect(elapsed).toBeLessThan(350);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it("With maxCount=1, tries once then errors", async () => {
|
|
104
|
-
let count = 0;
|
|
105
|
-
|
|
106
|
-
await expect(async () => {
|
|
107
|
-
await wait.until(
|
|
108
|
-
() => {
|
|
109
|
-
count++;
|
|
110
|
-
return false;
|
|
111
|
-
},
|
|
112
|
-
10,
|
|
113
|
-
1,
|
|
114
|
-
);
|
|
115
|
-
}).rejects.toThrow(TimeoutError);
|
|
116
|
-
|
|
117
|
-
expect(count).toBe(1);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
//#endregion
|
|
123
|
-
});
|
package/tests/utils/xml.spec.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { xml } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
describe("XmlConvert", () => {
|
|
5
|
-
//#region parse
|
|
6
|
-
|
|
7
|
-
describe("parse()", () => {
|
|
8
|
-
it("Parses basic XML", () => {
|
|
9
|
-
const xmlStr = "<root><child>value</child></root>";
|
|
10
|
-
const result = xml.parse(xmlStr) as Record<string, unknown>;
|
|
11
|
-
|
|
12
|
-
expect(result).toHaveProperty("root");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("Parses XML with attributes", () => {
|
|
16
|
-
const xmlStr = '<root id="1"><child name="test">value</child></root>';
|
|
17
|
-
const result = xml.parse(xmlStr) as {
|
|
18
|
-
root: {
|
|
19
|
-
$: { id: string };
|
|
20
|
-
child: Array<{ $: { name: string }; _: string }>;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
expect(result.root.$.id).toBe("1");
|
|
25
|
-
expect(result.root.child[0].$.name).toBe("test");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("Parses nested XML", () => {
|
|
29
|
-
const xmlStr = "<root><parent><child>value</child></parent></root>";
|
|
30
|
-
const result = xml.parse(xmlStr) as {
|
|
31
|
-
root: { parent: Array<{ child: string[] }> };
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
expect(result.root.parent[0].child[0]).toBe("value");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("Parses text nodes as _ key", () => {
|
|
38
|
-
const xmlStr = '<item id="1">text content</item>';
|
|
39
|
-
const result = xml.parse(xmlStr) as {
|
|
40
|
-
item: { $: { id: string }; _: string };
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
expect(result.item._).toBe("text content");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("Removes namespace prefix (stripTagPrefix: true)", () => {
|
|
47
|
-
const xmlStr = "<ns:root><ns:child>value</ns:child></ns:root>";
|
|
48
|
-
const result = xml.parse(xmlStr, { stripTagPrefix: true }) as {
|
|
49
|
-
root: { child: string[] };
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
expect(result).toHaveProperty("root");
|
|
53
|
-
expect(result.root).toHaveProperty("child");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("Preserves namespace prefix (default)", () => {
|
|
57
|
-
const xmlStr = "<ns:root><ns:child>value</ns:child></ns:root>";
|
|
58
|
-
const result = xml.parse(xmlStr) as Record<string, unknown>;
|
|
59
|
-
|
|
60
|
-
expect(result).toHaveProperty("ns:root");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("Parses multiple same tags as array", () => {
|
|
64
|
-
const xmlStr = "<root><item>1</item><item>2</item><item>3</item></root>";
|
|
65
|
-
const result = xml.parse(xmlStr) as { root: { item: string[] } };
|
|
66
|
-
|
|
67
|
-
expect(result.root.item).toEqual(["1", "2", "3"]);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("Does not remove namespace prefix from attributes", () => {
|
|
71
|
-
const xmlStr = '<ns:root xmlns:ns="http://example.com"><ns:child>value</ns:child></ns:root>';
|
|
72
|
-
const result = xml.parse(xmlStr, { stripTagPrefix: true }) as {
|
|
73
|
-
root: { $: Record<string, string>; child: string[] };
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
expect(result.root.$).toHaveProperty("xmlns:ns");
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
//#endregion
|
|
81
|
-
|
|
82
|
-
//#region stringify
|
|
83
|
-
|
|
84
|
-
describe("stringify()", () => {
|
|
85
|
-
it("Serializes object to XML", () => {
|
|
86
|
-
const obj = { root: { child: "value" } };
|
|
87
|
-
const result = xml.stringify(obj);
|
|
88
|
-
|
|
89
|
-
expect(result).toContain("<root>");
|
|
90
|
-
expect(result).toContain("<child>value</child>");
|
|
91
|
-
expect(result).toContain("</root>");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("Serializes object with attributes", () => {
|
|
95
|
-
const obj = { root: { $: { id: "1" }, child: "value" } };
|
|
96
|
-
const result = xml.stringify(obj);
|
|
97
|
-
|
|
98
|
-
expect(result).toContain('id="1"');
|
|
99
|
-
expect(result).toContain("<child>value</child>");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("Serializes array as multiple tags", () => {
|
|
103
|
-
const obj = { root: { item: ["1", "2", "3"] } };
|
|
104
|
-
const result = xml.stringify(obj);
|
|
105
|
-
|
|
106
|
-
expect(result).toContain("<item>1</item>");
|
|
107
|
-
expect(result).toContain("<item>2</item>");
|
|
108
|
-
expect(result).toContain("<item>3</item>");
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("Serializes text node as _ key", () => {
|
|
112
|
-
const obj = { item: { $: { id: "1" }, _: "text content" } };
|
|
113
|
-
const result = xml.stringify(obj);
|
|
114
|
-
|
|
115
|
-
expect(result).toContain('id="1"');
|
|
116
|
-
expect(result).toContain("text content");
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("Serializes nested object", () => {
|
|
120
|
-
const obj = { root: { parent: { child: "value" } } };
|
|
121
|
-
const result = xml.stringify(obj);
|
|
122
|
-
|
|
123
|
-
expect(result).toContain("<parent>");
|
|
124
|
-
expect(result).toContain("<child>value</child>");
|
|
125
|
-
expect(result).toContain("</parent>");
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
//#endregion
|
|
130
|
-
|
|
131
|
-
//#region roundtrip
|
|
132
|
-
|
|
133
|
-
describe("parse/stringify roundtrip", () => {
|
|
134
|
-
it("Structure preserved after parse then stringify", () => {
|
|
135
|
-
const xmlStr = "<root><child>value</child></root>";
|
|
136
|
-
const parsed = xml.parse(xmlStr);
|
|
137
|
-
const result = xml.stringify(parsed);
|
|
138
|
-
|
|
139
|
-
expect(result).toContain("<root>");
|
|
140
|
-
expect(result).toContain("<child>value</child>");
|
|
141
|
-
expect(result).toContain("</root>");
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
//#endregion
|
|
146
|
-
});
|
package/tests/utils/zip.spec.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { ZipArchive } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
const encoder = new TextEncoder();
|
|
5
|
-
const decoder = new TextDecoder();
|
|
6
|
-
|
|
7
|
-
describe("ZipArchive", () => {
|
|
8
|
-
//#region write + compress
|
|
9
|
-
|
|
10
|
-
describe("write + compress", () => {
|
|
11
|
-
it("adds files with write and creates ZIP with compress", async () => {
|
|
12
|
-
const zip = new ZipArchive();
|
|
13
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
14
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
15
|
-
|
|
16
|
-
const zipBuffer = await zip.compress();
|
|
17
|
-
|
|
18
|
-
expect(zipBuffer instanceof Uint8Array).toBe(true);
|
|
19
|
-
expect(zipBuffer.length).toBeGreaterThan(0);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("handles filenames with special characters", async () => {
|
|
23
|
-
const zip = new ZipArchive();
|
|
24
|
-
zip.write("파일 이름.txt", encoder.encode("한글 내용"));
|
|
25
|
-
zip.write("file (1).txt", encoder.encode("괄호 포함"));
|
|
26
|
-
zip.write("file@#$.txt", encoder.encode("특수문자"));
|
|
27
|
-
|
|
28
|
-
const zipBuffer = await zip.compress();
|
|
29
|
-
const result = new ZipArchive(zipBuffer);
|
|
30
|
-
|
|
31
|
-
const content1 = await result.get("파일 이름.txt");
|
|
32
|
-
const content2 = await result.get("file (1).txt");
|
|
33
|
-
const content3 = await result.get("file@#$.txt");
|
|
34
|
-
|
|
35
|
-
expect(content1 != null ? decoder.decode(content1) : undefined).toBe("한글 내용");
|
|
36
|
-
expect(content2 != null ? decoder.decode(content2) : undefined).toBe("괄호 포함");
|
|
37
|
-
expect(content3 != null ? decoder.decode(content3) : undefined).toBe("특수문자");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("can compress empty ZIP", async () => {
|
|
41
|
-
const zip = new ZipArchive();
|
|
42
|
-
const zipBuffer = await zip.compress();
|
|
43
|
-
|
|
44
|
-
expect(zipBuffer instanceof Uint8Array).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("overwrites when writing same filename multiple times", async () => {
|
|
48
|
-
const zip = new ZipArchive();
|
|
49
|
-
zip.write("file.txt", encoder.encode("first"));
|
|
50
|
-
zip.write("file.txt", encoder.encode("second"));
|
|
51
|
-
|
|
52
|
-
const zipBuffer = await zip.compress();
|
|
53
|
-
const result = new ZipArchive(zipBuffer);
|
|
54
|
-
const content = await result.get("file.txt");
|
|
55
|
-
|
|
56
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("second");
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
|
|
62
|
-
//#region extractAll
|
|
63
|
-
|
|
64
|
-
describe("extractAll", () => {
|
|
65
|
-
it("extracts all compressed files", async () => {
|
|
66
|
-
const zip = new ZipArchive();
|
|
67
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
68
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
69
|
-
const zipBuffer = await zip.compress();
|
|
70
|
-
|
|
71
|
-
const result = new ZipArchive(zipBuffer);
|
|
72
|
-
const files = await result.extractAll();
|
|
73
|
-
|
|
74
|
-
expect(files.size).toBe(2);
|
|
75
|
-
expect(
|
|
76
|
-
files.get("file1.txt") != null ? decoder.decode(files.get("file1.txt")) : undefined,
|
|
77
|
-
).toBe("content 1");
|
|
78
|
-
expect(
|
|
79
|
-
files.get("file2.txt") != null ? decoder.decode(files.get("file2.txt")) : undefined,
|
|
80
|
-
).toBe("content 2");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("calls progress callback", async () => {
|
|
84
|
-
const zip = new ZipArchive();
|
|
85
|
-
zip.write("file1.txt", encoder.encode("a".repeat(1000)));
|
|
86
|
-
zip.write("file2.txt", encoder.encode("b".repeat(1000)));
|
|
87
|
-
const zipBuffer = await zip.compress();
|
|
88
|
-
|
|
89
|
-
const result = new ZipArchive(zipBuffer);
|
|
90
|
-
const progressCalls: Array<{ fileName: string; extractedSize: number }> = [];
|
|
91
|
-
|
|
92
|
-
await result.extractAll((progress) => {
|
|
93
|
-
progressCalls.push({
|
|
94
|
-
fileName: progress.fileName,
|
|
95
|
-
extractedSize: progress.extractedSize,
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
expect(progressCalls.length).toBeGreaterThan(0);
|
|
100
|
-
expect(progressCalls.some((p) => p.fileName === "file1.txt")).toBe(true);
|
|
101
|
-
expect(progressCalls.some((p) => p.fileName === "file2.txt")).toBe(true);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("returns empty cache when reader is not available", async () => {
|
|
105
|
-
const zip = new ZipArchive();
|
|
106
|
-
const files = await zip.extractAll();
|
|
107
|
-
|
|
108
|
-
expect(files.size).toBe(0);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
//#endregion
|
|
113
|
-
|
|
114
|
-
//#region get
|
|
115
|
-
|
|
116
|
-
describe("get", () => {
|
|
117
|
-
it("extracts specific file only", async () => {
|
|
118
|
-
const zip = new ZipArchive();
|
|
119
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
120
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
121
|
-
const zipBuffer = await zip.compress();
|
|
122
|
-
|
|
123
|
-
const result = new ZipArchive(zipBuffer);
|
|
124
|
-
const content = await result.get("file1.txt");
|
|
125
|
-
|
|
126
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("content 1");
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it("returns undefined for non-existent file", async () => {
|
|
130
|
-
const zip = new ZipArchive();
|
|
131
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
132
|
-
const zipBuffer = await zip.compress();
|
|
133
|
-
|
|
134
|
-
const result = new ZipArchive(zipBuffer);
|
|
135
|
-
const content = await result.get("nonexistent.txt");
|
|
136
|
-
|
|
137
|
-
expect(content).toBe(undefined);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("does not re-extract cached file", async () => {
|
|
141
|
-
const zip = new ZipArchive();
|
|
142
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
143
|
-
const zipBuffer = await zip.compress();
|
|
144
|
-
|
|
145
|
-
const result = new ZipArchive(zipBuffer);
|
|
146
|
-
const content1 = await result.get("file.txt");
|
|
147
|
-
const content2 = await result.get("file.txt");
|
|
148
|
-
|
|
149
|
-
expect(content1).toBe(content2); // Same reference
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("returns undefined when reader is not available", async () => {
|
|
153
|
-
const zip = new ZipArchive();
|
|
154
|
-
const content = await zip.get("file.txt");
|
|
155
|
-
|
|
156
|
-
expect(content).toBe(undefined);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
//#endregion
|
|
161
|
-
|
|
162
|
-
//#region exists
|
|
163
|
-
|
|
164
|
-
describe("exists", () => {
|
|
165
|
-
it("checks file existence", async () => {
|
|
166
|
-
const zip = new ZipArchive();
|
|
167
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
168
|
-
const zipBuffer = await zip.compress();
|
|
169
|
-
|
|
170
|
-
const result = new ZipArchive(zipBuffer);
|
|
171
|
-
const exists = await result.exists("file.txt");
|
|
172
|
-
const notExists = await result.exists("nonexistent.txt");
|
|
173
|
-
|
|
174
|
-
expect(exists).toBe(true);
|
|
175
|
-
expect(notExists).toBe(false);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it("returns false when reader is not available", async () => {
|
|
179
|
-
const zip = new ZipArchive();
|
|
180
|
-
const exists = await zip.exists("file.txt");
|
|
181
|
-
|
|
182
|
-
expect(exists).toBe(false);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
//#endregion
|
|
187
|
-
|
|
188
|
-
//#region close
|
|
189
|
-
|
|
190
|
-
describe("close", () => {
|
|
191
|
-
it("closes reader", async () => {
|
|
192
|
-
const zip = new ZipArchive();
|
|
193
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
194
|
-
const zipBuffer = await zip.compress();
|
|
195
|
-
|
|
196
|
-
const result = new ZipArchive(zipBuffer);
|
|
197
|
-
// Call extractAll to load into cache
|
|
198
|
-
await result.extractAll();
|
|
199
|
-
await result.close();
|
|
200
|
-
|
|
201
|
-
// Cached data is still available after close
|
|
202
|
-
const content = await result.get("file.txt");
|
|
203
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("content");
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it("automatically closes with await using statement", async () => {
|
|
207
|
-
const zip = new ZipArchive();
|
|
208
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
209
|
-
const zipBuffer = await zip.compress();
|
|
210
|
-
|
|
211
|
-
{
|
|
212
|
-
await using result = new ZipArchive(zipBuffer);
|
|
213
|
-
await result.extractAll();
|
|
214
|
-
const content = await result.get("file.txt");
|
|
215
|
-
expect(decoder.decode(content)).toBe("content");
|
|
216
|
-
} // close called automatically when await using block ends
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
//#endregion
|
|
221
|
-
});
|