sonamu 0.11.11 → 0.11.13

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 (44) hide show
  1. package/dist/code-formatting/index.d.ts +8 -0
  2. package/dist/code-formatting/index.d.ts.map +1 -0
  3. package/dist/code-formatting/index.js +27 -0
  4. package/dist/code-formatting/oxfmt.d.ts +5 -0
  5. package/dist/code-formatting/oxfmt.d.ts.map +1 -0
  6. package/dist/code-formatting/oxfmt.js +61 -0
  7. package/dist/code-formatting/oxlint.d.ts +30 -0
  8. package/dist/code-formatting/oxlint.d.ts.map +1 -0
  9. package/dist/code-formatting/oxlint.js +130 -0
  10. package/dist/cone/cone-generator.js +1 -1
  11. package/dist/dict/sonamu-dictionary.js +3 -3
  12. package/dist/entity/entity.d.ts.map +1 -1
  13. package/dist/entity/entity.js +3 -3
  14. package/dist/migration/code-generation.d.ts.map +1 -1
  15. package/dist/migration/code-generation.js +3 -3
  16. package/dist/syncer/code-generator.d.ts.map +1 -1
  17. package/dist/syncer/code-generator.js +3 -3
  18. package/dist/syncer/file-copy.js +3 -3
  19. package/dist/syncer/filesystem-dependencies.js +1 -1
  20. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  21. package/dist/syncer/syncer-actions.js +3 -3
  22. package/dist/template/implementations/sd.template.js +1 -1
  23. package/dist/tooling/cdd-service.js +1 -1
  24. package/dist/ui-web/assets/index-BMdIyKXS.css +1 -0
  25. package/dist/ui-web/assets/{index-C_RUxOdN.js → index-ClxAM2Lk.js} +37 -37
  26. package/dist/ui-web/index.html +2 -2
  27. package/dist/utils/fs-utils.js +3 -3
  28. package/package.json +3 -3
  29. package/src/code-formatting/__tests__/formatter-batching.test.ts +210 -0
  30. package/src/{utils → code-formatting}/__tests__/formatter-bin.test.ts +2 -2
  31. package/src/code-formatting/index.ts +29 -0
  32. package/src/code-formatting/oxfmt.ts +63 -0
  33. package/src/{utils/formatter.ts → code-formatting/oxlint.ts} +67 -95
  34. package/src/dict/sonamu-dictionary.ts +1 -1
  35. package/src/entity/entity.ts +1 -1
  36. package/src/migration/code-generation.ts +1 -1
  37. package/src/syncer/code-generator.ts +1 -1
  38. package/src/syncer/file-copy.ts +1 -1
  39. package/src/syncer/syncer-actions.ts +1 -1
  40. package/src/utils/fs-utils.ts +1 -1
  41. package/dist/ui-web/assets/index-5i4uZVES.css +0 -1
  42. package/dist/utils/formatter.d.ts +0 -14
  43. package/dist/utils/formatter.d.ts.map +0 -1
  44. package/dist/utils/formatter.js +0 -147
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 코드를 프로젝트의 oxfmt + oxlint 설정에 맞춰 포매팅한 문자열을 반환합니다.
3
+ *
4
+ * 캐싱도 있어요 ㅎㅎ 똑같은 입력에 대해서 캐시 커버됩니다.
5
+ * 수명은 프로세스 죽을때까지 ㅋ
6
+ */
7
+ export declare const formatCode: (code: string, filePath: string) => Promise<string>;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-formatting/index.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,eAAO,MAAM,UAAU,qDAGrB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { cached, init_async_utils } from "../utils/async-utils.js";
3
+ import { init_oxfmt, runOxfmt } from "./oxfmt.js";
4
+ import { init_oxlint, runOxlint } from "./oxlint.js";
5
+ import { createHash } from "node:crypto";
6
+ //#region src/code-formatting/index.ts
7
+ /**
8
+ * 캐시 없는 포맷함수 엔트리.
9
+ */
10
+ async function formatCodeInternal(code, filePath) {
11
+ if (filePath.endsWith(".json")) return runOxfmt(code, filePath);
12
+ return runOxfmt(await runOxlint(code), filePath);
13
+ }
14
+ var formatCode;
15
+ var init_code_formatting = __esmMin((() => {
16
+ init_async_utils();
17
+ init_oxfmt();
18
+ init_oxlint();
19
+ formatCode = cached(formatCodeInternal, (code, filePath) => {
20
+ return `${filePath.endsWith(".tsx") ? "tsx" : filePath.endsWith(".json") ? "json" : "ts"}:${createHash("sha1").update(code).digest("hex")}`;
21
+ });
22
+ }));
23
+ //#endregion
24
+ init_code_formatting();
25
+ export { formatCode, init_code_formatting };
26
+
27
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvZGUtZm9ybWF0dGluZy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5cbmltcG9ydCB7IGNhY2hlZCB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgcnVuT3hmbXQgfSBmcm9tIFwiLi9veGZtdFwiO1xuaW1wb3J0IHsgcnVuT3hsaW50IH0gZnJvbSBcIi4vb3hsaW50XCI7XG5cbi8qKlxuICog7L2U65Oc66W8IO2UhOuhnOygne2KuOydmCBveGZtdCArIG94bGludCDshKTsoJXsl5Ag66ee7LawIO2PrOunpO2Mhe2VnCDrrLjsnpDsl7TsnYQg67CY7ZmY7ZWp64uI64ukLlxuICpcbiAqIOy6kOyLseuPhCDsnojslrTsmpQg44WO44WOIOuYkeqwmeydgCDsnoXroKXsl5Ag64yA7ZW07IScIOy6kOyLnCDsu6TrsoTrkKnri4jri6QuXG4gKiDsiJjrqoXsnYAg7ZSE66Gc7IS47IqkIOyjveydhOuVjOq5jOyngCDjhYtcbiAqL1xuZXhwb3J0IGNvbnN0IGZvcm1hdENvZGUgPSBjYWNoZWQoZm9ybWF0Q29kZUludGVybmFsLCAoY29kZSwgZmlsZVBhdGgpID0+IHtcbiAgY29uc3QgZXh0ID0gZmlsZVBhdGguZW5kc1dpdGgoXCIudHN4XCIpID8gXCJ0c3hcIiA6IGZpbGVQYXRoLmVuZHNXaXRoKFwiLmpzb25cIikgPyBcImpzb25cIiA6IFwidHNcIjtcbiAgcmV0dXJuIGAke2V4dH06JHtjcmVhdGVIYXNoKFwic2hhMVwiKS51cGRhdGUoY29kZSkuZGlnZXN0KFwiaGV4XCIpfWA7XG59KTtcblxuLyoqXG4gKiDsupDsi5wg7JeG64qUIO2PrOunt+2VqOyImCDsl5TtirjrpqwuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZvcm1hdENvZGVJbnRlcm5hbChjb2RlOiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAvLyBqc29u7J2AIO2PrOunt+unjCDtlZjrqbQg65Cp64uI64ukLlxuICBpZiAoZmlsZVBhdGguZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgIHJldHVybiBydW5PeGZtdChjb2RlLCBmaWxlUGF0aCk7XG4gIH1cblxuICAvLyDrprDtirgg66i87KCAIO2VnCDri6TsnYzsl5Ag7Y+s66e37Jy866GcIOuniOustOumrO2VtOyalC5cbiAgcmV0dXJuIHJ1bk94Zm10KGF3YWl0IHJ1bk94bGludChjb2RlKSwgZmlsZVBhdGgpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFvQkEsZUFBZSxtQkFBbUIsTUFBYyxVQUFtQztDQUVqRixJQUFJLFNBQVMsU0FBUyxPQUFPLEdBQzNCLE9BQU8sU0FBUyxNQUFNLFFBQVE7Q0FJaEMsT0FBTyxTQUFTLE1BQU0sVUFBVSxJQUFJLEdBQUcsUUFBUTtBQUNqRDs7O2tCQTFCNkM7WUFDWDthQUNFO0NBUXZCLGFBQWEsT0FBTyxxQkFBcUIsTUFBTSxhQUFhO0VBRXZFLE9BQU8sR0FESyxTQUFTLFNBQVMsTUFBTSxJQUFJLFFBQVEsU0FBUyxTQUFTLE9BQU8sSUFBSSxTQUFTLEtBQ3hFLEdBQUcsV0FBVyxNQUFNLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sS0FBSztDQUMvRCxDQUFDIn0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 프로젝트 설정을 찾아서 이에 맞춰서 코드를 포맷합니다.
3
+ */
4
+ export declare function runOxfmt(code: string, filePath: string): Promise<string>;
5
+ //# sourceMappingURL=oxfmt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oxfmt.d.ts","sourceRoot":"","sources":["../../src/code-formatting/oxfmt.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB9E"}
@@ -0,0 +1,61 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { init_controller, isTest } from "../utils/controller.js";
3
+ import { readFile } from "node:fs/promises";
4
+ import path, { dirname, join } from "node:path";
5
+ import { format } from "oxfmt";
6
+ //#region src/code-formatting/oxfmt.ts
7
+ /**
8
+ * 프로젝트 설정을 찾아서 이에 맞춰서 코드를 포맷합니다.
9
+ */
10
+ async function runOxfmt(code, filePath) {
11
+ const result = await format(path.basename(filePath), code, await loadOxfmtConfig());
12
+ const errors = result.errors.filter((e) => e.severity === "Error");
13
+ if (errors.length > 0) {
14
+ if (!isTest()) {
15
+ console.error(`oxfmt errors (${filePath}):`);
16
+ for (const err of errors) {
17
+ const label = err.labels[0];
18
+ if (label) {
19
+ const before = code.slice(Math.max(0, label.start - 80), label.start);
20
+ const at = code.slice(label.start, label.end);
21
+ const after = code.slice(label.end, Math.min(code.length, label.end + 80));
22
+ console.error(` - ${err.message} (offset ${label.start}-${label.end})`);
23
+ console.error(` around: ...${before}»${at}«${after}...`);
24
+ } else console.error(` - ${err.message}`);
25
+ }
26
+ }
27
+ return code;
28
+ }
29
+ return result.code;
30
+ }
31
+ async function loadOxfmtConfig() {
32
+ if (cachedOxfmtConfig !== null) return cachedOxfmtConfig;
33
+ let dir = process.cwd();
34
+ while (true) {
35
+ const candidate = join(dir, ".oxfmtrc.json");
36
+ try {
37
+ cachedOxfmtConfig = JSON.parse(await readFile(candidate, "utf-8"));
38
+ return cachedOxfmtConfig;
39
+ } catch (e) {
40
+ if (e.code !== "ENOENT") {
41
+ !isTest() && console.error(`Failed to load ${candidate}:`, e);
42
+ break;
43
+ }
44
+ }
45
+ const parent = dirname(dir);
46
+ if (parent === dir) break;
47
+ dir = parent;
48
+ }
49
+ cachedOxfmtConfig = {};
50
+ return cachedOxfmtConfig;
51
+ }
52
+ var cachedOxfmtConfig;
53
+ var init_oxfmt = __esmMin((() => {
54
+ init_controller();
55
+ cachedOxfmtConfig = null;
56
+ }));
57
+ //#endregion
58
+ init_oxfmt();
59
+ export { init_oxfmt, runOxfmt };
60
+
61
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3hmbXQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvZGUtZm9ybWF0dGluZy9veGZtdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCwgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5pbXBvcnQgeyBmb3JtYXQsIHR5cGUgRm9ybWF0Q29uZmlnIH0gZnJvbSBcIm94Zm10XCI7XG5cbmltcG9ydCB7IGlzVGVzdCB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5cbi8qKlxuICog7ZSE66Gc7KCd7Yq4IOyEpOygleydhCDssL7slYTshJwg7J207JeQIOunnuy2sOyEnCDsvZTrk5zrpbwg7Y+s66e37ZWp64uI64ukLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuT3hmbXQoY29kZTogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZm9ybWF0KHBhdGguYmFzZW5hbWUoZmlsZVBhdGgpLCBjb2RlLCBhd2FpdCBsb2FkT3hmbXRDb25maWcoKSk7XG5cbiAgY29uc3QgZXJyb3JzID0gcmVzdWx0LmVycm9ycy5maWx0ZXIoKGUpID0+IGUuc2V2ZXJpdHkgPT09IFwiRXJyb3JcIik7XG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIGlmICghaXNUZXN0KCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYG94Zm10IGVycm9ycyAoJHtmaWxlUGF0aH0pOmApO1xuICAgICAgZm9yIChjb25zdCBlcnIgb2YgZXJyb3JzKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gZXJyLmxhYmVsc1swXTtcbiAgICAgICAgaWYgKGxhYmVsKSB7XG4gICAgICAgICAgY29uc3QgYmVmb3JlID0gY29kZS5zbGljZShNYXRoLm1heCgwLCBsYWJlbC5zdGFydCAtIDgwKSwgbGFiZWwuc3RhcnQpO1xuICAgICAgICAgIGNvbnN0IGF0ID0gY29kZS5zbGljZShsYWJlbC5zdGFydCwgbGFiZWwuZW5kKTtcbiAgICAgICAgICBjb25zdCBhZnRlciA9IGNvZGUuc2xpY2UobGFiZWwuZW5kLCBNYXRoLm1pbihjb2RlLmxlbmd0aCwgbGFiZWwuZW5kICsgODApKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGAgIC0gJHtlcnIubWVzc2FnZX0gKG9mZnNldCAke2xhYmVsLnN0YXJ0fS0ke2xhYmVsLmVuZH0pYCk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihgICAgIGFyb3VuZDogLi4uJHtiZWZvcmV9wrske2F0fcKrJHthZnRlcn0uLi5gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGAgIC0gJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29kZTtcbiAgfVxuICByZXR1cm4gcmVzdWx0LmNvZGU7XG59XG5cbmxldCBjYWNoZWRPeGZtdENvbmZpZzogRm9ybWF0Q29uZmlnIHwgbnVsbCA9IG51bGw7XG5hc3luYyBmdW5jdGlvbiBsb2FkT3hmbXRDb25maWcoKTogUHJvbWlzZTxGb3JtYXRDb25maWc+IHtcbiAgaWYgKGNhY2hlZE94Zm10Q29uZmlnICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGNhY2hlZE94Zm10Q29uZmlnO1xuICB9XG5cbiAgbGV0IGRpciA9IHByb2Nlc3MuY3dkKCk7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gam9pbihkaXIsIFwiLm94Zm10cmMuanNvblwiKTtcbiAgICB0cnkge1xuICAgICAgLy8gU0FGRVRZOiDshKDtlokg67aE6riw7JmAIO2VqOyImCDqs4Tslb3snbQg7J20IO2DgOyeheydhCDrs7TsnqXtlanri4jri6QuXG4gICAgICBjYWNoZWRPeGZtdENvbmZpZyA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoY2FuZGlkYXRlLCBcInV0Zi04XCIpKSBhcyBGb3JtYXRDb25maWc7XG4gICAgICByZXR1cm4gY2FjaGVkT3hmbXRDb25maWc7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gU0FGRVRZOiDshKDtlokg67aE6riw7JmAIO2VqOyImCDqs4Tslb3snbQg7J20IO2DgOyeheydhCDrs7TsnqXtlanri4jri6QuXG4gICAgICBpZiAoKGUgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlICE9PSBcIkVOT0VOVFwiKSB7XG4gICAgICAgICFpc1Rlc3QoKSAmJiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gbG9hZCAke2NhbmRpZGF0ZX06YCwgZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBwYXJlbnQgPSBkaXJuYW1lKGRpcik7XG4gICAgaWYgKHBhcmVudCA9PT0gZGlyKSBicmVhaztcbiAgICBkaXIgPSBwYXJlbnQ7XG4gIH1cblxuICBjYWNoZWRPeGZtdENvbmZpZyA9IHt9O1xuICByZXR1cm4gY2FjaGVkT3hmbXRDb25maWc7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVVBLGVBQXNCLFNBQVMsTUFBYyxVQUFtQztDQUM5RSxNQUFNLFNBQVMsTUFBTSxPQUFPLEtBQUssU0FBUyxRQUFRLEdBQUcsTUFBTSxNQUFNLGdCQUFnQixDQUFDO0NBRWxGLE1BQU0sU0FBUyxPQUFPLE9BQU8sUUFBUSxNQUFNLEVBQUUsYUFBYSxPQUFPO0NBQ2pFLElBQUksT0FBTyxTQUFTLEdBQUc7RUFDckIsSUFBSSxDQUFDLE9BQU8sR0FBRztHQUNiLFFBQVEsTUFBTSxpQkFBaUIsU0FBUyxHQUFHO0dBQzNDLEtBQUssTUFBTSxPQUFPLFFBQVE7SUFDeEIsTUFBTSxRQUFRLElBQUksT0FBTztJQUN6QixJQUFJLE9BQU87S0FDVCxNQUFNLFNBQVMsS0FBSyxNQUFNLEtBQUssSUFBSSxHQUFHLE1BQU0sUUFBUSxFQUFFLEdBQUcsTUFBTSxLQUFLO0tBQ3BFLE1BQU0sS0FBSyxLQUFLLE1BQU0sTUFBTSxPQUFPLE1BQU0sR0FBRztLQUM1QyxNQUFNLFFBQVEsS0FBSyxNQUFNLE1BQU0sS0FBSyxLQUFLLElBQUksS0FBSyxRQUFRLE1BQU0sTUFBTSxFQUFFLENBQUM7S0FDekUsUUFBUSxNQUFNLE9BQU8sSUFBSSxRQUFRLFdBQVcsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUU7S0FDdkUsUUFBUSxNQUFNLGtCQUFrQixPQUFPLEdBQUcsR0FBRyxHQUFHLE1BQU0sSUFBSTtJQUM1RCxPQUNFLFFBQVEsTUFBTSxPQUFPLElBQUksU0FBUztHQUV0QztFQUNGO0VBQ0EsT0FBTztDQUNUO0NBQ0EsT0FBTyxPQUFPO0FBQ2hCO0FBR0EsZUFBZSxrQkFBeUM7Q0FDdEQsSUFBSSxzQkFBc0IsTUFDeEIsT0FBTztDQUdULElBQUksTUFBTSxRQUFRLElBQUk7Q0FDdEIsT0FBTyxNQUFNO0VBQ1gsTUFBTSxZQUFZLEtBQUssS0FBSyxlQUFlO0VBQzNDLElBQUk7R0FFRixvQkFBb0IsS0FBSyxNQUFNLE1BQU0sU0FBUyxXQUFXLE9BQU8sQ0FBQztHQUNqRSxPQUFPO0VBQ1QsU0FBUyxHQUFHO0dBRVYsSUFBSyxFQUE0QixTQUFTLFVBQVU7SUFDbEQsQ0FBQyxPQUFPLEtBQUssUUFBUSxNQUFNLGtCQUFrQixVQUFVLElBQUksQ0FBQztJQUM1RDtHQUNGO0VBQ0Y7RUFDQSxNQUFNLFNBQVMsUUFBUSxHQUFHO0VBQzFCLElBQUksV0FBVyxLQUFLO0VBQ3BCLE1BQU07Q0FDUjtDQUVBLG9CQUFvQixDQUFDO0NBQ3JCLE9BQU87QUFDVDs7O2lCQXpENEM7Q0E4QnhDLG9CQUF5QyJ9
@@ -0,0 +1,30 @@
1
+ export type ResolveOxlintBinOptions = {
2
+ resolveModule: (specifier: string) => string;
3
+ readFile: (filePath: string) => Promise<string>;
4
+ access: (filePath: string, mode: number) => Promise<void>;
5
+ };
6
+ /**
7
+ * 프로젝트 설정에 맞춰 코드를 lint합니다.
8
+ *
9
+ * 프로젝트 설정을 적용받는 oxlint cli를 찾아 띄워서,
10
+ * 임시 파일에 in-place로 써서 그 결과를 빼오는 방식으로 작동합니다.
11
+ * 왜 이렇게 하느냐? oxlint가 node api도 안 주고 cli에서 stdin 옵션도 안 주기 때문...
12
+ *
13
+ * 그런데 이 친구는 호출할 때마다 무지성으로 oxlint cli를 돌리지는 않습니다.
14
+ * 그런 식으로 했다가는 oxlint 프로세스만 동시에 수십 개가 떠 있게 될 수도 있어요.
15
+ * 그러다가 sync에서 파일 생성이 10초도 넘게 걸리는 일도 있었습니다.
16
+ * 이를 막기 위해, oxlint가 돌아가고 있을 때에 새 runOxlint 호출이 들어오면 내부에서 알아서 잘 쟁여놨다가 실행 끝나면 배치로 굴립니다.
17
+ * 한 번에 오직 하나의 oxlint cli 실행만 돌아가게 하는 겁니다.
18
+ *
19
+ * 자세한 배칭 전략:
20
+ * - 아무 것도 없을 때에 호출되면 바로 oxlint 실행합니다.
21
+ * - oxlint 실행 중에 들어오면 큐에 쟁여둡니다.
22
+ * - oxlint 실행 완료 시점에서 큐에 뭐가 있으면 그걸로 다음 배치 바로 실행합니다.
23
+ *
24
+ * 그래서 띄엄띄엄 하나씩 들어오면 그냥 순차 실행과 다름이 없고, 여러개 우루루 들어오면 그때 효용이 생깁니다.
25
+ * 다만 동시에 30개가 한번에 들어온다고 30개가 모두 한 배치를 타지는 않고,
26
+ * idle에서의 첫 요청에 즉시 배치를 시작하므로 최소 2배치가 소요된다는 점 주의염.
27
+ */
28
+ export declare function runOxlint(code: string): Promise<string>;
29
+ export declare function resolveOxlintBin(options?: ResolveOxlintBinOptions): Promise<string>;
30
+ //# sourceMappingURL=oxlint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oxlint.d.ts","sourceRoot":"","sources":["../../src/code-formatting/oxlint.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D,CAAC;AAkBF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB7D;AAgDD,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,uBAIR,GACA,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
@@ -0,0 +1,130 @@
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { init_runtime_value, isNumberValue } from "../utils/runtime-value.js";
3
+ import { init_controller, isTest } from "../utils/controller.js";
4
+ import { execute, init_process_utils } from "../utils/process-utils.js";
5
+ import { createRequire } from "node:module";
6
+ import { z } from "zod";
7
+ import { access, readFile, unlink, writeFile } from "node:fs/promises";
8
+ import path, { dirname, join } from "node:path";
9
+ import { constants } from "node:fs";
10
+ //#region src/code-formatting/oxlint.ts
11
+ /**
12
+ * 프로젝트 설정에 맞춰 코드를 lint합니다.
13
+ *
14
+ * 프로젝트 설정을 적용받는 oxlint cli를 찾아 띄워서,
15
+ * 임시 파일에 in-place로 써서 그 결과를 빼오는 방식으로 작동합니다.
16
+ * 왜 이렇게 하느냐? oxlint가 node api도 안 주고 cli에서 stdin 옵션도 안 주기 때문...
17
+ *
18
+ * 그런데 이 친구는 호출할 때마다 무지성으로 oxlint cli를 돌리지는 않습니다.
19
+ * 그런 식으로 했다가는 oxlint 프로세스만 동시에 수십 개가 떠 있게 될 수도 있어요.
20
+ * 그러다가 sync에서 파일 생성이 10초도 넘게 걸리는 일도 있었습니다.
21
+ * 이를 막기 위해, oxlint가 돌아가고 있을 때에 새 runOxlint 호출이 들어오면 내부에서 알아서 잘 쟁여놨다가 실행 끝나면 배치로 굴립니다.
22
+ * 한 번에 오직 하나의 oxlint cli 실행만 돌아가게 하는 겁니다.
23
+ *
24
+ * 자세한 배칭 전략:
25
+ * - 아무 것도 없을 때에 호출되면 바로 oxlint 실행합니다.
26
+ * - oxlint 실행 중에 들어오면 큐에 쟁여둡니다.
27
+ * - oxlint 실행 완료 시점에서 큐에 뭐가 있으면 그걸로 다음 배치 바로 실행합니다.
28
+ *
29
+ * 그래서 띄엄띄엄 하나씩 들어오면 그냥 순차 실행과 다름이 없고, 여러개 우루루 들어오면 그때 효용이 생깁니다.
30
+ * 다만 동시에 30개가 한번에 들어온다고 30개가 모두 한 배치를 타지는 않고,
31
+ * idle에서의 첫 요청에 즉시 배치를 시작하므로 최소 2배치가 소요된다는 점 주의염.
32
+ */
33
+ async function runOxlint(code) {
34
+ if (isTest()) return code;
35
+ const tmpFile = join(process.cwd(), `.sonamu-oxlint-${Date.now()}-${Math.random().toString(36).slice(2)}.ts`);
36
+ try {
37
+ await writeFile(tmpFile, code, "utf-8");
38
+ await enqueueOxlint(tmpFile);
39
+ return await readFile(tmpFile, "utf-8");
40
+ } finally {
41
+ try {
42
+ await unlink(tmpFile);
43
+ } catch {}
44
+ }
45
+ }
46
+ function enqueueOxlint(tmpFile) {
47
+ return new Promise((resolve, reject) => {
48
+ oxlintQueue.push({
49
+ tmpFile,
50
+ resolve,
51
+ reject
52
+ });
53
+ if (!isOxlintRunning) flushOxlintQueue();
54
+ });
55
+ }
56
+ async function flushOxlintQueue() {
57
+ if (isOxlintRunning || oxlintQueue.length === 0) return;
58
+ isOxlintRunning = true;
59
+ const batch = oxlintQueue.splice(0);
60
+ try {
61
+ try {
62
+ await execute(await resolveOxlintBin(), [
63
+ "--fix",
64
+ "--fix-suggestions",
65
+ "--type-aware",
66
+ ...batch.map(({ tmpFile }) => tmpFile)
67
+ ], { timeout: 1e4 });
68
+ } catch (e) {
69
+ const error = e;
70
+ if (!isNumberValue(error.code)) {
71
+ batch.forEach(({ reject }) => reject(error));
72
+ return;
73
+ }
74
+ }
75
+ batch.forEach(({ resolve }) => resolve());
76
+ } finally {
77
+ isOxlintRunning = false;
78
+ if (oxlintQueue.length > 0) flushOxlintQueue();
79
+ }
80
+ }
81
+ async function resolveOxlintBin(options = {
82
+ resolveModule: (specifier) => requireFromHere.resolve(specifier),
83
+ readFile: (filePath) => readFile(filePath, "utf-8"),
84
+ access: (filePath, mode) => access(filePath, mode)
85
+ }) {
86
+ let manifestPath;
87
+ try {
88
+ manifestPath = options.resolveModule("oxlint/package.json");
89
+ } catch {
90
+ throw createOxlintBinResolutionError("oxlint package.json을 찾을 수 없습니다. oxlint 의존성을 설치한 뒤 다시 시도해 주세요.");
91
+ }
92
+ let manifest;
93
+ try {
94
+ manifest = JSON.parse(await options.readFile(manifestPath));
95
+ } catch {
96
+ throw createOxlintBinResolutionError("oxlint package.json을 읽거나 해석할 수 없습니다. 패키지를 다시 설치한 뒤 시도해 주세요.");
97
+ }
98
+ const stringBinManifest = OxlintStringBinManifestSchema.safeParse(manifest);
99
+ const namedBinManifest = OxlintNamedBinManifestSchema.safeParse(manifest);
100
+ let bin = null;
101
+ if (stringBinManifest.success) bin = stringBinManifest.data.bin;
102
+ else if (namedBinManifest.success) bin = namedBinManifest.data.bin.oxlint;
103
+ if (bin === null) throw createOxlintBinResolutionError("oxlint package.json의 bin 필드가 없거나 올바르지 않습니다. 호환되는 oxlint 패키지를 설치해 주세요.");
104
+ const binPath = path.resolve(dirname(manifestPath), bin);
105
+ try {
106
+ await options.access(binPath, constants.F_OK | constants.X_OK);
107
+ } catch {
108
+ throw createOxlintBinResolutionError("oxlint package.json의 bin 실행 파일이 없거나 실행할 수 없습니다. 패키지를 다시 설치해 주세요.");
109
+ }
110
+ return binPath;
111
+ }
112
+ function createOxlintBinResolutionError(message) {
113
+ return Object.assign(new Error(message), { code: "OXLINT_BIN_RESOLUTION_FAILED" });
114
+ }
115
+ var requireFromHere, OxlintStringBinManifestSchema, OxlintNamedBinManifestSchema, oxlintQueue, isOxlintRunning;
116
+ var init_oxlint = __esmMin((() => {
117
+ init_controller();
118
+ init_process_utils();
119
+ init_runtime_value();
120
+ requireFromHere = createRequire(import.meta.url);
121
+ OxlintStringBinManifestSchema = z.object({ bin: z.string().trim().min(1) });
122
+ OxlintNamedBinManifestSchema = z.object({ bin: z.object({ oxlint: z.string().trim().min(1) }) });
123
+ oxlintQueue = [];
124
+ isOxlintRunning = false;
125
+ }));
126
+ //#endregion
127
+ init_oxlint();
128
+ export { init_oxlint, resolveOxlintBin, runOxlint };
129
+
130
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3hsaW50LmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2RlLWZvcm1hdHRpbmcvb3hsaW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIO2FjOyKpO2KuCDtmZjqsr3sl5DshJzripQgZnMvcHJvbWlzZXPqsIAgbW9ja+uQmOyngOunjCwg7JWE656YIHJ1bk94bGludOydtCBpc1Rlc3Qg6rCA65Oc66GcIOyViCDrj4Tri4jquYxcbi8vIOq3uOuDpSBmcy9wcm9taXNlcyDqt7jrjIDroZwg7IKs7JqpLiAocHJvZHVjdGlvbuyXkOyEnOunjCDsnoTsi5ztjIzsnbwg7Z2Q66aE7J20IOuPleuLiOuLpC4pXG5pbXBvcnQgeyBjb25zdGFudHMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgYWNjZXNzLCByZWFkRmlsZSwgdW5saW5rLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHBhdGgsIHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgaXNUZXN0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIjtcbmltcG9ydCB7IGV4ZWN1dGUgfSBmcm9tIFwiLi4vdXRpbHMvcHJvY2Vzcy11dGlsc1wiO1xuaW1wb3J0IHsgaXNOdW1iZXJWYWx1ZSB9IGZyb20gXCIuLi91dGlscy9ydW50aW1lLXZhbHVlXCI7XG5cbmNvbnN0IHJlcXVpcmVGcm9tSGVyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcblxuZXhwb3J0IHR5cGUgUmVzb2x2ZU94bGludEJpbk9wdGlvbnMgPSB7XG4gIHJlc29sdmVNb2R1bGU6IChzcGVjaWZpZXI6IHN0cmluZykgPT4gc3RyaW5nO1xuICByZWFkRmlsZTogKGZpbGVQYXRoOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nPjtcbiAgYWNjZXNzOiAoZmlsZVBhdGg6IHN0cmluZywgbW9kZTogbnVtYmVyKSA9PiBQcm9taXNlPHZvaWQ+O1xufTtcblxuY29uc3QgT3hsaW50U3RyaW5nQmluTWFuaWZlc3RTY2hlbWEgPSB6Lm9iamVjdCh7IGJpbjogei5zdHJpbmcoKS50cmltKCkubWluKDEpIH0pO1xuY29uc3QgT3hsaW50TmFtZWRCaW5NYW5pZmVzdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgYmluOiB6Lm9iamVjdCh7IG94bGludDogei5zdHJpbmcoKS50cmltKCkubWluKDEpIH0pLFxufSk7XG5cbnR5cGUgT3hsaW50UmVxdWVzdCA9IHtcbiAgdG1wRmlsZTogc3RyaW5nO1xuICByZXNvbHZlOiAoKSA9PiB2b2lkO1xuICByZWplY3Q6IChlcnJvcjogT3hsaW50RXJyb3IpID0+IHZvaWQ7XG59O1xuXG50eXBlIE94bGludEVycm9yID0gRXJyb3IgJiB7IGNvZGU/OiBzdHJpbmcgfCBudW1iZXIgfCBudWxsIH07XG5cbmNvbnN0IG94bGludFF1ZXVlOiBPeGxpbnRSZXF1ZXN0W10gPSBbXTtcbmxldCBpc094bGludFJ1bm5pbmcgPSBmYWxzZTtcblxuLyoqXG4gKiDtlITroZzsoJ3tirgg7ISk7KCV7JeQIOunnuy2sCDsvZTrk5zrpbwgbGludO2VqeuLiOuLpC5cbiAqXG4gKiDtlITroZzsoJ3tirgg7ISk7KCV7J2EIOyggeyaqeuwm+uKlCBveGxpbnQgY2xp66W8IOywvuyVhCDrnYTsm4zshJwsXG4gKiDsnoTsi5wg7YyM7J287JeQIGluLXBsYWNl66GcIOyNqOyEnCDqt7gg6rKw6rO866W8IOu5vOyYpOuKlCDrsKnsi53snLzroZwg7J6R64+Z7ZWp64uI64ukLlxuICog7JmcIOydtOugh+qyjCDtlZjripDrg5A/IG94bGludOqwgCBub2RlIGFwaeuPhCDslYgg7KO86rOgIGNsaeyXkOyEnCBzdGRpbiDsmLXshZjrj4Qg7JWIIOyjvOq4sCDrlYzrrLguLi5cbiAqXG4gKiDqt7jrn7DrjbAg7J20IOy5nOq1rOuKlCDtmLjstpztlaAg65WM66eI64ukIOustOyngOyEseycvOuhnCBveGxpbnQgY2xp66W8IOuPjOumrOyngOuKlCDslYrsirXri4jri6QuXG4gKiDqt7jrn7Ag7Iud7Jy866GcIO2WiOuLpOqwgOuKlCBveGxpbnQg7ZSE66Gc7IS47Iqk66eMIOuPmeyLnOyXkCDsiJjsi60g6rCc6rCAIOuWoCDsnojqsowg65CgIOyImOuPhCDsnojslrTsmpQuXG4gKiDqt7jrn6zri6TqsIAgc3luY+yXkOyEnCDtjIzsnbwg7IOd7ISx7J20IDEw7LSI64+EIOuEmOqyjCDqsbjrpqzripQg7J2864+EIOyeiOyXiOyKteuLiOuLpC5cbiAqIOydtOulvCDrp4nquLAg7JyE7ZW0LCBveGxpbnTqsIAg64+M7JWE6rCA6rOgIOyeiOydhCDrlYzsl5Ag7IOIIHJ1bk94bGludCDtmLjstpzsnbQg65Ok7Ja07Jik66m0IOuCtOu2gOyXkOyEnCDslYzslYTshJwg7J6YIOyfgeyXrOuGqOuLpOqwgCDsi6Ttlokg64Gd64KY66m0IOuwsOy5mOuhnCDqtbTrpr3ri4jri6QuXG4gKiDtlZwg67KI7JeQIOyYpOyngSDtlZjrgpjsnZggb3hsaW50IGNsaSDsi6Ttlonrp4wg64+M7JWE6rCA6rKMIO2VmOuKlCDqsoHri4jri6QuXG4gKlxuICog7J6Q7IS47ZWcIOuwsOy5rSDsoITrnrU6XG4gKiAtIOyVhOustCDqsoPrj4Qg7JeG7J2EIOuVjOyXkCDtmLjstpzrkJjrqbQg67CU66GcIG94bGludCDsi6Ttlontlanri4jri6QuXG4gKiAtIG94bGludCDsi6Ttlokg7KSR7JeQIOuTpOyWtOyYpOuptCDtgZDsl5Ag7J+B7Jes65Gh64uI64ukLlxuICogLSBveGxpbnQg7Iuk7ZaJIOyZhOujjCDsi5zsoJDsl5DshJwg7YGQ7JeQIOutkOqwgCDsnojsnLzrqbQg6re46rG466GcIOuLpOydjCDrsLDsuZgg67CU66GcIOyLpO2Wie2VqeuLiOuLpC5cbiAqXG4gKiDqt7jrnpjshJwg652E7JeE652E7JeEIO2VmOuCmOyUqSDrk6TslrTsmKTrqbQg6re464OlIOyInOywqCDsi6Ttlonqs7wg64uk66aE7J20IOyXhuqzoCwg7Jes65+s6rCcIOyasOujqOujqCDrk6TslrTsmKTrqbQg6re465WMIO2aqOyaqeydtCDsg53quYHri4jri6QuXG4gKiDri6Trp4wg64+Z7Iuc7JeQIDMw6rCc6rCAIO2VnOuyiOyXkCDrk6TslrTsmKjri6Tqs6AgMzDqsJzqsIAg66qo65GQIO2VnCDrsLDsuZjrpbwg7YOA7KeA64qUIOyViuqzoCxcbiAqIGlkbGXsl5DshJzsnZgg7LKrIOyalOyyreyXkCDsponsi5wg67Cw7LmY66W8IOyLnOyeke2VmOuvgOuhnCDstZzshowgMuuwsOy5mOqwgCDshozsmpTrkJzri6TripQg7KCQIOyjvOydmOyXvC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bk94bGludChjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoaXNUZXN0KCkpIHtcbiAgICAvLyDthYzsiqTtirgg7ZmY6rK97JeQ7ISc64qUIOuKkOugpOyngOq4sOunjCDtlZjqs6Ag6rKA7Kad7ZWgIOqwgOy5mOuPhCDsl4bslrTshJwg7JWIIO2VqeuLiOuLpC5cbiAgICAvLyBHaXRIdWIgQWN0aW9ucyDtmZjqsr3sl5DshJwgbGludOqwgCDsmKTrnpgg6rG466Ck7IScIOu7l+q4sOuPhCDtlojslrTsmpQuIChodHRwczovL2dpdGh1Yi5jb20vY2FydGFub3ZhLWFpL3NvbmFtdS9hY3Rpb25zL3J1bnMvMjUyNjcyMTQwMjcvam9iLzc0MDgzNjMwMTY5KVxuICAgIHJldHVybiBjb2RlO1xuICB9XG5cbiAgY29uc3QgdG1wRmlsZSA9IGpvaW4oXG4gICAgLy8g7YOA6rKfIO2MjOydvOydtCDro6jtirgg7JWE656Y7JeQIOyeiOyWtOyVvCDtlbTsmpQuIOq3uOuemOyEnCB0bXAg65SU66CJ7Yag66as6rCZ7J2A6rGwIOyViCDslIHri4jri6QhXG4gICAgcHJvY2Vzcy5jd2QoKSxcbiAgICBgLnNvbmFtdS1veGxpbnQtJHtEYXRlLm5vdygpfS0ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpfS50c2AsXG4gICk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB3cml0ZUZpbGUodG1wRmlsZSwgY29kZSwgXCJ1dGYtOFwiKTtcbiAgICBhd2FpdCBlbnF1ZXVlT3hsaW50KHRtcEZpbGUpO1xuICAgIHJldHVybiBhd2FpdCByZWFkRmlsZSh0bXBGaWxlLCBcInV0Zi04XCIpO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB1bmxpbmsodG1wRmlsZSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyDsgq3soJwg7Iuk7Yyo7ZW064+EIOyWtOywqO2UvCBpZ25vcmXrkKguXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGVucXVldWVPeGxpbnQodG1wRmlsZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgb3hsaW50UXVldWUucHVzaCh7IHRtcEZpbGUsIHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICBpZiAoIWlzT3hsaW50UnVubmluZykge1xuICAgICAgdm9pZCBmbHVzaE94bGludFF1ZXVlKCk7XG4gICAgfVxuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmx1c2hPeGxpbnRRdWV1ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGlzT3hsaW50UnVubmluZyB8fCBveGxpbnRRdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpc094bGludFJ1bm5pbmcgPSB0cnVlO1xuICAvLyDsi6TtlonsnYQg7Iuc7J6R7ZWgIOuVjOq5jOyngCDspIDruYTrkJwg7YyM7J2866eMIOustuyWtCDri6TsnYwg7JqU7LKt7J2AIO2bhOyGjSDrsLDsuZjroZwg64SY6rmB64uI64ukLlxuICBjb25zdCBiYXRjaCA9IG94bGludFF1ZXVlLnNwbGljZSgwKTtcblxuICB0cnkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjdXRlKFxuICAgICAgICBhd2FpdCByZXNvbHZlT3hsaW50QmluKCksXG4gICAgICAgIFtcIi0tZml4XCIsIFwiLS1maXgtc3VnZ2VzdGlvbnNcIiwgXCItLXR5cGUtYXdhcmVcIiwgLi4uYmF0Y2gubWFwKCh7IHRtcEZpbGUgfSkgPT4gdG1wRmlsZSldLFxuICAgICAgICB7XG4gICAgICAgICAgdGltZW91dDogMTAwMDAsXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGxpbnQg7JyE67CYIOyLnCBleGl0IGNvZGUgIT0gMOydtOyngOunjCAtLWZpeOuKlCDsoIHsmqnrkKguIGV4ZWMg7J6Q7LK0IOyLpO2MqOunjCDrsLDsuZgg7KCE7LK07JeQIOyghOuLrO2VqeuLiOuLpC5cbiAgICAgIC8vIFNBRkVUWTog7ISg7ZaJIOu2hOq4sOyZgCDtlajsiJgg6rOE7JW97J20IOydtCDtg4DsnoXsnYQg67O07J6l7ZWp64uI64ukLlxuICAgICAgY29uc3QgZXJyb3IgPSBlIGFzIE94bGludEVycm9yO1xuICAgICAgaWYgKCFpc051bWJlclZhbHVlKGVycm9yLmNvZGUpKSB7XG4gICAgICAgIGJhdGNoLmZvckVhY2goKHsgcmVqZWN0IH0pID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgYmF0Y2guZm9yRWFjaCgoeyByZXNvbHZlIH0pID0+IHJlc29sdmUoKSk7XG4gIH0gZmluYWxseSB7XG4gICAgaXNPeGxpbnRSdW5uaW5nID0gZmFsc2U7XG4gICAgaWYgKG94bGludFF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgZmx1c2hPeGxpbnRRdWV1ZSgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU94bGludEJpbihcbiAgb3B0aW9uczogUmVzb2x2ZU94bGludEJpbk9wdGlvbnMgPSB7XG4gICAgcmVzb2x2ZU1vZHVsZTogKHNwZWNpZmllcikgPT4gcmVxdWlyZUZyb21IZXJlLnJlc29sdmUoc3BlY2lmaWVyKSxcbiAgICByZWFkRmlsZTogKGZpbGVQYXRoKSA9PiByZWFkRmlsZShmaWxlUGF0aCwgXCJ1dGYtOFwiKSxcbiAgICBhY2Nlc3M6IChmaWxlUGF0aCwgbW9kZSkgPT4gYWNjZXNzKGZpbGVQYXRoLCBtb2RlKSxcbiAgfSxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBtYW5pZmVzdFBhdGg6IHN0cmluZztcbiAgdHJ5IHtcbiAgICBtYW5pZmVzdFBhdGggPSBvcHRpb25zLnJlc29sdmVNb2R1bGUoXCJveGxpbnQvcGFja2FnZS5qc29uXCIpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBjcmVhdGVPeGxpbnRCaW5SZXNvbHV0aW9uRXJyb3IoXG4gICAgICBcIm94bGludCBwYWNrYWdlLmpzb27snYQg7LC+7J2EIOyImCDsl4bsirXri4jri6QuIG94bGludCDsnZjsobTshLHsnYQg7ISk7LmY7ZWcIOuSpCDri6Tsi5wg7Iuc64+E7ZW0IOyjvOyEuOyalC5cIixcbiAgICApO1xuICB9XG5cbiAgbGV0IG1hbmlmZXN0OiB1bmtub3duO1xuICB0cnkge1xuICAgIG1hbmlmZXN0ID0gSlNPTi5wYXJzZShhd2FpdCBvcHRpb25zLnJlYWRGaWxlKG1hbmlmZXN0UGF0aCkpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBjcmVhdGVPeGxpbnRCaW5SZXNvbHV0aW9uRXJyb3IoXG4gICAgICBcIm94bGludCBwYWNrYWdlLmpzb27snYQg7J296rGw64KYIO2VtOyEne2VoCDsiJgg7JeG7Iq164uI64ukLiDtjKjtgqTsp4Drpbwg64uk7IucIOyEpOy5mO2VnCDrkqQg7Iuc64+E7ZW0IOyjvOyEuOyalC5cIixcbiAgICApO1xuICB9XG5cbiAgLy8gbnBt7J2YIGJpbuydgCDri6jsnbwg7Iuk7ZaJIO2MjOydvCDrrLjsnpDsl7Tqs7wg66qF66C5IOydtOumhOuzhCDqsJ3ssrTrpbwg66qo65GQIO2XiOyaqe2VqeuLiOuLpC5cbiAgY29uc3Qgc3RyaW5nQmluTWFuaWZlc3QgPSBPeGxpbnRTdHJpbmdCaW5NYW5pZmVzdFNjaGVtYS5zYWZlUGFyc2UobWFuaWZlc3QpO1xuICBjb25zdCBuYW1lZEJpbk1hbmlmZXN0ID0gT3hsaW50TmFtZWRCaW5NYW5pZmVzdFNjaGVtYS5zYWZlUGFyc2UobWFuaWZlc3QpO1xuICBsZXQgYmluOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgaWYgKHN0cmluZ0Jpbk1hbmlmZXN0LnN1Y2Nlc3MpIHtcbiAgICBiaW4gPSBzdHJpbmdCaW5NYW5pZmVzdC5kYXRhLmJpbjtcbiAgfSBlbHNlIGlmIChuYW1lZEJpbk1hbmlmZXN0LnN1Y2Nlc3MpIHtcbiAgICBiaW4gPSBuYW1lZEJpbk1hbmlmZXN0LmRhdGEuYmluLm94bGludDtcbiAgfVxuICBpZiAoYmluID09PSBudWxsKSB7XG4gICAgdGhyb3cgY3JlYXRlT3hsaW50QmluUmVzb2x1dGlvbkVycm9yKFxuICAgICAgXCJveGxpbnQgcGFja2FnZS5qc29u7J2YIGJpbiDtlYTrk5zqsIAg7JeG6rGw64KYIOyYrOuwlOultOyngCDslYrsirXri4jri6QuIO2YuO2ZmOuQmOuKlCBveGxpbnQg7Yyo7YKk7KeA66W8IOyEpOy5mO2VtCDso7zshLjsmpQuXCIsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGJpblBhdGggPSBwYXRoLnJlc29sdmUoZGlybmFtZShtYW5pZmVzdFBhdGgpLCBiaW4pO1xuICB0cnkge1xuICAgIGF3YWl0IG9wdGlvbnMuYWNjZXNzKGJpblBhdGgsIGNvbnN0YW50cy5GX09LIHwgY29uc3RhbnRzLlhfT0spO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBjcmVhdGVPeGxpbnRCaW5SZXNvbHV0aW9uRXJyb3IoXG4gICAgICBcIm94bGludCBwYWNrYWdlLmpzb27snZggYmluIOyLpO2WiSDtjIzsnbzsnbQg7JeG6rGw64KYIOyLpO2Wie2VoCDsiJgg7JeG7Iq164uI64ukLiDtjKjtgqTsp4Drpbwg64uk7IucIOyEpOy5mO2VtCDso7zshLjsmpQuXCIsXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBiaW5QYXRoO1xufVxuZnVuY3Rpb24gY3JlYXRlT3hsaW50QmluUmVzb2x1dGlvbkVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IE5vZGVKUy5FcnJub0V4Y2VwdGlvbiB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihtZXNzYWdlKSwgeyBjb2RlOiBcIk9YTElOVF9CSU5fUkVTT0xVVElPTl9GQUlMRURcIiB9KTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEyREEsZUFBc0IsVUFBVSxNQUErQjtDQUM3RCxJQUFJLE9BQU8sR0FHVCxPQUFPO0NBR1QsTUFBTSxVQUFVLEtBRWQsUUFBUSxJQUFJLEdBQ1osa0JBQWtCLEtBQUssSUFBSSxFQUFFLEdBQUcsS0FBSyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQ3RFO0NBRUEsSUFBSTtFQUNGLE1BQU0sVUFBVSxTQUFTLE1BQU0sT0FBTztFQUN0QyxNQUFNLGNBQWMsT0FBTztFQUMzQixPQUFPLE1BQU0sU0FBUyxTQUFTLE9BQU87Q0FDeEMsVUFBVTtFQUNSLElBQUk7R0FDRixNQUFNLE9BQU8sT0FBTztFQUN0QixRQUFRLENBRVI7Q0FDRjtBQUNGO0FBRUEsU0FBUyxjQUFjLFNBQWdDO0NBQ3JELE9BQU8sSUFBSSxTQUFTLFNBQVMsV0FBVztFQUN0QyxZQUFZLEtBQUs7R0FBRTtHQUFTO0dBQVM7RUFBTyxDQUFDO0VBQzdDLElBQUksQ0FBQyxpQkFDSCxBQUFLLGlCQUFpQjtDQUUxQixDQUFDO0FBQ0g7QUFFQSxlQUFlLG1CQUFrQztDQUMvQyxJQUFJLG1CQUFtQixZQUFZLFdBQVcsR0FDNUM7Q0FHRixrQkFBa0I7Q0FFbEIsTUFBTSxRQUFRLFlBQVksT0FBTyxDQUFDO0NBRWxDLElBQUk7RUFDRixJQUFJO0dBQ0YsTUFBTSxRQUNKLE1BQU0saUJBQWlCLEdBQ3ZCO0lBQUM7SUFBUztJQUFxQjtJQUFnQixHQUFHLE1BQU0sS0FBSyxFQUFFLGNBQWMsT0FBTztHQUFDLEdBQ3JGLEVBQ0UsU0FBUyxJQUNYLENBQ0Y7RUFDRixTQUFTLEdBQUc7R0FHVixNQUFNLFFBQVE7R0FDZCxJQUFJLENBQUMsY0FBYyxNQUFNLElBQUksR0FBRztJQUM5QixNQUFNLFNBQVMsRUFBRSxhQUFhLE9BQU8sS0FBSyxDQUFDO0lBQzNDO0dBQ0Y7RUFDRjtFQUVBLE1BQU0sU0FBUyxFQUFFLGNBQWMsUUFBUSxDQUFDO0NBQzFDLFVBQVU7RUFDUixrQkFBa0I7RUFDbEIsSUFBSSxZQUFZLFNBQVMsR0FDdkIsQUFBSyxpQkFBaUI7Q0FFMUI7QUFDRjtBQUVBLGVBQXNCLGlCQUNwQixVQUFtQztDQUNqQyxnQkFBZ0IsY0FBYyxnQkFBZ0IsUUFBUSxTQUFTO0NBQy9ELFdBQVcsYUFBYSxTQUFTLFVBQVUsT0FBTztDQUNsRCxTQUFTLFVBQVUsU0FBUyxPQUFPLFVBQVUsSUFBSTtBQUNuRCxHQUNpQjtDQUNqQixJQUFJO0NBQ0osSUFBSTtFQUNGLGVBQWUsUUFBUSxjQUFjLHFCQUFxQjtDQUM1RCxRQUFRO0VBQ04sTUFBTSwrQkFDSiwrREFDRjtDQUNGO0NBRUEsSUFBSTtDQUNKLElBQUk7RUFDRixXQUFXLEtBQUssTUFBTSxNQUFNLFFBQVEsU0FBUyxZQUFZLENBQUM7Q0FDNUQsUUFBUTtFQUNOLE1BQU0sK0JBQ0osNkRBQ0Y7Q0FDRjtDQUdBLE1BQU0sb0JBQW9CLDhCQUE4QixVQUFVLFFBQVE7Q0FDMUUsTUFBTSxtQkFBbUIsNkJBQTZCLFVBQVUsUUFBUTtDQUN4RSxJQUFJLE1BQXFCO0NBQ3pCLElBQUksa0JBQWtCLFNBQ3BCLE1BQU0sa0JBQWtCLEtBQUs7TUFDeEIsSUFBSSxpQkFBaUIsU0FDMUIsTUFBTSxpQkFBaUIsS0FBSyxJQUFJO0NBRWxDLElBQUksUUFBUSxNQUNWLE1BQU0sK0JBQ0osdUVBQ0Y7Q0FHRixNQUFNLFVBQVUsS0FBSyxRQUFRLFFBQVEsWUFBWSxHQUFHLEdBQUc7Q0FDdkQsSUFBSTtFQUNGLE1BQU0sUUFBUSxPQUFPLFNBQVMsVUFBVSxPQUFPLFVBQVUsSUFBSTtDQUMvRCxRQUFRO0VBQ04sTUFBTSwrQkFDSixrRUFDRjtDQUNGO0NBRUEsT0FBTztBQUNUO0FBQ0EsU0FBUywrQkFBK0IsU0FBd0M7Q0FDOUUsT0FBTyxPQUFPLE9BQU8sSUFBSSxNQUFNLE9BQU8sR0FBRyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkY7OztpQkEvSzRDO29CQUNJO29CQUNNO0NBRWhELGtCQUFrQixjQUFjLE9BQU8sS0FBSyxHQUFHO0NBUS9DLGdDQUFnQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztDQUMxRSwrQkFBK0IsRUFBRSxPQUFPLEVBQzVDLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFDcEQsQ0FBQztDQVVLLGNBQStCLENBQUM7Q0FDbEMsa0JBQWtCIn0=
@@ -1,8 +1,8 @@
1
1
  import { __esmMin, __toCommonJS } from "../_virtual/_rolldown/runtime.js";
2
2
  import { init_runtime_value, isObjectValue } from "../utils/runtime-value.js";
3
3
  import { api_exports, init_api } from "../api/index.js";
4
- import * as fs$1 from "node:fs";
5
4
  import * as path$1 from "node:path";
5
+ import * as fs$1 from "node:fs";
6
6
  //#region src/cone/cone-generator.ts
7
7
  /**
8
8
  * LLM을 사용하여 Entity의 cone 메타데이터를 생성합니다.