@simplysm/core-node 13.0.0-beta.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.
Files changed (111) hide show
  1. package/.cache/typecheck-node.tsbuildinfo +1 -0
  2. package/.cache/typecheck-tests-node.tsbuildinfo +1 -0
  3. package/README.md +375 -0
  4. package/dist/core-common/src/common.types.d.ts +74 -0
  5. package/dist/core-common/src/common.types.d.ts.map +1 -0
  6. package/dist/core-common/src/env.d.ts +6 -0
  7. package/dist/core-common/src/env.d.ts.map +1 -0
  8. package/dist/core-common/src/errors/argument-error.d.ts +25 -0
  9. package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
  10. package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
  11. package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
  12. package/dist/core-common/src/errors/sd-error.d.ts +27 -0
  13. package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
  14. package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
  15. package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
  16. package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
  17. package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
  18. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
  19. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
  20. package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
  21. package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
  22. package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
  23. package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
  24. package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
  25. package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
  26. package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
  27. package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
  28. package/dist/core-common/src/features/event-emitter.d.ts +66 -0
  29. package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
  30. package/dist/core-common/src/features/serial-queue.d.ts +47 -0
  31. package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
  32. package/dist/core-common/src/index.d.ts +32 -0
  33. package/dist/core-common/src/index.d.ts.map +1 -0
  34. package/dist/core-common/src/types/date-only.d.ts +152 -0
  35. package/dist/core-common/src/types/date-only.d.ts.map +1 -0
  36. package/dist/core-common/src/types/date-time.d.ts +96 -0
  37. package/dist/core-common/src/types/date-time.d.ts.map +1 -0
  38. package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
  39. package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
  40. package/dist/core-common/src/types/time.d.ts +68 -0
  41. package/dist/core-common/src/types/time.d.ts.map +1 -0
  42. package/dist/core-common/src/types/uuid.d.ts +35 -0
  43. package/dist/core-common/src/types/uuid.d.ts.map +1 -0
  44. package/dist/core-common/src/utils/bytes.d.ts +51 -0
  45. package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
  46. package/dist/core-common/src/utils/date-format.d.ts +90 -0
  47. package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
  48. package/dist/core-common/src/utils/json.d.ts +34 -0
  49. package/dist/core-common/src/utils/json.d.ts.map +1 -0
  50. package/dist/core-common/src/utils/num.d.ts +60 -0
  51. package/dist/core-common/src/utils/num.d.ts.map +1 -0
  52. package/dist/core-common/src/utils/obj.d.ts +258 -0
  53. package/dist/core-common/src/utils/obj.d.ts.map +1 -0
  54. package/dist/core-common/src/utils/path.d.ts +23 -0
  55. package/dist/core-common/src/utils/path.d.ts.map +1 -0
  56. package/dist/core-common/src/utils/primitive.d.ts +18 -0
  57. package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
  58. package/dist/core-common/src/utils/str.d.ts +103 -0
  59. package/dist/core-common/src/utils/str.d.ts.map +1 -0
  60. package/dist/core-common/src/utils/template-strings.d.ts +84 -0
  61. package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
  62. package/dist/core-common/src/utils/transferable.d.ts +47 -0
  63. package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
  64. package/dist/core-common/src/utils/wait.d.ts +19 -0
  65. package/dist/core-common/src/utils/wait.d.ts.map +1 -0
  66. package/dist/core-common/src/utils/xml.d.ts +36 -0
  67. package/dist/core-common/src/utils/xml.d.ts.map +1 -0
  68. package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
  69. package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
  70. package/dist/core-node/src/features/fs-watcher.d.ts +70 -0
  71. package/dist/core-node/src/features/fs-watcher.d.ts.map +1 -0
  72. package/dist/core-node/src/index.d.ts +7 -0
  73. package/dist/core-node/src/index.d.ts.map +1 -0
  74. package/dist/core-node/src/utils/fs.d.ts +197 -0
  75. package/dist/core-node/src/utils/fs.d.ts.map +1 -0
  76. package/dist/core-node/src/utils/path.d.ts +75 -0
  77. package/dist/core-node/src/utils/path.d.ts.map +1 -0
  78. package/dist/core-node/src/worker/create-worker.d.ts +23 -0
  79. package/dist/core-node/src/worker/create-worker.d.ts.map +1 -0
  80. package/dist/core-node/src/worker/types.d.ts +67 -0
  81. package/dist/core-node/src/worker/types.d.ts.map +1 -0
  82. package/dist/core-node/src/worker/worker.d.ts +27 -0
  83. package/dist/core-node/src/worker/worker.d.ts.map +1 -0
  84. package/dist/features/fs-watcher.js +100 -0
  85. package/dist/features/fs-watcher.js.map +7 -0
  86. package/dist/index.js +7 -0
  87. package/dist/index.js.map +7 -0
  88. package/dist/utils/fs.js +305 -0
  89. package/dist/utils/fs.js.map +7 -0
  90. package/dist/utils/path.js +48 -0
  91. package/dist/utils/path.js.map +7 -0
  92. package/dist/worker/create-worker.js +85 -0
  93. package/dist/worker/create-worker.js.map +7 -0
  94. package/dist/worker/types.js +1 -0
  95. package/dist/worker/types.js.map +7 -0
  96. package/dist/worker/worker.js +142 -0
  97. package/dist/worker/worker.js.map +7 -0
  98. package/lib/worker-dev-proxy.js +12 -0
  99. package/package.json +23 -0
  100. package/src/features/fs-watcher.ts +176 -0
  101. package/src/index.ts +11 -0
  102. package/src/utils/fs.ts +550 -0
  103. package/src/utils/path.ts +128 -0
  104. package/src/worker/create-worker.ts +141 -0
  105. package/src/worker/types.ts +86 -0
  106. package/src/worker/worker.ts +207 -0
  107. package/tests/utils/fs-watcher.spec.ts +295 -0
  108. package/tests/utils/fs.spec.ts +754 -0
  109. package/tests/utils/path.spec.ts +192 -0
  110. package/tests/worker/fixtures/test-worker.ts +35 -0
  111. package/tests/worker/sd-worker.spec.ts +183 -0
@@ -0,0 +1,100 @@
1
+ import { DebounceQueue } from "@simplysm/core-common";
2
+ import * as chokidar from "chokidar";
3
+ import { createConsola } from "consola";
4
+ import { pathNorm } from "../utils/path";
5
+ const FS_WATCHER_EVENTS = ["add", "addDir", "change", "unlink", "unlinkDir"];
6
+ class FsWatcher {
7
+ /**
8
+ * 파일 감시 시작 (비동기).
9
+ * ready 이벤트가 발생할 때까지 대기.
10
+ *
11
+ * @param paths - 감시할 파일/디렉토리 경로 또는 glob 패턴 배열
12
+ * @param options - chokidar 옵션
13
+ */
14
+ static async watch(paths, options) {
15
+ return new Promise((resolve, reject) => {
16
+ const watcher = new FsWatcher(paths, options);
17
+ watcher._watcher.on("ready", () => {
18
+ resolve(watcher);
19
+ });
20
+ watcher._watcher.on("error", reject);
21
+ });
22
+ }
23
+ _watcher;
24
+ _ignoreInitial = true;
25
+ _debounceQueues = [];
26
+ _logger = createConsola().withTag("sd-fs-watcher");
27
+ constructor(paths, options) {
28
+ this._watcher = chokidar.watch(paths, {
29
+ persistent: true,
30
+ ...options,
31
+ ignoreInitial: true
32
+ });
33
+ this._ignoreInitial = options?.ignoreInitial ?? this._ignoreInitial;
34
+ this._watcher.on("error", (err) => {
35
+ this._logger.error("FsWatcher error:", err);
36
+ });
37
+ }
38
+ /**
39
+ * 파일 변경 이벤트 핸들러 등록.
40
+ * 지정된 delay 시간 동안 이벤트를 모아서 한 번에 콜백 호출.
41
+ *
42
+ * @param opt.delay - 이벤트 병합 대기 시간 (ms)
43
+ * @param cb - 변경 이벤트 콜백
44
+ */
45
+ onChange(opt, cb) {
46
+ const fnQ = new DebounceQueue(opt.delay);
47
+ this._debounceQueues.push(fnQ);
48
+ let changeInfoMap = /* @__PURE__ */ new Map();
49
+ if (!this._ignoreInitial) {
50
+ fnQ.run(async () => {
51
+ await cb([]);
52
+ });
53
+ }
54
+ this._watcher.on("all", (event, filePath) => {
55
+ if (!FS_WATCHER_EVENTS.includes(event)) return;
56
+ if (!changeInfoMap.has(filePath)) {
57
+ changeInfoMap.set(filePath, event);
58
+ }
59
+ const prevEvent = changeInfoMap.get(filePath);
60
+ if (prevEvent === "add" && event === "change") {
61
+ changeInfoMap.set(filePath, "add");
62
+ } else if (prevEvent === "add" && event === "unlink" || prevEvent === "addDir" && event === "unlinkDir") {
63
+ changeInfoMap.delete(filePath);
64
+ } else if (prevEvent === "unlink" && (event === "add" || event === "change")) {
65
+ changeInfoMap.set(filePath, "add");
66
+ } else if (prevEvent === "unlinkDir" && event === "addDir") {
67
+ changeInfoMap.set(filePath, "addDir");
68
+ } else {
69
+ changeInfoMap.set(filePath, event);
70
+ }
71
+ fnQ.run(async () => {
72
+ if (changeInfoMap.size === 0) return;
73
+ const currChangeInfoMap = changeInfoMap;
74
+ changeInfoMap = /* @__PURE__ */ new Map();
75
+ const changeInfos = Array.from(currChangeInfoMap.entries()).map(
76
+ ([path, evt]) => ({
77
+ path: pathNorm(path),
78
+ event: evt
79
+ })
80
+ );
81
+ await cb(changeInfos);
82
+ });
83
+ });
84
+ return this;
85
+ }
86
+ /**
87
+ * 파일 감시 종료.
88
+ */
89
+ async close() {
90
+ for (const q of this._debounceQueues) {
91
+ q.dispose();
92
+ }
93
+ this._debounceQueues.length = 0;
94
+ await this._watcher.close();
95
+ }
96
+ }
97
+ export {
98
+ FsWatcher
99
+ };
100
+ //# sourceMappingURL=fs-watcher.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/features/fs-watcher.ts"],
4
+ "sourcesContent": ["import { DebounceQueue } from \"@simplysm/core-common\";\nimport * as chokidar from \"chokidar\";\nimport { createConsola } from \"consola\";\nimport type { EventName } from \"chokidar/handler.js\";\nimport { type NormPath, pathNorm } from \"../utils/path\";\n\n//#region Types\n\n/**\n * \uC9C0\uC6D0\uD558\uB294 \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 \uBAA9\uB85D.\n */\nconst FS_WATCHER_EVENTS = [\"add\", \"addDir\", \"change\", \"unlink\", \"unlinkDir\"] as const;\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785.\n */\nexport type FsWatcherEvent = (typeof FS_WATCHER_EVENTS)[number];\n\n/**\n * \uD30C\uC77C \uBCC0\uACBD \uC815\uBCF4.\n */\nexport interface FsWatcherChangeInfo {\n /** \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD0C0\uC785 */\n event: FsWatcherEvent;\n /** \uBCC0\uACBD\uB41C \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uC815\uADDC\uD654\uB428) */\n path: NormPath;\n}\n\n//#endregion\n\n//#region FsWatcher\n\n/**\n * chokidar \uAE30\uBC18 \uD30C\uC77C \uC2DC\uC2A4\uD15C \uAC10\uC2DC \uB798\uD37C.\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uBC1C\uC0DD\uD55C \uC774\uBCA4\uD2B8\uB97C \uBCD1\uD569\uD558\uC5EC \uCF5C\uBC31 \uD638\uCD9C.\n *\n * **\uC8FC\uC758**: chokidar\uC758 `ignoreInitial` \uC635\uC158\uC740 \uB0B4\uBD80\uC801\uC73C\uB85C \uD56D\uC0C1 `true`\uB85C \uC124\uC815\uB41C\uB2E4.\n * `options.ignoreInitial: false`\uB97C \uC804\uB2EC\uD558\uBA74 `onChange` \uCCAB \uD638\uCD9C \uC2DC \uBE48 \uBC30\uC5F4\uB85C\n * \uCF5C\uBC31\uC774 \uD638\uCD9C\uB418\uC9C0\uB9CC, \uC2E4\uC81C \uCD08\uAE30 \uD30C\uC77C \uBAA9\uB85D\uC740 \uD3EC\uD568\uB418\uC9C0 \uC54A\uB294\uB2E4.\n * \uC774\uB294 \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB85C\uC9C1\uACFC\uC758 \uCDA9\uB3CC\uC744 \uBC29\uC9C0\uD558\uAE30 \uC704\uD55C \uC758\uB3C4\uB41C \uB3D9\uC791\uC774\uB2E4.\n *\n * @example\n * const watcher = await FsWatcher.watch([\"src/**\\/*.ts\"]);\n * watcher.onChange({ delay: 300 }, (changes) => {\n * for (const { path, event } of changes) {\n * console.log(`${event}: ${path}`);\n * }\n * });\n *\n * // \uC885\uB8CC\n * await watcher.close();\n */\nexport class FsWatcher {\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC2DC\uC791 (\uBE44\uB3D9\uAE30).\n * ready \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD560 \uB54C\uAE4C\uC9C0 \uB300\uAE30.\n *\n * @param paths - \uAC10\uC2DC\uD560 \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uB610\uB294 glob \uD328\uD134 \uBC30\uC5F4\n * @param options - chokidar \uC635\uC158\n */\n static async watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher> {\n return new Promise<FsWatcher>((resolve, reject) => {\n const watcher = new FsWatcher(paths, options);\n watcher._watcher.on(\"ready\", () => {\n resolve(watcher);\n });\n watcher._watcher.on(\"error\", reject);\n });\n }\n\n private readonly _watcher: chokidar.FSWatcher;\n private readonly _ignoreInitial: boolean = true;\n private readonly _debounceQueues: DebounceQueue[] = [];\n\n private readonly _logger = createConsola().withTag(\"sd-fs-watcher\");\n\n private constructor(paths: string[], options?: chokidar.ChokidarOptions) {\n this._watcher = chokidar.watch(paths, {\n persistent: true,\n ...options,\n ignoreInitial: true,\n });\n this._ignoreInitial = options?.ignoreInitial ?? this._ignoreInitial;\n\n // \uAC10\uC2DC \uC911 \uBC1C\uC0DD\uD558\uB294 \uC5D0\uB7EC \uB85C\uAE45\n this._watcher.on(\"error\", (err) => {\n this._logger.error(\"FsWatcher error:\", err);\n });\n }\n\n /**\n * \uD30C\uC77C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uB4F1\uB85D.\n * \uC9C0\uC815\uB41C delay \uC2DC\uAC04 \uB3D9\uC548 \uC774\uBCA4\uD2B8\uB97C \uBAA8\uC544\uC11C \uD55C \uBC88\uC5D0 \uCF5C\uBC31 \uD638\uCD9C.\n *\n * @param opt.delay - \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uB300\uAE30 \uC2DC\uAC04 (ms)\n * @param cb - \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uCF5C\uBC31\n */\n onChange(opt: { delay?: number }, cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>): this {\n const fnQ = new DebounceQueue(opt.delay);\n this._debounceQueues.push(fnQ);\n\n let changeInfoMap = new Map<string, EventName>();\n\n // ignoreInitial\uC774 false\uBA74 \uCD08\uAE30\uC5D0 \uBE48 \uBC30\uC5F4\uB85C \uCF5C\uBC31 \uD638\uCD9C\n if (!this._ignoreInitial) {\n fnQ.run(async () => {\n await cb([]);\n });\n }\n\n this._watcher.on(\"all\", (event, filePath) => {\n // \uC9C0\uC6D0\uD558\uB294 \uC774\uBCA4\uD2B8\uB9CC \uCC98\uB9AC\n if (!FS_WATCHER_EVENTS.includes(event as FsWatcherEvent)) return;\n\n /*\n * \uC774\uBCA4\uD2B8 \uBCD1\uD569 \uC804\uB7B5:\n * \uC9E7\uC740 \uC2DC\uAC04 \uB0B4 \uAC19\uC740 \uD30C\uC77C\uC5D0 \uB300\uD574 \uC5EC\uB7EC \uC774\uBCA4\uD2B8\uAC00 \uBC1C\uC0DD\uD558\uBA74 \uCD5C\uC885 \uC0C1\uD0DC\uB9CC \uC804\uB2EC\uD55C\uB2E4.\n * - add + change \u2192 add (\uC0DD\uC131 \uC9C1\uD6C4 \uC218\uC815\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - add + unlink \u2192 \uC0AD\uC81C (\uC0DD\uC131 \uD6C4 \uC989\uC2DC \uC0AD\uC81C\uB294 \uBCC0\uACBD \uC5C6\uC74C)\n * - unlink + add \u2192 add (\uC0AD\uC81C \uD6C4 \uC7AC\uC0DD\uC131\uC740 \uC0DD\uC131\uC73C\uB85C \uAC04\uC8FC)\n * - \uADF8 \uC678 \u2192 \uCD5C\uC2E0 \uC774\uBCA4\uD2B8\uB85C \uB36E\uC5B4\uC500\n */\n if (!changeInfoMap.has(filePath)) {\n changeInfoMap.set(filePath, event);\n }\n const prevEvent = changeInfoMap.get(filePath)!;\n\n if (prevEvent === \"add\" && event === \"change\") {\n // add \uD6C4 change \u2192 add \uC720\uC9C0\n changeInfoMap.set(filePath, \"add\");\n } else if ((prevEvent === \"add\" && event === \"unlink\") || (prevEvent === \"addDir\" && event === \"unlinkDir\")) {\n // add \uD6C4 unlink \u2192 \uBCC0\uACBD \uC5C6\uC74C (\uC0AD\uC81C)\n changeInfoMap.delete(filePath);\n } else if (prevEvent === \"unlink\" && (event === \"add\" || event === \"change\")) {\n // unlink \uD6C4 add/change \u2192 add (\uD30C\uC77C \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"add\");\n } else if (prevEvent === \"unlinkDir\" && event === \"addDir\") {\n // unlinkDir \uD6C4 addDir \u2192 addDir (\uB514\uB809\uD1A0\uB9AC \uC7AC\uC0DD\uC131)\n changeInfoMap.set(filePath, \"addDir\");\n } else {\n changeInfoMap.set(filePath, event);\n }\n\n fnQ.run(async () => {\n if (changeInfoMap.size === 0) return;\n\n const currChangeInfoMap = changeInfoMap;\n changeInfoMap = new Map<string, EventName>();\n\n const changeInfos = Array.from(currChangeInfoMap.entries()).map(\n ([path, evt]): FsWatcherChangeInfo => ({\n path: pathNorm(path),\n event: evt as FsWatcherEvent,\n }),\n );\n\n await cb(changeInfos);\n });\n });\n\n return this;\n }\n\n /**\n * \uD30C\uC77C \uAC10\uC2DC \uC885\uB8CC.\n */\n async close(): Promise<void> {\n for (const q of this._debounceQueues) {\n q.dispose();\n }\n this._debounceQueues.length = 0;\n await this._watcher.close();\n }\n}\n\n//#endregion\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B,YAAY,cAAc;AAC1B,SAAS,qBAAqB;AAE9B,SAAwB,gBAAgB;AAOxC,MAAM,oBAAoB,CAAC,OAAO,UAAU,UAAU,UAAU,WAAW;AAyCpE,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrB,aAAa,MAAM,OAAiB,SAAwD;AAC1F,WAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AACjD,YAAM,UAAU,IAAI,UAAU,OAAO,OAAO;AAC5C,cAAQ,SAAS,GAAG,SAAS,MAAM;AACjC,gBAAQ,OAAO;AAAA,MACjB,CAAC;AACD,cAAQ,SAAS,GAAG,SAAS,MAAM;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEiB;AAAA,EACA,iBAA0B;AAAA,EAC1B,kBAAmC,CAAC;AAAA,EAEpC,UAAU,cAAc,EAAE,QAAQ,eAAe;AAAA,EAE1D,YAAY,OAAiB,SAAoC;AACvE,SAAK,WAAW,SAAS,MAAM,OAAO;AAAA,MACpC,YAAY;AAAA,MACZ,GAAG;AAAA,MACH,eAAe;AAAA,IACjB,CAAC;AACD,SAAK,iBAAiB,SAAS,iBAAiB,KAAK;AAGrD,SAAK,SAAS,GAAG,SAAS,CAAC,QAAQ;AACjC,WAAK,QAAQ,MAAM,oBAAoB,GAAG;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,KAAyB,IAAwE;AACxG,UAAM,MAAM,IAAI,cAAc,IAAI,KAAK;AACvC,SAAK,gBAAgB,KAAK,GAAG;AAE7B,QAAI,gBAAgB,oBAAI,IAAuB;AAG/C,QAAI,CAAC,KAAK,gBAAgB;AACxB,UAAI,IAAI,YAAY;AAClB,cAAM,GAAG,CAAC,CAAC;AAAA,MACb,CAAC;AAAA,IACH;AAEA,SAAK,SAAS,GAAG,OAAO,CAAC,OAAO,aAAa;AAE3C,UAAI,CAAC,kBAAkB,SAAS,KAAuB,EAAG;AAU1D,UAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAChC,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AACA,YAAM,YAAY,cAAc,IAAI,QAAQ;AAE5C,UAAI,cAAc,SAAS,UAAU,UAAU;AAE7C,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAY,cAAc,SAAS,UAAU,YAAc,cAAc,YAAY,UAAU,aAAc;AAE3G,sBAAc,OAAO,QAAQ;AAAA,MAC/B,WAAW,cAAc,aAAa,UAAU,SAAS,UAAU,WAAW;AAE5E,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC,WAAW,cAAc,eAAe,UAAU,UAAU;AAE1D,sBAAc,IAAI,UAAU,QAAQ;AAAA,MACtC,OAAO;AACL,sBAAc,IAAI,UAAU,KAAK;AAAA,MACnC;AAEA,UAAI,IAAI,YAAY;AAClB,YAAI,cAAc,SAAS,EAAG;AAE9B,cAAM,oBAAoB;AAC1B,wBAAgB,oBAAI,IAAuB;AAE3C,cAAM,cAAc,MAAM,KAAK,kBAAkB,QAAQ,CAAC,EAAE;AAAA,UAC1D,CAAC,CAAC,MAAM,GAAG,OAA4B;AAAA,YACrC,MAAM,SAAS,IAAI;AAAA,YACnB,OAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,GAAG,WAAW;AAAA,MACtB,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,eAAW,KAAK,KAAK,iBAAiB;AACpC,QAAE,QAAQ;AAAA,IACZ;AACA,SAAK,gBAAgB,SAAS;AAC9B,UAAM,KAAK,SAAS,MAAM;AAAA,EAC5B;AACF;",
6
+ "names": []
7
+ }
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./utils/fs";
2
+ export * from "./utils/path";
3
+ export * from "./features/fs-watcher";
4
+ export * from "./worker/types";
5
+ export * from "./worker/worker";
6
+ export * from "./worker/create-worker";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["// Utils\nexport * from \"./utils/fs\";\nexport * from \"./utils/path\";\n\n// Features\nexport * from \"./features/fs-watcher\";\n\n// Worker\nexport * from \"./worker/types\";\nexport * from \"./worker/worker\";\nexport * from \"./worker/create-worker\";\n"],
5
+ "mappings": "AACA,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,305 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import os from "os";
4
+ import { glob as globRaw, globSync as globRawSync } from "glob";
5
+ import { jsonParse, jsonStringify, SdError } from "@simplysm/core-common";
6
+ import "@simplysm/core-common";
7
+ function fsExistsSync(targetPath) {
8
+ return fs.existsSync(targetPath);
9
+ }
10
+ async function fsExists(targetPath) {
11
+ try {
12
+ await fs.promises.access(targetPath);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+ function fsMkdirSync(targetPath) {
19
+ try {
20
+ fs.mkdirSync(targetPath, { recursive: true });
21
+ } catch (err) {
22
+ throw new SdError(err, targetPath);
23
+ }
24
+ }
25
+ async function fsMkdir(targetPath) {
26
+ try {
27
+ await fs.promises.mkdir(targetPath, { recursive: true });
28
+ } catch (err) {
29
+ throw new SdError(err, targetPath);
30
+ }
31
+ }
32
+ function fsRmSync(targetPath) {
33
+ try {
34
+ fs.rmSync(targetPath, { recursive: true, force: true });
35
+ } catch (err) {
36
+ throw new SdError(err, targetPath);
37
+ }
38
+ }
39
+ async function fsRm(targetPath) {
40
+ try {
41
+ await fs.promises.rm(targetPath, {
42
+ recursive: true,
43
+ force: true,
44
+ retryDelay: 500,
45
+ maxRetries: 6
46
+ });
47
+ } catch (err) {
48
+ throw new SdError(err, targetPath);
49
+ }
50
+ }
51
+ function fsCopySync(sourcePath, targetPath, filter) {
52
+ if (!fsExistsSync(sourcePath)) {
53
+ return;
54
+ }
55
+ let stats;
56
+ try {
57
+ stats = fs.lstatSync(sourcePath);
58
+ } catch (err) {
59
+ throw new SdError(err, sourcePath);
60
+ }
61
+ if (stats.isDirectory()) {
62
+ fsMkdirSync(targetPath);
63
+ const children = fsGlobSync(path.resolve(sourcePath, "*"), { dot: true });
64
+ for (const childPath of children) {
65
+ if (filter !== void 0 && !filter(childPath)) {
66
+ continue;
67
+ }
68
+ const relativeChildPath = path.relative(sourcePath, childPath);
69
+ const childTargetPath = path.resolve(targetPath, relativeChildPath);
70
+ fsCopySync(childPath, childTargetPath, filter);
71
+ }
72
+ } else {
73
+ fsMkdirSync(path.dirname(targetPath));
74
+ try {
75
+ fs.copyFileSync(sourcePath, targetPath);
76
+ } catch (err) {
77
+ throw new SdError(err, targetPath);
78
+ }
79
+ }
80
+ }
81
+ async function fsCopy(sourcePath, targetPath, filter) {
82
+ if (!await fsExists(sourcePath)) {
83
+ return;
84
+ }
85
+ let stats;
86
+ try {
87
+ stats = await fs.promises.lstat(sourcePath);
88
+ } catch (err) {
89
+ throw new SdError(err, sourcePath);
90
+ }
91
+ if (stats.isDirectory()) {
92
+ await fsMkdir(targetPath);
93
+ const children = await fsGlob(path.resolve(sourcePath, "*"), { dot: true });
94
+ await children.parallelAsync(async (childPath) => {
95
+ if (filter !== void 0 && !filter(childPath)) {
96
+ return;
97
+ }
98
+ const relativeChildPath = path.relative(sourcePath, childPath);
99
+ const childTargetPath = path.resolve(targetPath, relativeChildPath);
100
+ await fsCopy(childPath, childTargetPath, filter);
101
+ });
102
+ } else {
103
+ await fsMkdir(path.dirname(targetPath));
104
+ try {
105
+ await fs.promises.copyFile(sourcePath, targetPath);
106
+ } catch (err) {
107
+ throw new SdError(err, targetPath);
108
+ }
109
+ }
110
+ }
111
+ function fsReadSync(targetPath) {
112
+ try {
113
+ return fs.readFileSync(targetPath, "utf-8");
114
+ } catch (err) {
115
+ throw new SdError(err, targetPath);
116
+ }
117
+ }
118
+ async function fsRead(targetPath) {
119
+ try {
120
+ return await fs.promises.readFile(targetPath, "utf-8");
121
+ } catch (err) {
122
+ throw new SdError(err, targetPath);
123
+ }
124
+ }
125
+ function fsReadBufferSync(targetPath) {
126
+ try {
127
+ return fs.readFileSync(targetPath);
128
+ } catch (err) {
129
+ throw new SdError(err, targetPath);
130
+ }
131
+ }
132
+ async function fsReadBuffer(targetPath) {
133
+ try {
134
+ return await fs.promises.readFile(targetPath);
135
+ } catch (err) {
136
+ throw new SdError(err, targetPath);
137
+ }
138
+ }
139
+ function fsReadJsonSync(targetPath) {
140
+ const contents = fsReadSync(targetPath);
141
+ try {
142
+ return jsonParse(contents);
143
+ } catch (err) {
144
+ const preview = contents.length > 500 ? contents.slice(0, 500) + "...(truncated)" : contents;
145
+ throw new SdError(err, targetPath + os.EOL + preview);
146
+ }
147
+ }
148
+ async function fsReadJson(targetPath) {
149
+ const contents = await fsRead(targetPath);
150
+ try {
151
+ return jsonParse(contents);
152
+ } catch (err) {
153
+ const preview = contents.length > 500 ? contents.slice(0, 500) + "...(truncated)" : contents;
154
+ throw new SdError(err, targetPath + os.EOL + preview);
155
+ }
156
+ }
157
+ function fsWriteSync(targetPath, data) {
158
+ fsMkdirSync(path.dirname(targetPath));
159
+ try {
160
+ fs.writeFileSync(targetPath, data, { flush: true });
161
+ } catch (err) {
162
+ throw new SdError(err, targetPath);
163
+ }
164
+ }
165
+ async function fsWrite(targetPath, data) {
166
+ await fsMkdir(path.dirname(targetPath));
167
+ try {
168
+ await fs.promises.writeFile(targetPath, data, { flush: true });
169
+ } catch (err) {
170
+ throw new SdError(err, targetPath);
171
+ }
172
+ }
173
+ function fsWriteJsonSync(targetPath, data, options) {
174
+ const json = jsonStringify(data, options);
175
+ fsWriteSync(targetPath, json);
176
+ }
177
+ async function fsWriteJson(targetPath, data, options) {
178
+ const json = jsonStringify(data, options);
179
+ await fsWrite(targetPath, json);
180
+ }
181
+ function fsReaddirSync(targetPath) {
182
+ try {
183
+ return fs.readdirSync(targetPath);
184
+ } catch (err) {
185
+ throw new SdError(err, targetPath);
186
+ }
187
+ }
188
+ async function fsReaddir(targetPath) {
189
+ try {
190
+ return await fs.promises.readdir(targetPath);
191
+ } catch (err) {
192
+ throw new SdError(err, targetPath);
193
+ }
194
+ }
195
+ function fsStatSync(targetPath) {
196
+ try {
197
+ return fs.statSync(targetPath);
198
+ } catch (err) {
199
+ throw new SdError(err, targetPath);
200
+ }
201
+ }
202
+ async function fsStat(targetPath) {
203
+ try {
204
+ return await fs.promises.stat(targetPath);
205
+ } catch (err) {
206
+ throw new SdError(err, targetPath);
207
+ }
208
+ }
209
+ function fsLstatSync(targetPath) {
210
+ try {
211
+ return fs.lstatSync(targetPath);
212
+ } catch (err) {
213
+ throw new SdError(err, targetPath);
214
+ }
215
+ }
216
+ async function fsLstat(targetPath) {
217
+ try {
218
+ return await fs.promises.lstat(targetPath);
219
+ } catch (err) {
220
+ throw new SdError(err, targetPath);
221
+ }
222
+ }
223
+ function fsGlobSync(pattern, options) {
224
+ return globRawSync(pattern.replace(/\\/g, "/"), options ?? {}).map((item) => path.resolve(item.toString()));
225
+ }
226
+ async function fsGlob(pattern, options) {
227
+ return (await globRaw(pattern.replace(/\\/g, "/"), options ?? {})).map((item) => path.resolve(item.toString()));
228
+ }
229
+ async function fsClearEmptyDirectory(dirPath) {
230
+ if (!await fsExists(dirPath)) return;
231
+ const childNames = await fsReaddir(dirPath);
232
+ let hasFiles = false;
233
+ for (const childName of childNames) {
234
+ const childPath = path.resolve(dirPath, childName);
235
+ if ((await fsLstat(childPath)).isDirectory()) {
236
+ await fsClearEmptyDirectory(childPath);
237
+ } else {
238
+ hasFiles = true;
239
+ }
240
+ }
241
+ if (hasFiles) return;
242
+ if ((await fsReaddir(dirPath)).length === 0) {
243
+ await fsRm(dirPath);
244
+ }
245
+ }
246
+ function fsFindAllParentChildPathsSync(childGlob, fromPath, rootPath) {
247
+ const resultPaths = [];
248
+ let current = fromPath;
249
+ while (current) {
250
+ const potential = path.resolve(current, childGlob);
251
+ const globResults = fsGlobSync(potential);
252
+ resultPaths.push(...globResults);
253
+ if (current === rootPath) break;
254
+ const next = path.dirname(current);
255
+ if (next === current) break;
256
+ current = next;
257
+ }
258
+ return resultPaths;
259
+ }
260
+ async function fsFindAllParentChildPaths(childGlob, fromPath, rootPath) {
261
+ const resultPaths = [];
262
+ let current = fromPath;
263
+ while (current) {
264
+ const potential = path.resolve(current, childGlob);
265
+ const globResults = await fsGlob(potential);
266
+ resultPaths.push(...globResults);
267
+ if (current === rootPath) break;
268
+ const next = path.dirname(current);
269
+ if (next === current) break;
270
+ current = next;
271
+ }
272
+ return resultPaths;
273
+ }
274
+ export {
275
+ fsClearEmptyDirectory,
276
+ fsCopy,
277
+ fsCopySync,
278
+ fsExists,
279
+ fsExistsSync,
280
+ fsFindAllParentChildPaths,
281
+ fsFindAllParentChildPathsSync,
282
+ fsGlob,
283
+ fsGlobSync,
284
+ fsLstat,
285
+ fsLstatSync,
286
+ fsMkdir,
287
+ fsMkdirSync,
288
+ fsRead,
289
+ fsReadBuffer,
290
+ fsReadBufferSync,
291
+ fsReadJson,
292
+ fsReadJsonSync,
293
+ fsReadSync,
294
+ fsReaddir,
295
+ fsReaddirSync,
296
+ fsRm,
297
+ fsRmSync,
298
+ fsStat,
299
+ fsStatSync,
300
+ fsWrite,
301
+ fsWriteJson,
302
+ fsWriteJsonSync,
303
+ fsWriteSync
304
+ };
305
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/fs.ts"],
4
+ "sourcesContent": ["import path from \"path\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport { glob as globRaw, type GlobOptions, globSync as globRawSync } from \"glob\";\nimport { jsonParse, jsonStringify, SdError } from \"@simplysm/core-common\";\nimport \"@simplysm/core-common\";\n\n//#region \uC874\uC7AC \uD655\uC778\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uC874\uC7AC \uD655\uC778 (\uB3D9\uAE30).\n * @param targetPath - \uD655\uC778\uD560 \uACBD\uB85C\n */\nexport function fsExistsSync(targetPath: string): boolean {\n return fs.existsSync(targetPath);\n}\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uC874\uC7AC \uD655\uC778 (\uBE44\uB3D9\uAE30).\n * @param targetPath - \uD655\uC778\uD560 \uACBD\uB85C\n */\nexport async function fsExists(targetPath: string): Promise<boolean> {\n try {\n await fs.promises.access(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\n//#endregion\n\n//#region \uB514\uB809\uD1A0\uB9AC \uC0DD\uC131\n\n/**\n * \uB514\uB809\uD1A0\uB9AC \uC0DD\uC131 (recursive).\n * @param targetPath - \uC0DD\uC131\uD560 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\n */\nexport function fsMkdirSync(targetPath: string): void {\n try {\n fs.mkdirSync(targetPath, { recursive: true });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uB514\uB809\uD1A0\uB9AC \uC0DD\uC131 (recursive, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC0DD\uC131\uD560 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\n */\nexport async function fsMkdir(targetPath: string): Promise<void> {\n try {\n await fs.promises.mkdir(targetPath, { recursive: true });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n//#endregion\n\n//#region \uC0AD\uC81C\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uC0AD\uC81C.\n * @param targetPath - \uC0AD\uC81C\uD560 \uACBD\uB85C\n * @remarks \uB3D9\uAE30 \uBC84\uC804\uC740 \uC7AC\uC2DC\uB3C4 \uC5C6\uC774 \uC989\uC2DC \uC2E4\uD328\uD568. \uD30C\uC77C \uC7A0\uAE08 \uB4F1 \uC77C\uC2DC\uC801 \uC624\uB958 \uAC00\uB2A5\uC131\uC774 \uC788\uB294 \uACBD\uC6B0 fsRm \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD568.\n */\nexport function fsRmSync(targetPath: string): void {\n try {\n fs.rmSync(targetPath, { recursive: true, force: true });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uC0AD\uC81C (\uBE44\uB3D9\uAE30).\n * @param targetPath - \uC0AD\uC81C\uD560 \uACBD\uB85C\n * @remarks \uBE44\uB3D9\uAE30 \uBC84\uC804\uC740 \uD30C\uC77C \uC7A0\uAE08 \uB4F1\uC758 \uC77C\uC2DC\uC801 \uC624\uB958\uC5D0 \uB300\uD574 \uCD5C\uB300 6\uD68C(500ms \uAC04\uACA9) \uC7AC\uC2DC\uB3C4\uD568.\n */\nexport async function fsRm(targetPath: string): Promise<void> {\n try {\n await fs.promises.rm(targetPath, {\n recursive: true,\n force: true,\n retryDelay: 500,\n maxRetries: 6,\n });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n//#endregion\n\n//#region \uBCF5\uC0AC\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uBCF5\uC0AC.\n *\n * sourcePath\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC73C\uBA74 \uC544\uBB34 \uC791\uC5C5\uB3C4 \uC218\uD589\uD558\uC9C0 \uC54A\uACE0 \uBC18\uD658\uD55C\uB2E4.\n *\n * @param sourcePath \uBCF5\uC0AC\uD560 \uC6D0\uBCF8 \uACBD\uB85C\n * @param targetPath \uBCF5\uC0AC \uB300\uC0C1 \uACBD\uB85C\n * @param filter \uBCF5\uC0AC \uC5EC\uBD80\uB97C \uACB0\uC815\uD558\uB294 \uD544\uD130 \uD568\uC218.\n * \uAC01 \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC\uC758 **\uC808\uB300 \uACBD\uB85C**\uAC00 \uC804\uB2EC\uB418\uBA70,\n * true\uB97C \uBC18\uD658\uD558\uBA74 \uBCF5\uC0AC, false\uBA74 \uC81C\uC678.\n * **\uC8FC\uC758**: \uCD5C\uC0C1\uC704 sourcePath\uB294 \uD544\uD130 \uB300\uC0C1\uC774 \uC544\uB2C8\uBA70,\n * \uBAA8\uB4E0 \uD558\uC704 \uD56D\uBAA9(\uC790\uC2DD, \uC190\uC790 \uB4F1)\uC5D0 \uC7AC\uADC0\uC801\uC73C\uB85C filter \uD568\uC218\uAC00 \uC801\uC6A9\uB41C\uB2E4.\n * \uB514\uB809\uD1A0\uB9AC\uC5D0 false\uB97C \uBC18\uD658\uD558\uBA74 \uD574\uB2F9 \uB514\uB809\uD1A0\uB9AC\uC640 \uBAA8\uB4E0 \uD558\uC704 \uD56D\uBAA9\uC774 \uAC74\uB108\uB6F0\uC5B4\uC9D0.\n */\nexport function fsCopySync(sourcePath: string, targetPath: string, filter?: (absolutePath: string) => boolean): void {\n if (!fsExistsSync(sourcePath)) {\n return;\n }\n\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(sourcePath);\n } catch (err) {\n throw new SdError(err, sourcePath);\n }\n\n if (stats.isDirectory()) {\n fsMkdirSync(targetPath);\n\n const children = fsGlobSync(path.resolve(sourcePath, \"*\"), { dot: true });\n\n for (const childPath of children) {\n if (filter !== undefined && !filter(childPath)) {\n continue;\n }\n\n const relativeChildPath = path.relative(sourcePath, childPath);\n const childTargetPath = path.resolve(targetPath, relativeChildPath);\n fsCopySync(childPath, childTargetPath, filter);\n }\n } else {\n fsMkdirSync(path.dirname(targetPath));\n\n try {\n fs.copyFileSync(sourcePath, targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n }\n}\n\n/**\n * \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC \uBCF5\uC0AC (\uBE44\uB3D9\uAE30).\n *\n * sourcePath\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC73C\uBA74 \uC544\uBB34 \uC791\uC5C5\uB3C4 \uC218\uD589\uD558\uC9C0 \uC54A\uACE0 \uBC18\uD658\uD55C\uB2E4.\n *\n * @param sourcePath \uBCF5\uC0AC\uD560 \uC6D0\uBCF8 \uACBD\uB85C\n * @param targetPath \uBCF5\uC0AC \uB300\uC0C1 \uACBD\uB85C\n * @param filter \uBCF5\uC0AC \uC5EC\uBD80\uB97C \uACB0\uC815\uD558\uB294 \uD544\uD130 \uD568\uC218.\n * \uAC01 \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC\uC758 **\uC808\uB300 \uACBD\uB85C**\uAC00 \uC804\uB2EC\uB418\uBA70,\n * true\uB97C \uBC18\uD658\uD558\uBA74 \uBCF5\uC0AC, false\uBA74 \uC81C\uC678.\n * **\uC8FC\uC758**: \uCD5C\uC0C1\uC704 sourcePath\uB294 \uD544\uD130 \uB300\uC0C1\uC774 \uC544\uB2C8\uBA70,\n * \uBAA8\uB4E0 \uD558\uC704 \uD56D\uBAA9(\uC790\uC2DD, \uC190\uC790 \uB4F1)\uC5D0 \uC7AC\uADC0\uC801\uC73C\uB85C filter \uD568\uC218\uAC00 \uC801\uC6A9\uB41C\uB2E4.\n * \uB514\uB809\uD1A0\uB9AC\uC5D0 false\uB97C \uBC18\uD658\uD558\uBA74 \uD574\uB2F9 \uB514\uB809\uD1A0\uB9AC\uC640 \uBAA8\uB4E0 \uD558\uC704 \uD56D\uBAA9\uC774 \uAC74\uB108\uB6F0\uC5B4\uC9D0.\n */\nexport async function fsCopy(\n sourcePath: string,\n targetPath: string,\n filter?: (absolutePath: string) => boolean,\n): Promise<void> {\n if (!(await fsExists(sourcePath))) {\n return;\n }\n\n let stats: fs.Stats;\n try {\n stats = await fs.promises.lstat(sourcePath);\n } catch (err) {\n throw new SdError(err, sourcePath);\n }\n\n if (stats.isDirectory()) {\n await fsMkdir(targetPath);\n\n const children = await fsGlob(path.resolve(sourcePath, \"*\"), { dot: true });\n\n await children.parallelAsync(async (childPath) => {\n if (filter !== undefined && !filter(childPath)) {\n return;\n }\n\n const relativeChildPath = path.relative(sourcePath, childPath);\n const childTargetPath = path.resolve(targetPath, relativeChildPath);\n await fsCopy(childPath, childTargetPath, filter);\n });\n } else {\n await fsMkdir(path.dirname(targetPath));\n\n try {\n await fs.promises.copyFile(sourcePath, targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n }\n}\n\n//#endregion\n\n//#region \uD30C\uC77C \uC77D\uAE30\n\n/**\n * \uD30C\uC77C \uC77D\uAE30 (UTF-8 \uBB38\uC790\uC5F4).\n * @param targetPath - \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C\n */\nexport function fsReadSync(targetPath: string): string {\n try {\n return fs.readFileSync(targetPath, \"utf-8\");\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C \uC77D\uAE30 (UTF-8 \uBB38\uC790\uC5F4, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C\n */\nexport async function fsRead(targetPath: string): Promise<string> {\n try {\n return await fs.promises.readFile(targetPath, \"utf-8\");\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C \uC77D\uAE30 (Buffer).\n * @param targetPath - \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C\n */\nexport function fsReadBufferSync(targetPath: string): Buffer {\n try {\n return fs.readFileSync(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C \uC77D\uAE30 (Buffer, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C\n */\nexport async function fsReadBuffer(targetPath: string): Promise<Buffer> {\n try {\n return await fs.promises.readFile(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * JSON \uD30C\uC77C \uC77D\uAE30 (JsonConvert \uC0AC\uC6A9).\n * @param targetPath - \uC77D\uC744 JSON \uD30C\uC77C \uACBD\uB85C\n */\nexport function fsReadJsonSync<T = unknown>(targetPath: string): T {\n const contents = fsReadSync(targetPath);\n try {\n return jsonParse(contents);\n } catch (err) {\n const preview = contents.length > 500 ? contents.slice(0, 500) + \"...(truncated)\" : contents;\n throw new SdError(err, targetPath + os.EOL + preview);\n }\n}\n\n/**\n * JSON \uD30C\uC77C \uC77D\uAE30 (JsonConvert \uC0AC\uC6A9, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC77D\uC744 JSON \uD30C\uC77C \uACBD\uB85C\n */\nexport async function fsReadJson<T = unknown>(targetPath: string): Promise<T> {\n const contents = await fsRead(targetPath);\n try {\n return jsonParse<T>(contents);\n } catch (err) {\n const preview = contents.length > 500 ? contents.slice(0, 500) + \"...(truncated)\" : contents;\n throw new SdError(err, targetPath + os.EOL + preview);\n }\n}\n\n//#endregion\n\n//#region \uD30C\uC77C \uC4F0\uAE30\n\n/**\n * \uD30C\uC77C \uC4F0\uAE30 (\uBD80\uBAA8 \uB514\uB809\uD1A0\uB9AC \uC790\uB3D9 \uC0DD\uC131).\n * @param targetPath - \uC4F8 \uD30C\uC77C \uACBD\uB85C\n * @param data - \uC4F8 \uB370\uC774\uD130 (\uBB38\uC790\uC5F4 \uB610\uB294 \uBC14\uC774\uB108\uB9AC)\n */\nexport function fsWriteSync(targetPath: string, data: string | Uint8Array): void {\n fsMkdirSync(path.dirname(targetPath));\n\n try {\n fs.writeFileSync(targetPath, data, { flush: true });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C \uC4F0\uAE30 (\uBD80\uBAA8 \uB514\uB809\uD1A0\uB9AC \uC790\uB3D9 \uC0DD\uC131, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC4F8 \uD30C\uC77C \uACBD\uB85C\n * @param data - \uC4F8 \uB370\uC774\uD130 (\uBB38\uC790\uC5F4 \uB610\uB294 \uBC14\uC774\uB108\uB9AC)\n */\nexport async function fsWrite(targetPath: string, data: string | Uint8Array): Promise<void> {\n await fsMkdir(path.dirname(targetPath));\n\n try {\n await fs.promises.writeFile(targetPath, data, { flush: true });\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * JSON \uD30C\uC77C \uC4F0\uAE30 (JsonConvert \uC0AC\uC6A9).\n * @param targetPath - \uC4F8 JSON \uD30C\uC77C \uACBD\uB85C\n * @param data - \uC4F8 \uB370\uC774\uD130\n * @param options - JSON \uC9C1\uB82C\uD654 \uC635\uC158\n */\nexport function fsWriteJsonSync(\n targetPath: string,\n data: unknown,\n options?: {\n replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;\n space?: string | number;\n },\n): void {\n const json = jsonStringify(data, options);\n fsWriteSync(targetPath, json);\n}\n\n/**\n * JSON \uD30C\uC77C \uC4F0\uAE30 (JsonConvert \uC0AC\uC6A9, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC4F8 JSON \uD30C\uC77C \uACBD\uB85C\n * @param data - \uC4F8 \uB370\uC774\uD130\n * @param options - JSON \uC9C1\uB82C\uD654 \uC635\uC158\n */\nexport async function fsWriteJson(\n targetPath: string,\n data: unknown,\n options?: {\n replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;\n space?: string | number;\n },\n): Promise<void> {\n const json = jsonStringify(data, options);\n await fsWrite(targetPath, json);\n}\n\n//#endregion\n\n//#region \uB514\uB809\uD1A0\uB9AC \uC77D\uAE30\n\n/**\n * \uB514\uB809\uD1A0\uB9AC \uB0B4\uC6A9 \uC77D\uAE30.\n * @param targetPath - \uC77D\uC744 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\n */\nexport function fsReaddirSync(targetPath: string): string[] {\n try {\n return fs.readdirSync(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uB514\uB809\uD1A0\uB9AC \uB0B4\uC6A9 \uC77D\uAE30 (\uBE44\uB3D9\uAE30).\n * @param targetPath - \uC77D\uC744 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\n */\nexport async function fsReaddir(targetPath: string): Promise<string[]> {\n try {\n return await fs.promises.readdir(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n//#endregion\n\n//#region \uD30C\uC77C \uC815\uBCF4\n\n/**\n * \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uC815\uBCF4 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C \uB530\uB77C\uAC10).\n * @param targetPath - \uC815\uBCF4\uB97C \uC870\uD68C\uD560 \uACBD\uB85C\n */\nexport function fsStatSync(targetPath: string): fs.Stats {\n try {\n return fs.statSync(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uC815\uBCF4 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C \uB530\uB77C\uAC10, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC815\uBCF4\uB97C \uC870\uD68C\uD560 \uACBD\uB85C\n */\nexport async function fsStat(targetPath: string): Promise<fs.Stats> {\n try {\n return await fs.promises.stat(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uC815\uBCF4 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C \uB530\uB77C\uAC00\uC9C0 \uC54A\uC74C).\n * @param targetPath - \uC815\uBCF4\uB97C \uC870\uD68C\uD560 \uACBD\uB85C\n */\nexport function fsLstatSync(targetPath: string): fs.Stats {\n try {\n return fs.lstatSync(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n/**\n * \uD30C\uC77C/\uB514\uB809\uD1A0\uB9AC \uC815\uBCF4 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C \uB530\uB77C\uAC00\uC9C0 \uC54A\uC74C, \uBE44\uB3D9\uAE30).\n * @param targetPath - \uC815\uBCF4\uB97C \uC870\uD68C\uD560 \uACBD\uB85C\n */\nexport async function fsLstat(targetPath: string): Promise<fs.Stats> {\n try {\n return await fs.promises.lstat(targetPath);\n } catch (err) {\n throw new SdError(err, targetPath);\n }\n}\n\n//#endregion\n\n//#region \uAE00\uB85C\uBE0C\n\n/**\n * \uAE00\uB85C\uBE0C \uD328\uD134\uC73C\uB85C \uD30C\uC77C \uAC80\uC0C9.\n * @param pattern - \uAE00\uB85C\uBE0C \uD328\uD134 (\uC608: \"**\\/*.ts\")\n * @param options - glob \uC635\uC158\n * @returns \uB9E4\uCE6D\uB41C \uD30C\uC77C\uB4E4\uC758 \uC808\uB300 \uACBD\uB85C \uBC30\uC5F4\n */\nexport function fsGlobSync(pattern: string, options?: GlobOptions): string[] {\n return globRawSync(pattern.replace(/\\\\/g, \"/\"), options ?? {}).map((item) => path.resolve(item.toString()));\n}\n\n/**\n * \uAE00\uB85C\uBE0C \uD328\uD134\uC73C\uB85C \uD30C\uC77C \uAC80\uC0C9 (\uBE44\uB3D9\uAE30).\n * @param pattern - \uAE00\uB85C\uBE0C \uD328\uD134 (\uC608: \"**\\/*.ts\")\n * @param options - glob \uC635\uC158\n * @returns \uB9E4\uCE6D\uB41C \uD30C\uC77C\uB4E4\uC758 \uC808\uB300 \uACBD\uB85C \uBC30\uC5F4\n */\nexport async function fsGlob(pattern: string, options?: GlobOptions): Promise<string[]> {\n return (await globRaw(pattern.replace(/\\\\/g, \"/\"), options ?? {})).map((item) => path.resolve(item.toString()));\n}\n\n//#endregion\n\n//#region \uC720\uD2F8\uB9AC\uD2F0\n\n/**\n * \uC9C0\uC815 \uB514\uB809\uD1A0\uB9AC \uD558\uC704\uC758 \uBE48 \uB514\uB809\uD1A0\uB9AC\uB97C \uC7AC\uADC0\uC801\uC73C\uB85C \uD0D0\uC0C9\uD558\uC5EC \uC0AD\uC81C.\n * \uD558\uC704 \uB514\uB809\uD1A0\uB9AC\uAC00 \uBAA8\uB450 \uC0AD\uC81C\uB418\uC5B4 \uBE48 \uB514\uB809\uD1A0\uB9AC\uAC00 \uB41C \uACBD\uC6B0, \uD574\uB2F9 \uB514\uB809\uD1A0\uB9AC\uB3C4 \uC0AD\uC81C \uB300\uC0C1\uC774 \uB428.\n */\nexport async function fsClearEmptyDirectory(dirPath: string): Promise<void> {\n if (!(await fsExists(dirPath))) return;\n\n const childNames = await fsReaddir(dirPath);\n let hasFiles = false;\n\n for (const childName of childNames) {\n const childPath = path.resolve(dirPath, childName);\n if ((await fsLstat(childPath)).isDirectory()) {\n await fsClearEmptyDirectory(childPath);\n } else {\n hasFiles = true;\n }\n }\n\n // \uD30C\uC77C\uC774 \uC788\uC5C8\uB2E4\uBA74 \uC0AD\uC81C \uBD88\uAC00\n if (hasFiles) return;\n\n // \uD30C\uC77C\uC774 \uC5C6\uC5C8\uB358 \uACBD\uC6B0\uC5D0\uB9CC \uC7AC\uD655\uC778 (\uD558\uC704 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC0AD\uC81C\uB418\uC5C8\uC744 \uC218 \uC788\uC74C)\n if ((await fsReaddir(dirPath)).length === 0) {\n await fsRm(dirPath);\n }\n}\n\n/**\n * \uC2DC\uC791 \uACBD\uB85C\uBD80\uD130 \uB8E8\uD2B8 \uBC29\uD5A5\uC73C\uB85C \uC0C1\uC704 \uB514\uB809\uD1A0\uB9AC\uB97C \uC21C\uD68C\uD558\uBA70 glob \uD328\uD134 \uAC80\uC0C9.\n * \uAC01 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C childGlob \uD328\uD134\uC5D0 \uB9E4\uCE6D\uB418\uB294 \uBAA8\uB4E0 \uD30C\uC77C \uACBD\uB85C\uB97C \uC218\uC9D1.\n * @param childGlob - \uAC01 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uAC80\uC0C9\uD560 glob \uD328\uD134\n * @param fromPath - \uAC80\uC0C9 \uC2DC\uC791 \uACBD\uB85C\n * @param rootPath - \uAC80\uC0C9 \uC885\uB8CC \uACBD\uB85C (\uBBF8\uC9C0\uC815 \uC2DC \uD30C\uC77C\uC2DC\uC2A4\uD15C \uB8E8\uD2B8\uAE4C\uC9C0).\n * **\uC8FC\uC758**: fromPath\uAC00 rootPath\uC758 \uC790\uC2DD \uACBD\uB85C\uC5EC\uC57C \uD568.\n * \uADF8\uB807\uC9C0 \uC54A\uC73C\uBA74 \uD30C\uC77C\uC2DC\uC2A4\uD15C \uB8E8\uD2B8\uAE4C\uC9C0 \uAC80\uC0C9\uD568.\n */\nexport function fsFindAllParentChildPathsSync(childGlob: string, fromPath: string, rootPath?: string): string[] {\n const resultPaths: string[] = [];\n\n let current = fromPath;\n while (current) {\n const potential = path.resolve(current, childGlob);\n const globResults = fsGlobSync(potential);\n resultPaths.push(...globResults);\n\n if (current === rootPath) break;\n\n const next = path.dirname(current);\n if (next === current) break;\n current = next;\n }\n\n return resultPaths;\n}\n\n/**\n * \uC2DC\uC791 \uACBD\uB85C\uBD80\uD130 \uB8E8\uD2B8 \uBC29\uD5A5\uC73C\uB85C \uC0C1\uC704 \uB514\uB809\uD1A0\uB9AC\uB97C \uC21C\uD68C\uD558\uBA70 glob \uD328\uD134 \uAC80\uC0C9 (\uBE44\uB3D9\uAE30).\n * \uAC01 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C childGlob \uD328\uD134\uC5D0 \uB9E4\uCE6D\uB418\uB294 \uBAA8\uB4E0 \uD30C\uC77C \uACBD\uB85C\uB97C \uC218\uC9D1.\n * @param childGlob - \uAC01 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uAC80\uC0C9\uD560 glob \uD328\uD134\n * @param fromPath - \uAC80\uC0C9 \uC2DC\uC791 \uACBD\uB85C\n * @param rootPath - \uAC80\uC0C9 \uC885\uB8CC \uACBD\uB85C (\uBBF8\uC9C0\uC815 \uC2DC \uD30C\uC77C\uC2DC\uC2A4\uD15C \uB8E8\uD2B8\uAE4C\uC9C0).\n * **\uC8FC\uC758**: fromPath\uAC00 rootPath\uC758 \uC790\uC2DD \uACBD\uB85C\uC5EC\uC57C \uD568.\n * \uADF8\uB807\uC9C0 \uC54A\uC73C\uBA74 \uD30C\uC77C\uC2DC\uC2A4\uD15C \uB8E8\uD2B8\uAE4C\uC9C0 \uAC80\uC0C9\uD568.\n */\nexport async function fsFindAllParentChildPaths(\n childGlob: string,\n fromPath: string,\n rootPath?: string,\n): Promise<string[]> {\n const resultPaths: string[] = [];\n\n let current = fromPath;\n while (current) {\n const potential = path.resolve(current, childGlob);\n const globResults = await fsGlob(potential);\n resultPaths.push(...globResults);\n\n if (current === rootPath) break;\n\n const next = path.dirname(current);\n if (next === current) break;\n current = next;\n }\n\n return resultPaths;\n}\n\n//#endregion\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,48 @@
1
+ import path from "path";
2
+ import { ArgumentError } from "@simplysm/core-common";
3
+ const NORM = /* @__PURE__ */ Symbol("NormPath");
4
+ function pathPosix(...args) {
5
+ const resolvedPath = path.join(...args);
6
+ return resolvedPath.replace(/\\/g, "/");
7
+ }
8
+ function pathChangeFileDirectory(filePath, fromDirectory, toDirectory) {
9
+ if (filePath === fromDirectory) {
10
+ return toDirectory;
11
+ }
12
+ if (!pathIsChildPath(filePath, fromDirectory)) {
13
+ throw new ArgumentError(`'${filePath}'\uAC00 ${fromDirectory} \uC548\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`, { filePath, fromDirectory });
14
+ }
15
+ return path.resolve(toDirectory, path.relative(fromDirectory, filePath));
16
+ }
17
+ function pathGetBasenameWithoutExt(filePath) {
18
+ return path.basename(filePath, path.extname(filePath));
19
+ }
20
+ function pathIsChildPath(childPath, parentPath) {
21
+ const normalizedChild = pathNorm(childPath);
22
+ const normalizedParent = pathNorm(parentPath);
23
+ if (normalizedChild === normalizedParent) {
24
+ return false;
25
+ }
26
+ const parentWithSep = normalizedParent.endsWith(path.sep) ? normalizedParent : normalizedParent + path.sep;
27
+ return normalizedChild.startsWith(parentWithSep);
28
+ }
29
+ function pathNorm(...paths) {
30
+ return path.resolve(...paths);
31
+ }
32
+ function pathFilterByTargets(files, targets, cwd) {
33
+ if (targets.length === 0) return files;
34
+ const normalizedTargets = targets.map((t) => pathPosix(t));
35
+ return files.filter((file) => {
36
+ const relativePath = pathPosix(path.relative(cwd, file));
37
+ return normalizedTargets.some((target) => relativePath === target || relativePath.startsWith(target + "/"));
38
+ });
39
+ }
40
+ export {
41
+ pathChangeFileDirectory,
42
+ pathFilterByTargets,
43
+ pathGetBasenameWithoutExt,
44
+ pathIsChildPath,
45
+ pathNorm,
46
+ pathPosix
47
+ };
48
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/path.ts"],
4
+ "sourcesContent": ["import path from \"path\";\nimport { ArgumentError } from \"@simplysm/core-common\";\n\n//#region Types\n\nconst NORM = Symbol(\"NormPath\");\n\n/**\n * \uC815\uADDC\uD654\uB41C \uACBD\uB85C\uB97C \uB098\uD0C0\uB0B4\uB294 \uBE0C\uB79C\uB4DC \uD0C0\uC785.\n * pathNorm()\uC744 \uD1B5\uD574\uC11C\uB9CC \uC0DD\uC131 \uAC00\uB2A5.\n */\nexport type NormPath = string & {\n [NORM]: never;\n};\n\n//#endregion\n\n//#region \uD568\uC218\n\n/**\n * POSIX \uC2A4\uD0C0\uC77C \uACBD\uB85C\uB85C \uBCC0\uD658 (\uBC31\uC2AC\uB798\uC2DC \u2192 \uC2AC\uB798\uC2DC).\n *\n * @example\n * pathPosix(\"C:\\\\Users\\\\test\"); // \"C:/Users/test\"\n * pathPosix(\"src\", \"index.ts\"); // \"src/index.ts\"\n */\nexport function pathPosix(...args: string[]): string {\n const resolvedPath = path.join(...args);\n return resolvedPath.replace(/\\\\/g, \"/\");\n}\n\n/**\n * \uD30C\uC77C \uACBD\uB85C\uC758 \uB514\uB809\uD1A0\uB9AC\uB97C \uBCC0\uACBD.\n *\n * @example\n * pathChangeFileDirectory(\"/a/b/c.txt\", \"/a\", \"/x\");\n * // \u2192 \"/x/b/c.txt\"\n *\n * @throws \uD30C\uC77C\uC774 fromDirectory \uC548\uC5D0 \uC5C6\uC73C\uBA74 \uC5D0\uB7EC\n */\nexport function pathChangeFileDirectory(filePath: string, fromDirectory: string, toDirectory: string): string {\n if (filePath === fromDirectory) {\n return toDirectory;\n }\n\n if (!pathIsChildPath(filePath, fromDirectory)) {\n throw new ArgumentError(`'${filePath}'\uAC00 ${fromDirectory} \uC548\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`, { filePath, fromDirectory });\n }\n\n return path.resolve(toDirectory, path.relative(fromDirectory, filePath));\n}\n\n/**\n * \uD655\uC7A5\uC790\uB97C \uC81C\uAC70\uD55C \uD30C\uC77C\uBA85(basename)\uC744 \uBC18\uD658.\n *\n * @example\n * pathGetBasenameWithoutExt(\"file.txt\"); // \"file\"\n * pathGetBasenameWithoutExt(\"/path/to/file.spec.ts\"); // \"file.spec\"\n */\nexport function pathGetBasenameWithoutExt(filePath: string): string {\n return path.basename(filePath, path.extname(filePath));\n}\n\n/**\n * childPath\uAC00 parentPath\uC758 \uC790\uC2DD \uACBD\uB85C\uC778\uC9C0 \uD655\uC778.\n * \uAC19\uC740 \uACBD\uB85C\uB294 false \uBC18\uD658.\n *\n * \uACBD\uB85C\uB294 \uB0B4\uBD80\uC801\uC73C\uB85C `pathNorm()`\uC73C\uB85C \uC815\uADDC\uD654\uB41C \uD6C4 \uBE44\uAD50\uB418\uBA70,\n * \uD50C\uB7AB\uD3FC\uBCC4 \uACBD\uB85C \uAD6C\uBD84\uC790(Windows: `\\`, Unix: `/`)\uB97C \uC0AC\uC6A9\uD55C\uB2E4.\n *\n * @example\n * pathIsChildPath(\"/a/b/c\", \"/a/b\"); // true\n * pathIsChildPath(\"/a/b\", \"/a/b/c\"); // false\n * pathIsChildPath(\"/a/b\", \"/a/b\"); // false (\uAC19\uC740 \uACBD\uB85C)\n */\nexport function pathIsChildPath(childPath: string, parentPath: string): boolean {\n const normalizedChild = pathNorm(childPath);\n const normalizedParent = pathNorm(parentPath);\n\n // \uAC19\uC740 \uACBD\uB85C\uBA74 false\n if (normalizedChild === normalizedParent) {\n return false;\n }\n\n // \uBD80\uBAA8 \uACBD\uB85C + \uAD6C\uBD84\uC790\uB85C \uC2DC\uC791\uD558\uB294\uC9C0 \uD655\uC778\n const parentWithSep = normalizedParent.endsWith(path.sep) ? normalizedParent : normalizedParent + path.sep;\n\n return normalizedChild.startsWith(parentWithSep);\n}\n\n/**\n * \uACBD\uB85C\uB97C \uC815\uADDC\uD654\uD558\uC5EC NormPath\uB85C \uBC18\uD658.\n * \uC808\uB300 \uACBD\uB85C\uB85C \uBCC0\uD658\uB418\uBA70, \uD50C\uB7AB\uD3FC\uBCC4 \uAD6C\uBD84\uC790\uB85C \uC815\uADDC\uD654\uB428.\n *\n * @example\n * pathNorm(\"/some/path\"); // NormPath\n * pathNorm(\"relative\", \"path\"); // NormPath (\uC808\uB300 \uACBD\uB85C\uB85C \uBCC0\uD658)\n */\nexport function pathNorm(...paths: string[]): NormPath {\n return path.resolve(...paths) as NormPath;\n}\n\n/**\n * \uD0C0\uAC9F \uACBD\uB85C \uBAA9\uB85D\uC744 \uAE30\uC900\uC73C\uB85C \uD30C\uC77C\uC744 \uD544\uD130\uB9C1.\n * \uD30C\uC77C\uC774 \uD0C0\uAC9F \uACBD\uB85C\uC640 \uAC19\uAC70\uB098 \uD0C0\uAC9F\uC758 \uC790\uC2DD \uACBD\uB85C\uC77C \uB54C \uD3EC\uD568.\n *\n * @param files - \uD544\uD130\uB9C1\uD560 \uD30C\uC77C \uACBD\uB85C \uBAA9\uB85D.\n * **\uC8FC\uC758**: cwd \uD558\uC704\uC758 \uC808\uB300 \uACBD\uB85C\uC5EC\uC57C \uD568.\n * cwd \uC678\uBD80 \uACBD\uB85C\uB294 \uC0C1\uB300 \uACBD\uB85C(../ \uD615\uD0DC)\uB85C \uBCC0\uD658\uB418\uC5B4 \uCC98\uB9AC\uB428.\n * @param targets - \uD0C0\uAC9F \uACBD\uB85C \uBAA9\uB85D (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C, POSIX \uC2A4\uD0C0\uC77C \uAD8C\uC7A5)\n * @param cwd - \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC (\uC808\uB300 \uACBD\uB85C)\n * @returns targets\uAC00 \uBE48 \uBC30\uC5F4\uC774\uBA74 files \uADF8\uB300\uB85C, \uC544\uB2C8\uBA74 \uD0C0\uAC9F \uACBD\uB85C \uD558\uC704 \uD30C\uC77C\uB9CC\n *\n * @example\n * const files = [\"/proj/src/a.ts\", \"/proj/src/b.ts\", \"/proj/tests/c.ts\"];\n * pathFilterByTargets(files, [\"src\"], \"/proj\");\n * // \u2192 [\"/proj/src/a.ts\", \"/proj/src/b.ts\"]\n */\nexport function pathFilterByTargets(files: string[], targets: string[], cwd: string): string[] {\n if (targets.length === 0) return files;\n const normalizedTargets = targets.map((t) => pathPosix(t));\n return files.filter((file) => {\n const relativePath = pathPosix(path.relative(cwd, file));\n return normalizedTargets.some((target) => relativePath === target || relativePath.startsWith(target + \"/\"));\n });\n}\n\n//#endregion\n"],
5
+ "mappings": "AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAI9B,MAAM,OAAO,uBAAO,UAAU;AAqBvB,SAAS,aAAa,MAAwB;AACnD,QAAM,eAAe,KAAK,KAAK,GAAG,IAAI;AACtC,SAAO,aAAa,QAAQ,OAAO,GAAG;AACxC;AAWO,SAAS,wBAAwB,UAAkB,eAAuB,aAA6B;AAC5G,MAAI,aAAa,eAAe;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,gBAAgB,UAAU,aAAa,GAAG;AAC7C,UAAM,IAAI,cAAc,IAAI,QAAQ,WAAM,aAAa,2CAAa,EAAE,UAAU,cAAc,CAAC;AAAA,EACjG;AAEA,SAAO,KAAK,QAAQ,aAAa,KAAK,SAAS,eAAe,QAAQ,CAAC;AACzE;AASO,SAAS,0BAA0B,UAA0B;AAClE,SAAO,KAAK,SAAS,UAAU,KAAK,QAAQ,QAAQ,CAAC;AACvD;AAcO,SAAS,gBAAgB,WAAmB,YAA6B;AAC9E,QAAM,kBAAkB,SAAS,SAAS;AAC1C,QAAM,mBAAmB,SAAS,UAAU;AAG5C,MAAI,oBAAoB,kBAAkB;AACxC,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB,iBAAiB,SAAS,KAAK,GAAG,IAAI,mBAAmB,mBAAmB,KAAK;AAEvG,SAAO,gBAAgB,WAAW,aAAa;AACjD;AAUO,SAAS,YAAY,OAA2B;AACrD,SAAO,KAAK,QAAQ,GAAG,KAAK;AAC9B;AAkBO,SAAS,oBAAoB,OAAiB,SAAmB,KAAuB;AAC7F,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,oBAAoB,QAAQ,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;AACzD,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,UAAM,eAAe,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AACvD,WAAO,kBAAkB,KAAK,CAAC,WAAW,iBAAiB,UAAU,aAAa,WAAW,SAAS,GAAG,CAAC;AAAA,EAC5G,CAAC;AACH;",
6
+ "names": []
7
+ }
@@ -0,0 +1,85 @@
1
+ import { parentPort } from "worker_threads";
2
+ import { SdError, transferableDecode, transferableEncode } from "@simplysm/core-common";
3
+ function createWorker(methods) {
4
+ if (parentPort === null) {
5
+ throw new SdError("\uC774 \uC2A4\uD06C\uB9BD\uD2B8\uB294 \uC6CC\uCEE4 \uC2A4\uB808\uB4DC\uC5D0\uC11C \uC2E4\uD589\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4 (parentPort \uD544\uC694).");
6
+ }
7
+ const port = parentPort;
8
+ process.stdout.write = (chunk, encodingOrCallback, callback) => {
9
+ const body = typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
10
+ const response = { type: "log", body };
11
+ const serialized = transferableEncode(response);
12
+ port.postMessage(serialized.result, serialized.transferList);
13
+ const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
14
+ if (cb) {
15
+ queueMicrotask(() => cb());
16
+ }
17
+ return true;
18
+ };
19
+ port.on("message", async (serializedRequest) => {
20
+ const decoded = transferableDecode(serializedRequest);
21
+ if (decoded == null || typeof decoded !== "object" || !("id" in decoded) || !("method" in decoded) || !("params" in decoded)) {
22
+ let decodedStr;
23
+ try {
24
+ decodedStr = JSON.stringify(decoded);
25
+ } catch {
26
+ decodedStr = String(decoded);
27
+ }
28
+ const errorResponse = {
29
+ type: "error",
30
+ request: { id: "unknown", method: "unknown", params: [] },
31
+ body: new SdError(`\uD615\uC2DD\uC774 \uC798\uBABB\uB41C \uC6CC\uCEE4 \uC694\uCCAD: ${decodedStr}`)
32
+ };
33
+ const serialized = transferableEncode(errorResponse);
34
+ port.postMessage(serialized.result, serialized.transferList);
35
+ return;
36
+ }
37
+ const request = decoded;
38
+ const methodFn = methods[request.method];
39
+ if (methodFn == null) {
40
+ const response = {
41
+ request,
42
+ type: "error",
43
+ body: new SdError(`\uC54C \uC218 \uC5C6\uB294 \uBA54\uC11C\uB4DC: ${request.method}`)
44
+ };
45
+ const serialized = transferableEncode(response);
46
+ port.postMessage(serialized.result, serialized.transferList);
47
+ return;
48
+ }
49
+ try {
50
+ const result = await methodFn(...request.params);
51
+ const response = {
52
+ request,
53
+ type: "return",
54
+ body: result
55
+ };
56
+ const serialized = transferableEncode(response);
57
+ port.postMessage(serialized.result, serialized.transferList);
58
+ } catch (err) {
59
+ const response = {
60
+ request,
61
+ type: "error",
62
+ body: err instanceof Error ? err : new Error(String(err))
63
+ };
64
+ const serialized = transferableEncode(response);
65
+ port.postMessage(serialized.result, serialized.transferList);
66
+ }
67
+ });
68
+ return {
69
+ __methods: methods,
70
+ __events: {},
71
+ send(event, data) {
72
+ const response = {
73
+ type: "event",
74
+ event,
75
+ body: data
76
+ };
77
+ const serialized = transferableEncode(response);
78
+ port.postMessage(serialized.result, serialized.transferList);
79
+ }
80
+ };
81
+ }
82
+ export {
83
+ createWorker
84
+ };
85
+ //# sourceMappingURL=create-worker.js.map