@simplysm/core-common 13.0.69 → 13.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +66 -267
  2. package/dist/common.types.d.ts +14 -14
  3. package/dist/errors/argument-error.d.ts +10 -10
  4. package/dist/errors/argument-error.d.ts.map +1 -1
  5. package/dist/errors/argument-error.js +2 -2
  6. package/dist/errors/argument-error.js.map +1 -1
  7. package/dist/errors/not-implemented-error.d.ts +8 -8
  8. package/dist/errors/not-implemented-error.js +2 -2
  9. package/dist/errors/not-implemented-error.js.map +1 -1
  10. package/dist/errors/sd-error.d.ts +10 -10
  11. package/dist/errors/sd-error.d.ts.map +1 -1
  12. package/dist/errors/timeout-error.d.ts +10 -10
  13. package/dist/errors/timeout-error.js +3 -3
  14. package/dist/errors/timeout-error.js.map +1 -1
  15. package/dist/extensions/arr-ext.d.ts +2 -2
  16. package/dist/extensions/arr-ext.helpers.d.ts +8 -8
  17. package/dist/extensions/arr-ext.helpers.js +1 -1
  18. package/dist/extensions/arr-ext.helpers.js.map +1 -1
  19. package/dist/extensions/arr-ext.js +13 -13
  20. package/dist/extensions/arr-ext.js.map +1 -1
  21. package/dist/extensions/arr-ext.types.d.ts +57 -57
  22. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  23. package/dist/extensions/map-ext.d.ts +16 -16
  24. package/dist/extensions/set-ext.d.ts +11 -11
  25. package/dist/features/debounce-queue.d.ts +17 -15
  26. package/dist/features/debounce-queue.d.ts.map +1 -1
  27. package/dist/features/debounce-queue.js +6 -6
  28. package/dist/features/debounce-queue.js.map +1 -1
  29. package/dist/features/event-emitter.d.ts +20 -20
  30. package/dist/features/event-emitter.js +17 -17
  31. package/dist/features/serial-queue.d.ts +11 -11
  32. package/dist/features/serial-queue.js +5 -5
  33. package/dist/features/serial-queue.js.map +1 -1
  34. package/dist/globals.d.ts +4 -4
  35. package/dist/types/date-only.d.ts +64 -64
  36. package/dist/types/date-only.d.ts.map +1 -1
  37. package/dist/types/date-only.js +63 -63
  38. package/dist/types/date-time.d.ts +37 -37
  39. package/dist/types/date-time.d.ts.map +1 -1
  40. package/dist/types/date-time.js +54 -37
  41. package/dist/types/date-time.js.map +1 -1
  42. package/dist/types/lazy-gc-map.d.ts +26 -26
  43. package/dist/types/lazy-gc-map.d.ts.map +1 -1
  44. package/dist/types/lazy-gc-map.js +26 -26
  45. package/dist/types/lazy-gc-map.js.map +1 -1
  46. package/dist/types/time.d.ts +25 -25
  47. package/dist/types/time.d.ts.map +1 -1
  48. package/dist/types/time.js +25 -25
  49. package/dist/types/time.js.map +1 -1
  50. package/dist/types/uuid.d.ts +11 -11
  51. package/dist/types/uuid.d.ts.map +1 -1
  52. package/dist/types/uuid.js +12 -12
  53. package/dist/types/uuid.js.map +1 -1
  54. package/dist/utils/bytes.d.ts +17 -17
  55. package/dist/utils/bytes.js +4 -4
  56. package/dist/utils/bytes.js.map +1 -1
  57. package/dist/utils/date-format.d.ts +45 -45
  58. package/dist/utils/date-format.js +1 -1
  59. package/dist/utils/date-format.js.map +1 -1
  60. package/dist/utils/error.d.ts +4 -4
  61. package/dist/utils/json.d.ts +17 -17
  62. package/dist/utils/json.js +3 -3
  63. package/dist/utils/json.js.map +1 -1
  64. package/dist/utils/num.d.ts +23 -23
  65. package/dist/utils/obj.d.ts +111 -111
  66. package/dist/utils/obj.d.ts.map +1 -1
  67. package/dist/utils/obj.js +3 -3
  68. package/dist/utils/obj.js.map +1 -1
  69. package/dist/utils/path.d.ts +10 -10
  70. package/dist/utils/primitive.d.ts +5 -5
  71. package/dist/utils/primitive.js +1 -1
  72. package/dist/utils/primitive.js.map +1 -1
  73. package/dist/utils/str.d.ts +46 -46
  74. package/dist/utils/str.d.ts.map +1 -1
  75. package/dist/utils/str.js +5 -5
  76. package/dist/utils/str.js.map +1 -1
  77. package/dist/utils/template-strings.d.ts +26 -26
  78. package/dist/utils/transferable.d.ts +18 -18
  79. package/dist/utils/transferable.js +1 -1
  80. package/dist/utils/transferable.js.map +1 -1
  81. package/dist/utils/wait.d.ts +9 -9
  82. package/dist/utils/xml.d.ts +13 -13
  83. package/dist/utils/xml.d.ts.map +1 -1
  84. package/dist/utils/xml.js +1 -0
  85. package/dist/utils/xml.js.map +1 -1
  86. package/dist/zip/sd-zip.d.ts +22 -22
  87. package/dist/zip/sd-zip.js +16 -16
  88. package/package.json +4 -4
  89. package/src/common.types.ts +17 -17
  90. package/src/errors/argument-error.ts +15 -15
  91. package/src/errors/not-implemented-error.ts +9 -9
  92. package/src/errors/sd-error.ts +12 -12
  93. package/src/errors/timeout-error.ts +12 -12
  94. package/src/extensions/arr-ext.helpers.ts +10 -10
  95. package/src/extensions/arr-ext.ts +57 -57
  96. package/src/extensions/arr-ext.types.ts +59 -59
  97. package/src/extensions/map-ext.ts +16 -16
  98. package/src/extensions/set-ext.ts +11 -11
  99. package/src/features/debounce-queue.ts +21 -19
  100. package/src/features/event-emitter.ts +25 -25
  101. package/src/features/serial-queue.ts +13 -13
  102. package/src/globals.ts +4 -4
  103. package/src/index.ts +1 -1
  104. package/src/types/date-only.ts +83 -83
  105. package/src/types/date-time.ts +64 -44
  106. package/src/types/lazy-gc-map.ts +45 -45
  107. package/src/types/time.ts +34 -34
  108. package/src/types/uuid.ts +17 -17
  109. package/src/utils/bytes.ts +35 -35
  110. package/src/utils/date-format.ts +65 -65
  111. package/src/utils/error.ts +4 -4
  112. package/src/utils/json.ts +39 -39
  113. package/src/utils/num.ts +23 -23
  114. package/src/utils/obj.ts +138 -138
  115. package/src/utils/path.ts +10 -10
  116. package/src/utils/primitive.ts +6 -6
  117. package/src/utils/str.ts +260 -261
  118. package/src/utils/template-strings.ts +29 -29
  119. package/src/utils/transferable.ts +284 -284
  120. package/src/utils/wait.ts +10 -10
  121. package/src/utils/xml.ts +20 -19
  122. package/src/zip/sd-zip.ts +25 -25
  123. package/tests/errors/errors.spec.ts +80 -0
  124. package/tests/extensions/array-extension.spec.ts +796 -0
  125. package/tests/extensions/map-extension.spec.ts +147 -0
  126. package/tests/extensions/set-extension.spec.ts +74 -0
  127. package/tests/types/date-only.spec.ts +638 -0
  128. package/tests/types/date-time.spec.ts +391 -0
  129. package/tests/types/lazy-gc-map.spec.ts +692 -0
  130. package/tests/types/time.spec.ts +559 -0
  131. package/tests/types/uuid.spec.ts +74 -0
  132. package/tests/utils/bytes-utils.spec.ts +230 -0
  133. package/tests/utils/date-format.spec.ts +373 -0
  134. package/tests/utils/debounce-queue.spec.ts +272 -0
  135. package/tests/utils/json.spec.ts +486 -0
  136. package/tests/utils/number.spec.ts +157 -0
  137. package/tests/utils/object.spec.ts +829 -0
  138. package/tests/utils/path.spec.ts +78 -0
  139. package/tests/utils/primitive.spec.ts +43 -0
  140. package/tests/utils/sd-event-emitter.spec.ts +216 -0
  141. package/tests/utils/serial-queue.spec.ts +365 -0
  142. package/tests/utils/string.spec.ts +281 -0
  143. package/tests/utils/template-strings.spec.ts +57 -0
  144. package/tests/utils/transferable.spec.ts +703 -0
  145. package/tests/utils/wait.spec.ts +145 -0
  146. package/tests/utils/xml.spec.ts +146 -0
  147. package/tests/zip/sd-zip.spec.ts +238 -0
  148. package/docs/extensions.md +0 -503
  149. package/docs/features.md +0 -109
  150. package/docs/types.md +0 -486
  151. package/docs/utils.md +0 -780
package/src/utils/xml.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * XML 변환 유틸리티
2
+ * XML conversion utility
3
3
  */
4
4
  import type { XmlBuilderOptions } from "fast-xml-parser";
5
5
  import { XMLBuilder, XMLParser } from "fast-xml-parser";
@@ -7,14 +7,14 @@ import { XMLBuilder, XMLParser } from "fast-xml-parser";
7
7
  //#region parse
8
8
 
9
9
  /**
10
- * XML 문자열을 객체로 파싱
11
- * @param str XML 문자열
12
- * @param options 옵션
13
- * @param options.stripTagPrefix 태그 prefix 제거 여부 (namespace)
14
- * @returns 파싱된 객체. 구조:
15
- * - 속성: `$` 객체에 그룹화
16
- * - 텍스트 노드: `_` 키에 저장
17
- * - 자식 요소: 배열로 변환 (루트 요소 제외)
10
+ * Parse XML string into an object
11
+ * @param str XML string
12
+ * @param options Options
13
+ * @param options.stripTagPrefix Whether to remove tag prefix (namespace)
14
+ * @returns Parsed object. Structure:
15
+ * - Attributes: grouped in `$` object
16
+ * - Text nodes: stored in `_` key
17
+ * - Child elements: converted to array (except root element)
18
18
  * @example
19
19
  * xmlParse('<root id="1"><item>hello</item></root>');
20
20
  * // { root: { $: { id: "1" }, item: [{ _: "hello" }] } }
@@ -27,6 +27,7 @@ export function xmlParse(str: string, options?: { stripTagPrefix?: boolean }): u
27
27
  parseAttributeValue: false,
28
28
  parseTagValue: false,
29
29
  textNodeName: "_",
30
+ htmlEntities: true,
30
31
  isArray: (_tagName: string, jPath: string, _isLeafNode: boolean, isAttribute: boolean) => {
31
32
  return !isAttribute && jPath.split(".").length > 1;
32
33
  },
@@ -39,10 +40,10 @@ export function xmlParse(str: string, options?: { stripTagPrefix?: boolean }): u
39
40
  //#region stringify
40
41
 
41
42
  /**
42
- * 객체를 XML 문자열로 직렬화
43
- * @param obj 직렬화할 객체
44
- * @param options fast-xml-parser XmlBuilderOptions (선택)
45
- * @returns XML 문자열
43
+ * Serialize object to XML string
44
+ * @param obj Object to serialize
45
+ * @param options fast-xml-parser XmlBuilderOptions (optional)
46
+ * @returns XML string
46
47
  * @example
47
48
  * xmlStringify({
48
49
  * root: {
@@ -68,10 +69,10 @@ export function xmlStringify(obj: unknown, options?: XmlBuilderOptions): string
68
69
  //#region private
69
70
 
70
71
  /**
71
- * 태그 이름에서 namespace prefix 제거
72
- * @note XML 파싱 결과에서 "ns:tag" 형태의 namespace prefix를 제거하여 태그 이름만 남긴다.
73
- * 이를 통해 namespace를 고려하지 않고 일관된 방식으로 XML 데이터에 접근할 있다.
74
- * 단, 속성(attribute)은 prefix를 유지한다.
72
+ * Remove namespace prefix from tag name
73
+ * @note Removes the namespace prefix in the format "ns:tag" from XML parsing results, leaving only the tag name.
74
+ * This allows consistent access to XML data without considering namespace.
75
+ * However, attributes are kept with their prefix.
75
76
  */
76
77
  function stripTagPrefix(obj: unknown): unknown {
77
78
  if (Array.isArray(obj)) {
@@ -85,11 +86,11 @@ function stripTagPrefix(obj: unknown): unknown {
85
86
  for (const key of Object.keys(record)) {
86
87
  const value = record[key];
87
88
 
88
- // Attribute는 prefix를 제거하면 된다.
89
+ // Attributes must not have prefix removed
89
90
  if (key === "$") {
90
91
  newObj[key] = value;
91
92
  } else {
92
- // 태그 이름에서만 번째 ":"을 기준으로 prefix 제거
93
+ // Remove prefix from tag names only, based on first ":"
93
94
  const colonIndex = key.indexOf(":");
94
95
  const cleanKey = colonIndex !== -1 ? key.slice(colonIndex + 1) : key;
95
96
  newObj[cleanKey] = stripTagPrefix(value);
package/src/zip/sd-zip.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ZIP 파일 처리 유틸리티
2
+ * ZIP file processing utility
3
3
  */
4
4
  import type { FileEntry } from "@zip.js/zip.js";
5
5
  import {
@@ -18,25 +18,25 @@ export interface ZipArchiveProgress {
18
18
  }
19
19
 
20
20
  /**
21
- * ZIP 아카이브 처리 클래스
21
+ * ZIP archive processing class
22
22
  *
23
- * ZIP 파일의 읽기, 쓰기, 압축/해제를 처리합니다.
24
- * 내부 캐시를 사용하여 동일 파일의 중복 압축 해제를 방지합니다.
23
+ * Handles reading, writing, compression, and decompression of ZIP files.
24
+ * Uses internal caching to prevent duplicate decompression of the same file.
25
25
  *
26
26
  * @example
27
- * // ZIP 파일 읽기
27
+ * // Read ZIP file
28
28
  * await using archive = new ZipArchive(zipBytes);
29
29
  * const content = await archive.get("file.txt");
30
30
  *
31
31
  * @example
32
- * // ZIP 파일 생성
32
+ * // Create ZIP file
33
33
  * await using archive = new ZipArchive();
34
34
  * archive.write("file.txt", textBytes);
35
35
  * archive.write("data.json", jsonBytes);
36
36
  * const zipBytes = await archive.compress();
37
37
  *
38
38
  * @example
39
- * // 전체 압축 해제 (진행률 표시)
39
+ * // Extract all files (with progress reporting)
40
40
  * await using archive = new ZipArchive(zipBytes);
41
41
  * const files = await archive.extractAll((progress) => {
42
42
  * console.log(`${progress.fileName}: ${progress.extractedSize}/${progress.totalSize}`);
@@ -48,8 +48,8 @@ export class ZipArchive {
48
48
  private _entries?: Awaited<ReturnType<ZipReader<Blob | Bytes>["getEntries"]>>;
49
49
 
50
50
  /**
51
- * ZipArchive 생성
52
- * @param data ZIP 데이터 (생략 아카이브 생성)
51
+ * Create ZipArchive
52
+ * @param data ZIP data (omit to create a new archive)
53
53
  */
54
54
  constructor(data?: Blob | Bytes) {
55
55
  if (!data) return;
@@ -70,8 +70,8 @@ export class ZipArchive {
70
70
 
71
71
  //#region extractAll
72
72
  /**
73
- * 모든 파일을 압축 해제
74
- * @param progressCallback 진행률 콜백
73
+ * Extract all files
74
+ * @param progressCallback Progress callback
75
75
  */
76
76
  async extractAll(
77
77
  progressCallback?: (progress: ZipArchiveProgress) => void,
@@ -79,7 +79,7 @@ export class ZipArchive {
79
79
  const entries = await this._getEntries();
80
80
  if (entries == null) return this._cache;
81
81
 
82
- // 압축 해제 대상 크기 총합 계산
82
+ // Calculate total size to extract
83
83
  const totalSize = entries
84
84
  .filter((e) => !e.directory)
85
85
  .reduce((acc, e) => acc + e.uncompressedSize, 0);
@@ -112,7 +112,7 @@ export class ZipArchive {
112
112
 
113
113
  this._cache.set(entry.filename, entryBytes);
114
114
 
115
- // 개별 파일이 끝나면 누적 처리
115
+ // Accumulate when individual file completes
116
116
  totalExtracted += entry.uncompressedSize;
117
117
 
118
118
  progressCallback?.({
@@ -128,8 +128,8 @@ export class ZipArchive {
128
128
 
129
129
  //#region get
130
130
  /**
131
- * 특정 파일 압축 해제
132
- * @param fileName 파일 이름
131
+ * Extract specific file
132
+ * @param fileName File name
133
133
  */
134
134
  async get(fileName: string): Promise<Bytes | undefined> {
135
135
  if (this._cache.has(fileName)) {
@@ -156,8 +156,8 @@ export class ZipArchive {
156
156
 
157
157
  //#region exists
158
158
  /**
159
- * 파일 존재 여부 확인
160
- * @param fileName 파일 이름
159
+ * Check if file exists
160
+ * @param fileName File name
161
161
  */
162
162
  async exists(fileName: string): Promise<boolean> {
163
163
  if (this._cache.has(fileName)) {
@@ -176,9 +176,9 @@ export class ZipArchive {
176
176
 
177
177
  //#region write
178
178
  /**
179
- * 파일 쓰기 (캐시에 저장)
180
- * @param fileName 파일 이름
181
- * @param bytes 파일 내용
179
+ * Write file (store in cache)
180
+ * @param fileName File name
181
+ * @param bytes File content
182
182
  */
183
183
  write(fileName: string, bytes: Bytes): void {
184
184
  this._cache.set(fileName, bytes);
@@ -187,11 +187,11 @@ export class ZipArchive {
187
187
 
188
188
  //#region compress
189
189
  /**
190
- * 캐시된 파일들을 ZIP으로 압축
190
+ * Compress cached files to ZIP
191
191
  *
192
192
  * @remarks
193
- * 내부적으로 `extractAll()`을 호출하여 모든 파일을 메모리에 로드한 압축합니다.
194
- * 대용량 ZIP 파일의 경우 메모리 사용량에 주의가 필요합니다.
193
+ * Internally calls `extractAll()` to load all files into memory before compressing.
194
+ * Be mindful of memory usage when dealing with large ZIP files.
195
195
  */
196
196
  async compress(): Promise<Bytes> {
197
197
  const fileMap = await this.extractAll();
@@ -211,7 +211,7 @@ export class ZipArchive {
211
211
 
212
212
  //#region close
213
213
  /**
214
- * 리더 닫기 캐시 정리
214
+ * Close reader and clear cache
215
215
  */
216
216
  async close(): Promise<void> {
217
217
  await this._reader?.close();
@@ -219,7 +219,7 @@ export class ZipArchive {
219
219
  }
220
220
 
221
221
  /**
222
- * await using 지원
222
+ * Support for await using
223
223
  */
224
224
  async [Symbol.asyncDispose](): Promise<void> {
225
225
  await this.close();
@@ -0,0 +1,80 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { SdError, ArgumentError } from "@simplysm/core-common";
3
+
4
+ describe("Errors", () => {
5
+ //#region SdError
6
+
7
+ describe("SdError", () => {
8
+ it("Creates with cause", () => {
9
+ const cause = new Error("original error");
10
+ const error = new SdError(cause, "wrapped message");
11
+
12
+ // Message combined as "wrapped message => original error" format
13
+ expect(error.message).toContain("wrapped message");
14
+ expect(error.message).toContain("original error");
15
+ });
16
+
17
+ it("Integrates cause message", () => {
18
+ const cause = new Error("cause message");
19
+ const error = new SdError(cause, "main message");
20
+
21
+ expect(error.message).toContain("main message");
22
+ });
23
+
24
+ it("Handles multi-level cause chain", () => {
25
+ const root = new Error("root error");
26
+ const middle = new SdError(root, "middle error");
27
+ const top = new SdError(middle, "top error");
28
+
29
+ expect(top.message).toContain("top error");
30
+ expect(top.message).toContain("middle error");
31
+ expect(top.message).toContain("root error");
32
+ });
33
+
34
+ it("Integrates cause stack to current stack", () => {
35
+ const cause = new Error("cause error");
36
+ const error = new SdError(cause, "main error");
37
+
38
+ expect(error.stack).toContain("---- cause stack ----");
39
+ expect(error.stack).toContain(cause.stack);
40
+ });
41
+
42
+ it("Converts non-Error object passed as cause using String()", () => {
43
+ // number
44
+ const errorFromNumber = new SdError(42, "number cause");
45
+ expect(errorFromNumber.message).toContain("42");
46
+
47
+ // object
48
+ const errorFromObject = new SdError({ code: 500, reason: "server error" }, "object cause");
49
+ expect(errorFromObject.message).toContain("object cause");
50
+
51
+ // null/undefined
52
+ const errorFromNull = new SdError(null, "null cause");
53
+ expect(errorFromNull.message).toContain("null cause");
54
+ });
55
+ });
56
+
57
+ //#endregion
58
+
59
+ //#region ArgumentError
60
+
61
+ describe("ArgumentError", () => {
62
+ it("Creates with argObj", () => {
63
+ const error = new ArgumentError("invalid argument", { param: "value", expected: "string" });
64
+
65
+ // argObj included in message as YAML format
66
+ expect(error.message).toContain("invalid argument");
67
+ expect(error.message).toContain("param");
68
+ expect(error.message).toContain("value");
69
+ });
70
+
71
+ it("Creates with only argObj without message", () => {
72
+ const error = new ArgumentError({ key: "value" });
73
+
74
+ expect(error.message).toContain("Invalid arguments");
75
+ expect(error.message).toContain("key");
76
+ });
77
+ });
78
+
79
+ //#endregion
80
+ });