@simplysm/core-node 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.
package/src/utils/fs.ts CHANGED
@@ -5,19 +5,19 @@ import { glob as globRaw, type GlobOptions, globSync as globRawSync } from "glob
5
5
  import { jsonParse, jsonStringify, SdError } from "@simplysm/core-common";
6
6
  import "@simplysm/core-common";
7
7
 
8
- //#region 존재 확인
8
+ //#region Existence Check
9
9
 
10
10
  /**
11
- * 파일 또는 디렉토리 존재 확인 (동기).
12
- * @param targetPath - 확인할 경로
11
+ * Checks if a file or directory exists (synchronous).
12
+ * @param targetPath - Path to check
13
13
  */
14
14
  export function fsExistsSync(targetPath: string): boolean {
15
15
  return fs.existsSync(targetPath);
16
16
  }
17
17
 
18
18
  /**
19
- * 파일 또는 디렉토리 존재 확인 (비동기).
20
- * @param targetPath - 확인할 경로
19
+ * Checks if a file or directory exists (asynchronous).
20
+ * @param targetPath - Path to check
21
21
  */
22
22
  export async function fsExists(targetPath: string): Promise<boolean> {
23
23
  try {
@@ -30,11 +30,11 @@ export async function fsExists(targetPath: string): Promise<boolean> {
30
30
 
31
31
  //#endregion
32
32
 
33
- //#region 디렉토리 생성
33
+ //#region Create Directory
34
34
 
35
35
  /**
36
- * 디렉토리 생성 (recursive).
37
- * @param targetPath - 생성할 디렉토리 경로
36
+ * Creates a directory (recursive).
37
+ * @param targetPath - Directory path to create
38
38
  */
39
39
  export function fsMkdirSync(targetPath: string): void {
40
40
  try {
@@ -45,8 +45,8 @@ export function fsMkdirSync(targetPath: string): void {
45
45
  }
46
46
 
47
47
  /**
48
- * 디렉토리 생성 (recursive, 비동기).
49
- * @param targetPath - 생성할 디렉토리 경로
48
+ * Creates a directory (recursive, asynchronous).
49
+ * @param targetPath - Directory path to create
50
50
  */
51
51
  export async function fsMkdir(targetPath: string): Promise<void> {
52
52
  try {
@@ -58,12 +58,12 @@ export async function fsMkdir(targetPath: string): Promise<void> {
58
58
 
59
59
  //#endregion
60
60
 
61
- //#region 삭제
61
+ //#region Delete
62
62
 
63
63
  /**
64
- * 파일 또는 디렉토리 삭제.
65
- * @param targetPath - 삭제할 경로
66
- * @remarks 동기 버전은 재시도 없이 즉시 실패함. 파일 잠금 일시적 오류 가능성이 있는 경우 fsRm 사용을 권장함.
64
+ * Deletes a file or directory.
65
+ * @param targetPath - Path to delete
66
+ * @remarks The synchronous version fails immediately without retries. Use fsRm for cases with potential transient errors like file locks.
67
67
  */
68
68
  export function fsRmSync(targetPath: string): void {
69
69
  try {
@@ -74,9 +74,9 @@ export function fsRmSync(targetPath: string): void {
74
74
  }
75
75
 
76
76
  /**
77
- * 파일 또는 디렉토리 삭제 (비동기).
78
- * @param targetPath - 삭제할 경로
79
- * @remarks 비동기 버전은 파일 잠금 등의 일시적 오류에 대해 최대 6회(500ms 간격) 재시도함.
77
+ * Deletes a file or directory (asynchronous).
78
+ * @param targetPath - Path to delete
79
+ * @remarks The asynchronous version retries up to 6 times (500ms interval) for transient errors like file locks.
80
80
  */
81
81
  export async function fsRm(targetPath: string): Promise<void> {
82
82
  try {
@@ -93,21 +93,21 @@ export async function fsRm(targetPath: string): Promise<void> {
93
93
 
94
94
  //#endregion
95
95
 
96
- //#region 복사
96
+ //#region Copy
97
97
 
98
98
  /**
99
- * 파일 또는 디렉토리 복사.
99
+ * Copies a file or directory.
100
100
  *
101
- * sourcePath 존재하지 않으면 아무 작업도 수행하지 않고 반환한다.
101
+ * If sourcePath does not exist, no action is performed and the function returns.
102
102
  *
103
- * @param sourcePath 복사할 원본 경로
104
- * @param targetPath 복사 대상 경로
105
- * @param filter 복사 여부를 결정하는 필터 함수.
106
- * 파일/디렉토리의 **절대 경로**가 전달되며,
107
- * true 반환하면 복사, false 제외.
108
- * **주의**: 최상위 sourcePath 필터 대상이 아니며,
109
- * 모든 하위 항목(자식, 손자 등)에 재귀적으로 filter 함수가 적용된다.
110
- * 디렉토리에 false 반환하면 해당 디렉토리와 모든 하위 항목이 건너뛰어짐.
103
+ * @param sourcePath Path of the source to copy
104
+ * @param targetPath Destination path for the copy
105
+ * @param filter A filter function that determines whether to copy.
106
+ * The **absolute path** of each file/directory is passed.
107
+ * Returns true to copy, false to exclude.
108
+ * **Note**: The top-level sourcePath is not subject to filtering;
109
+ * the filter function is applied recursively to all children (direct and indirect).
110
+ * Returning false for a directory skips that directory and all its contents.
111
111
  */
112
112
  export function fsCopySync(
113
113
  sourcePath: string,
@@ -151,18 +151,18 @@ export function fsCopySync(
151
151
  }
152
152
 
153
153
  /**
154
- * 파일 또는 디렉토리 복사 (비동기).
154
+ * Copies a file or directory (asynchronous).
155
155
  *
156
- * sourcePath 존재하지 않으면 아무 작업도 수행하지 않고 반환한다.
156
+ * If sourcePath does not exist, no action is performed and the function returns.
157
157
  *
158
- * @param sourcePath 복사할 원본 경로
159
- * @param targetPath 복사 대상 경로
160
- * @param filter 복사 여부를 결정하는 필터 함수.
161
- * 파일/디렉토리의 **절대 경로**가 전달되며,
162
- * true 반환하면 복사, false 제외.
163
- * **주의**: 최상위 sourcePath 필터 대상이 아니며,
164
- * 모든 하위 항목(자식, 손자 등)에 재귀적으로 filter 함수가 적용된다.
165
- * 디렉토리에 false 반환하면 해당 디렉토리와 모든 하위 항목이 건너뛰어짐.
158
+ * @param sourcePath Path of the source to copy
159
+ * @param targetPath Destination path for the copy
160
+ * @param filter A filter function that determines whether to copy.
161
+ * The **absolute path** of each file/directory is passed.
162
+ * Returns true to copy, false to exclude.
163
+ * **Note**: The top-level sourcePath is not subject to filtering;
164
+ * the filter function is applied recursively to all children (direct and indirect).
165
+ * Returning false for a directory skips that directory and all its contents.
166
166
  */
167
167
  export async function fsCopy(
168
168
  sourcePath: string,
@@ -207,11 +207,11 @@ export async function fsCopy(
207
207
 
208
208
  //#endregion
209
209
 
210
- //#region 파일 읽기
210
+ //#region Read File
211
211
 
212
212
  /**
213
- * 파일 읽기 (UTF-8 문자열).
214
- * @param targetPath - 읽을 파일 경로
213
+ * Reads a file as a UTF-8 string.
214
+ * @param targetPath - Path of the file to read
215
215
  */
216
216
  export function fsReadSync(targetPath: string): string {
217
217
  try {
@@ -222,8 +222,8 @@ export function fsReadSync(targetPath: string): string {
222
222
  }
223
223
 
224
224
  /**
225
- * 파일 읽기 (UTF-8 문자열, 비동기).
226
- * @param targetPath - 읽을 파일 경로
225
+ * Reads a file as a UTF-8 string (asynchronous).
226
+ * @param targetPath - Path of the file to read
227
227
  */
228
228
  export async function fsRead(targetPath: string): Promise<string> {
229
229
  try {
@@ -234,8 +234,8 @@ export async function fsRead(targetPath: string): Promise<string> {
234
234
  }
235
235
 
236
236
  /**
237
- * 파일 읽기 (Buffer).
238
- * @param targetPath - 읽을 파일 경로
237
+ * Reads a file as a Buffer.
238
+ * @param targetPath - Path of the file to read
239
239
  */
240
240
  export function fsReadBufferSync(targetPath: string): Buffer {
241
241
  try {
@@ -246,8 +246,8 @@ export function fsReadBufferSync(targetPath: string): Buffer {
246
246
  }
247
247
 
248
248
  /**
249
- * 파일 읽기 (Buffer, 비동기).
250
- * @param targetPath - 읽을 파일 경로
249
+ * Reads a file as a Buffer (asynchronous).
250
+ * @param targetPath - Path of the file to read
251
251
  */
252
252
  export async function fsReadBuffer(targetPath: string): Promise<Buffer> {
253
253
  try {
@@ -258,8 +258,8 @@ export async function fsReadBuffer(targetPath: string): Promise<Buffer> {
258
258
  }
259
259
 
260
260
  /**
261
- * JSON 파일 읽기 (JsonConvert 사용).
262
- * @param targetPath - 읽을 JSON 파일 경로
261
+ * Reads a JSON file (using JsonConvert).
262
+ * @param targetPath - Path of the JSON file to read
263
263
  */
264
264
  export function fsReadJsonSync<TData = unknown>(targetPath: string): TData {
265
265
  const contents = fsReadSync(targetPath);
@@ -272,8 +272,8 @@ export function fsReadJsonSync<TData = unknown>(targetPath: string): TData {
272
272
  }
273
273
 
274
274
  /**
275
- * JSON 파일 읽기 (JsonConvert 사용, 비동기).
276
- * @param targetPath - 읽을 JSON 파일 경로
275
+ * Reads a JSON file (using JsonConvert, asynchronous).
276
+ * @param targetPath - Path of the JSON file to read
277
277
  */
278
278
  export async function fsReadJson<TData = unknown>(targetPath: string): Promise<TData> {
279
279
  const contents = await fsRead(targetPath);
@@ -287,12 +287,12 @@ export async function fsReadJson<TData = unknown>(targetPath: string): Promise<T
287
287
 
288
288
  //#endregion
289
289
 
290
- //#region 파일 쓰기
290
+ //#region Write File
291
291
 
292
292
  /**
293
- * 파일 쓰기 (부모 디렉토리 자동 생성).
294
- * @param targetPath - 파일 경로
295
- * @param data - 데이터 (문자열 또는 바이너리)
293
+ * Writes data to a file (auto-creates parent directories).
294
+ * @param targetPath - Path of the file to write
295
+ * @param data - Data to write (string or binary)
296
296
  */
297
297
  export function fsWriteSync(targetPath: string, data: string | Uint8Array): void {
298
298
  fsMkdirSync(path.dirname(targetPath));
@@ -305,9 +305,9 @@ export function fsWriteSync(targetPath: string, data: string | Uint8Array): void
305
305
  }
306
306
 
307
307
  /**
308
- * 파일 쓰기 (부모 디렉토리 자동 생성, 비동기).
309
- * @param targetPath - 파일 경로
310
- * @param data - 데이터 (문자열 또는 바이너리)
308
+ * Writes data to a file (auto-creates parent directories, asynchronous).
309
+ * @param targetPath - Path of the file to write
310
+ * @param data - Data to write (string or binary)
311
311
  */
312
312
  export async function fsWrite(targetPath: string, data: string | Uint8Array): Promise<void> {
313
313
  await fsMkdir(path.dirname(targetPath));
@@ -320,10 +320,10 @@ export async function fsWrite(targetPath: string, data: string | Uint8Array): Pr
320
320
  }
321
321
 
322
322
  /**
323
- * JSON 파일 쓰기 (JsonConvert 사용).
324
- * @param targetPath - JSON 파일 경로
325
- * @param data - 데이터
326
- * @param options - JSON 직렬화 옵션
323
+ * Writes data to a JSON file (using JsonConvert).
324
+ * @param targetPath - Path of the JSON file to write
325
+ * @param data - Data to write
326
+ * @param options - JSON serialization options
327
327
  */
328
328
  export function fsWriteJsonSync(
329
329
  targetPath: string,
@@ -338,10 +338,10 @@ export function fsWriteJsonSync(
338
338
  }
339
339
 
340
340
  /**
341
- * JSON 파일 쓰기 (JsonConvert 사용, 비동기).
342
- * @param targetPath - JSON 파일 경로
343
- * @param data - 데이터
344
- * @param options - JSON 직렬화 옵션
341
+ * Writes data to a JSON file (using JsonConvert, asynchronous).
342
+ * @param targetPath - Path of the JSON file to write
343
+ * @param data - Data to write
344
+ * @param options - JSON serialization options
345
345
  */
346
346
  export async function fsWriteJson(
347
347
  targetPath: string,
@@ -357,11 +357,11 @@ export async function fsWriteJson(
357
357
 
358
358
  //#endregion
359
359
 
360
- //#region 디렉토리 읽기
360
+ //#region Read Directory
361
361
 
362
362
  /**
363
- * 디렉토리 내용 읽기.
364
- * @param targetPath - 읽을 디렉토리 경로
363
+ * Reads the contents of a directory.
364
+ * @param targetPath - Path of the directory to read
365
365
  */
366
366
  export function fsReaddirSync(targetPath: string): string[] {
367
367
  try {
@@ -372,8 +372,8 @@ export function fsReaddirSync(targetPath: string): string[] {
372
372
  }
373
373
 
374
374
  /**
375
- * 디렉토리 내용 읽기 (비동기).
376
- * @param targetPath - 읽을 디렉토리 경로
375
+ * Reads the contents of a directory (asynchronous).
376
+ * @param targetPath - Path of the directory to read
377
377
  */
378
378
  export async function fsReaddir(targetPath: string): Promise<string[]> {
379
379
  try {
@@ -385,11 +385,11 @@ export async function fsReaddir(targetPath: string): Promise<string[]> {
385
385
 
386
386
  //#endregion
387
387
 
388
- //#region 파일 정보
388
+ //#region File Information
389
389
 
390
390
  /**
391
- * 파일/디렉토리 정보 (심볼릭 링크 따라감).
392
- * @param targetPath - 정보를 조회할 경로
391
+ * Gets file/directory information (follows symbolic links).
392
+ * @param targetPath - Path to query information for
393
393
  */
394
394
  export function fsStatSync(targetPath: string): fs.Stats {
395
395
  try {
@@ -400,8 +400,8 @@ export function fsStatSync(targetPath: string): fs.Stats {
400
400
  }
401
401
 
402
402
  /**
403
- * 파일/디렉토리 정보 (심볼릭 링크 따라감, 비동기).
404
- * @param targetPath - 정보를 조회할 경로
403
+ * Gets file/directory information (follows symbolic links, asynchronous).
404
+ * @param targetPath - Path to query information for
405
405
  */
406
406
  export async function fsStat(targetPath: string): Promise<fs.Stats> {
407
407
  try {
@@ -412,8 +412,8 @@ export async function fsStat(targetPath: string): Promise<fs.Stats> {
412
412
  }
413
413
 
414
414
  /**
415
- * 파일/디렉토리 정보 (심볼릭 링크 따라가지 않음).
416
- * @param targetPath - 정보를 조회할 경로
415
+ * Gets file/directory information (does not follow symbolic links).
416
+ * @param targetPath - Path to query information for
417
417
  */
418
418
  export function fsLstatSync(targetPath: string): fs.Stats {
419
419
  try {
@@ -424,8 +424,8 @@ export function fsLstatSync(targetPath: string): fs.Stats {
424
424
  }
425
425
 
426
426
  /**
427
- * 파일/디렉토리 정보 (심볼릭 링크 따라가지 않음, 비동기).
428
- * @param targetPath - 정보를 조회할 경로
427
+ * Gets file/directory information (does not follow symbolic links, asynchronous).
428
+ * @param targetPath - Path to query information for
429
429
  */
430
430
  export async function fsLstat(targetPath: string): Promise<fs.Stats> {
431
431
  try {
@@ -437,13 +437,13 @@ export async function fsLstat(targetPath: string): Promise<fs.Stats> {
437
437
 
438
438
  //#endregion
439
439
 
440
- //#region 글로브
440
+ //#region Glob
441
441
 
442
442
  /**
443
- * 글로브 패턴으로 파일 검색.
444
- * @param pattern - 글로브 패턴 (예: "**\/*.ts")
445
- * @param options - glob 옵션
446
- * @returns 매칭된 파일들의 절대 경로 배열
443
+ * Searches for files using a glob pattern.
444
+ * @param pattern - Glob pattern (e.g., "**\/*.ts")
445
+ * @param options - glob options
446
+ * @returns Array of absolute paths for matched files
447
447
  */
448
448
  export function fsGlobSync(pattern: string, options?: GlobOptions): string[] {
449
449
  return globRawSync(pattern.replace(/\\/g, "/"), options ?? {}).map((item) =>
@@ -452,10 +452,10 @@ export function fsGlobSync(pattern: string, options?: GlobOptions): string[] {
452
452
  }
453
453
 
454
454
  /**
455
- * 글로브 패턴으로 파일 검색 (비동기).
456
- * @param pattern - 글로브 패턴 (예: "**\/*.ts")
457
- * @param options - glob 옵션
458
- * @returns 매칭된 파일들의 절대 경로 배열
455
+ * Searches for files using a glob pattern (asynchronous).
456
+ * @param pattern - Glob pattern (e.g., "**\/*.ts")
457
+ * @param options - glob options
458
+ * @returns Array of absolute paths for matched files
459
459
  */
460
460
  export async function fsGlob(pattern: string, options?: GlobOptions): Promise<string[]> {
461
461
  return (await globRaw(pattern.replace(/\\/g, "/"), options ?? {})).map((item) =>
@@ -465,11 +465,11 @@ export async function fsGlob(pattern: string, options?: GlobOptions): Promise<st
465
465
 
466
466
  //#endregion
467
467
 
468
- //#region 유틸리티
468
+ //#region Utilities
469
469
 
470
470
  /**
471
- * 지정 디렉토리 하위의 디렉토리를 재귀적으로 탐색하여 삭제.
472
- * 하위 디렉토리가 모두 삭제되어 디렉토리가 경우, 해당 디렉토리도 삭제 대상이 됨.
471
+ * Recursively searches and deletes empty directories under a specified directory.
472
+ * If all child directories are deleted and a parent becomes empty, it will also be deleted.
473
473
  */
474
474
  export async function fsClearEmptyDirectory(dirPath: string): Promise<void> {
475
475
  if (!(await fsExists(dirPath))) return;
@@ -486,23 +486,23 @@ export async function fsClearEmptyDirectory(dirPath: string): Promise<void> {
486
486
  }
487
487
  }
488
488
 
489
- // 파일이 있었다면 삭제 불가
489
+ // If there are files, cannot delete
490
490
  if (hasFiles) return;
491
491
 
492
- // 파일이 없었던 경우에만 재확인 (하위 디렉토리가 삭제되었을 있음)
492
+ // Only re-check if there were no files (child directories may have been deleted)
493
493
  if ((await fsReaddir(dirPath)).length === 0) {
494
494
  await fsRm(dirPath);
495
495
  }
496
496
  }
497
497
 
498
498
  /**
499
- * 시작 경로부터 루트 방향으로 상위 디렉토리를 순회하며 glob 패턴 검색.
500
- * 디렉토리에서 childGlob 패턴에 매칭되는 모든 파일 경로를 수집.
501
- * @param childGlob - 디렉토리에서 검색할 glob 패턴
502
- * @param fromPath - 검색 시작 경로
503
- * @param rootPath - 검색 종료 경로 (미지정 파일시스템 루트까지).
504
- * **주의**: fromPath rootPath의 자식 경로여야 함.
505
- * 그렇지 않으면 파일시스템 루트까지 검색함.
499
+ * Searches for files matching a glob pattern by traversing parent directories from a start path towards the root.
500
+ * Collects all file paths matching the childGlob pattern in each directory.
501
+ * @param childGlob - Glob pattern to search for in each directory
502
+ * @param fromPath - Path to start searching from
503
+ * @param rootPath - Path to stop searching at (if not specified, searches to filesystem root).
504
+ * **Note**: fromPath must be a child path of rootPath.
505
+ * Otherwise, searches to the filesystem root.
506
506
  */
507
507
  export function fsFindAllParentChildPathsSync(
508
508
  childGlob: string,
@@ -528,13 +528,13 @@ export function fsFindAllParentChildPathsSync(
528
528
  }
529
529
 
530
530
  /**
531
- * 시작 경로부터 루트 방향으로 상위 디렉토리를 순회하며 glob 패턴 검색 (비동기).
532
- * 디렉토리에서 childGlob 패턴에 매칭되는 모든 파일 경로를 수집.
533
- * @param childGlob - 디렉토리에서 검색할 glob 패턴
534
- * @param fromPath - 검색 시작 경로
535
- * @param rootPath - 검색 종료 경로 (미지정 파일시스템 루트까지).
536
- * **주의**: fromPath rootPath의 자식 경로여야 함.
537
- * 그렇지 않으면 파일시스템 루트까지 검색함.
531
+ * Searches for files matching a glob pattern by traversing parent directories from a start path towards the root (asynchronous).
532
+ * Collects all file paths matching the childGlob pattern in each directory.
533
+ * @param childGlob - Glob pattern to search for in each directory
534
+ * @param fromPath - Path to start searching from
535
+ * @param rootPath - Path to stop searching at (if not specified, searches to filesystem root).
536
+ * **Note**: fromPath must be a child path of rootPath.
537
+ * Otherwise, searches to the filesystem root.
538
538
  */
539
539
  export async function fsFindAllParentChildPaths(
540
540
  childGlob: string,
package/src/utils/path.ts CHANGED
@@ -6,8 +6,8 @@ import { ArgumentError } from "@simplysm/core-common";
6
6
  const NORM = Symbol("NormPath");
7
7
 
8
8
  /**
9
- * 정규화된 경로를 나타내는 브랜드 타입.
10
- * pathNorm()을 통해서만 생성 가능.
9
+ * Brand type representing a normalized path.
10
+ * Can only be created through pathNorm().
11
11
  */
12
12
  export type NormPath = string & {
13
13
  [NORM]: never;
@@ -15,10 +15,10 @@ export type NormPath = string & {
15
15
 
16
16
  //#endregion
17
17
 
18
- //#region 함수
18
+ //#region Functions
19
19
 
20
20
  /**
21
- * POSIX 스타일 경로로 변환 (백슬래시슬래시).
21
+ * Converts to POSIX-style path (backslashforward slash).
22
22
  *
23
23
  * @example
24
24
  * pathPosix("C:\\Users\\test"); // "C:/Users/test"
@@ -30,13 +30,13 @@ export function pathPosix(...args: string[]): string {
30
30
  }
31
31
 
32
32
  /**
33
- * 파일 경로의 디렉토리를 변경.
33
+ * Changes the directory of a file path.
34
34
  *
35
35
  * @example
36
36
  * pathChangeFileDirectory("/a/b/c.txt", "/a", "/x");
37
37
  * // → "/x/b/c.txt"
38
38
  *
39
- * @throws 파일이 fromDirectory 안에 없으면 에러
39
+ * @throws Error if the file is not inside fromDirectory
40
40
  */
41
41
  export function pathChangeFileDirectory(
42
42
  filePath: string,
@@ -48,7 +48,7 @@ export function pathChangeFileDirectory(
48
48
  }
49
49
 
50
50
  if (!pathIsChildPath(filePath, fromDirectory)) {
51
- throw new ArgumentError(`'${filePath}' ${fromDirectory} 안에 없습니다.`, {
51
+ throw new ArgumentError(`'${filePath}' is not inside ${fromDirectory}.`, {
52
52
  filePath,
53
53
  fromDirectory,
54
54
  });
@@ -58,7 +58,7 @@ export function pathChangeFileDirectory(
58
58
  }
59
59
 
60
60
  /**
61
- * 확장자를 제거한 파일명(basename) 반환.
61
+ * Returns the filename (basename) without extension.
62
62
  *
63
63
  * @example
64
64
  * pathBasenameWithoutExt("file.txt"); // "file"
@@ -69,27 +69,27 @@ export function pathBasenameWithoutExt(filePath: string): string {
69
69
  }
70
70
 
71
71
  /**
72
- * childPath parentPath의 자식 경로인지 확인.
73
- * 같은 경로는 false 반환.
72
+ * Checks if childPath is a child path of parentPath.
73
+ * Returns false if the paths are the same.
74
74
  *
75
- * 경로는 내부적으로 `pathNorm()`으로 정규화된 비교되며,
76
- * 플랫폼별 경로 구분자(Windows: `\`, Unix: `/`)를 사용한다.
75
+ * Paths are internally normalized using `pathNorm()` and compared using
76
+ * platform-specific path separators (Windows: `\`, Unix: `/`).
77
77
  *
78
78
  * @example
79
79
  * pathIsChildPath("/a/b/c", "/a/b"); // true
80
80
  * pathIsChildPath("/a/b", "/a/b/c"); // false
81
- * pathIsChildPath("/a/b", "/a/b"); // false (같은 경로)
81
+ * pathIsChildPath("/a/b", "/a/b"); // false (same path)
82
82
  */
83
83
  export function pathIsChildPath(childPath: string, parentPath: string): boolean {
84
84
  const normalizedChild = pathNorm(childPath);
85
85
  const normalizedParent = pathNorm(parentPath);
86
86
 
87
- // 같은 경로면 false
87
+ // Same path returns false
88
88
  if (normalizedChild === normalizedParent) {
89
89
  return false;
90
90
  }
91
91
 
92
- // 부모 경로 + 구분자로 시작하는지 확인
92
+ // Check if it starts with parent path + separator
93
93
  const parentWithSep = normalizedParent.endsWith(path.sep)
94
94
  ? normalizedParent
95
95
  : normalizedParent + path.sep;
@@ -98,27 +98,27 @@ export function pathIsChildPath(childPath: string, parentPath: string): boolean
98
98
  }
99
99
 
100
100
  /**
101
- * 경로를 정규화하여 NormPath로 반환.
102
- * 절대 경로로 변환되며, 플랫폼별 구분자로 정규화됨.
101
+ * Normalizes the path and returns it as NormPath.
102
+ * Converts to absolute path and normalizes using platform-specific separators.
103
103
  *
104
104
  * @example
105
105
  * pathNorm("/some/path"); // NormPath
106
- * pathNorm("relative", "path"); // NormPath (절대 경로로 변환)
106
+ * pathNorm("relative", "path"); // NormPath (converted to absolute path)
107
107
  */
108
108
  export function pathNorm(...paths: string[]): NormPath {
109
109
  return path.resolve(...paths) as NormPath;
110
110
  }
111
111
 
112
112
  /**
113
- * 타겟 경로 목록을 기준으로 파일을 필터링.
114
- * 파일이 타겟 경로와 같거나 타겟의 자식 경로일 포함.
113
+ * Filters files based on a list of target paths.
114
+ * Includes files that match or are children of a target path.
115
115
  *
116
- * @param files - 필터링할 파일 경로 목록.
117
- * **주의**: cwd 하위의 절대 경로여야 함.
118
- * cwd 외부 경로는 상대 경로(../ 형태) 변환되어 처리됨.
119
- * @param targets - 타겟 경로 목록 (cwd 기준 상대 경로, POSIX 스타일 권장)
120
- * @param cwd - 현재 작업 디렉토리 (절대 경로)
121
- * @returns targets 배열이면 files 그대로, 아니면 타겟 경로 하위 파일만
116
+ * @param files - File paths to filter.
117
+ * **Note**: Must be absolute paths under cwd.
118
+ * Paths outside cwd are converted to relative paths (../) for processing.
119
+ * @param targets - Target paths (relative to cwd, POSIX style recommended)
120
+ * @param cwd - Current working directory (absolute path)
121
+ * @returns If targets is empty, returns files as-is; otherwise returns only files under target paths
122
122
  *
123
123
  * @example
124
124
  * const files = ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"];
@@ -2,18 +2,18 @@ import { parentPort } from "worker_threads";
2
2
  import { SdError, transferableDecode, transferableEncode } from "@simplysm/core-common";
3
3
  import type { WorkerRequest, WorkerResponse } from "./types";
4
4
 
5
- //#region createSdWorker
5
+ //#region createWorker
6
6
 
7
7
  /**
8
- * 워커 스레드에서 사용할 워커 팩토리.
8
+ * Worker factory for use in worker threads.
9
9
  *
10
10
  * @example
11
- * // 이벤트 없는 워커
11
+ * // Worker without events
12
12
  * export default createWorker({
13
13
  * add: (a: number, b: number) => a + b,
14
14
  * });
15
15
  *
16
- * // 이벤트 있는 워커
16
+ * // Worker with events
17
17
  * interface MyEvents { progress: number; }
18
18
  * const methods = {
19
19
  * calc: (x: number) => { sender.send("progress", 50); return x * 2; },
@@ -32,13 +32,13 @@ export function createWorker<
32
32
  __events: TEvents;
33
33
  } {
34
34
  if (parentPort === null) {
35
- throw new SdError(" 스크립트는 워커 스레드에서 실행되어야 합니다 (parentPort 필요).");
35
+ throw new SdError("This script must be executed in a worker thread (parentPort required).");
36
36
  }
37
37
 
38
38
  const port = parentPort;
39
39
 
40
- // Worker 스레드의 stdout 메인 스레드로 자동 전달되지 않음
41
- // stdout.write 가로채서 메시지 프로토콜을 통해 메인 스레드로 전달
40
+ // Worker thread's stdout is not automatically forwarded to the main thread
41
+ // Intercept stdout.write and forward it to the main thread via message protocol
42
42
  process.stdout.write = (
43
43
  chunk: string | Uint8Array,
44
44
  encodingOrCallback?: BufferEncoding | ((err?: Error) => void),
@@ -60,7 +60,7 @@ export function createWorker<
60
60
  port.on("message", async (serializedRequest: unknown) => {
61
61
  const decoded = transferableDecode(serializedRequest);
62
62
 
63
- // 요청 구조 검증
63
+ // Validate request structure
64
64
  if (
65
65
  decoded == null ||
66
66
  typeof decoded !== "object" ||
@@ -77,7 +77,7 @@ export function createWorker<
77
77
  const errorResponse: WorkerResponse = {
78
78
  type: "error",
79
79
  request: { id: "unknown", method: "unknown", params: [] },
80
- body: new SdError(`형식이 잘못된 워커 요청: ${decodedStr}`),
80
+ body: new SdError(`Invalid worker request format: ${decodedStr}`),
81
81
  };
82
82
  const serialized = transferableEncode(errorResponse);
83
83
  port.postMessage(serialized.result, serialized.transferList);
@@ -91,7 +91,7 @@ export function createWorker<
91
91
  const response: WorkerResponse = {
92
92
  request,
93
93
  type: "error",
94
- body: new SdError(`알 없는 메서드: ${request.method}`),
94
+ body: new SdError(`Unknown method: ${request.method}`),
95
95
  };
96
96
 
97
97
  const serialized = transferableEncode(response);