From fdd93cdb2dbb170aff9147c4735aa7816336211d Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 21 Oct 2026 17:24:27 +0900 Subject: [PATCH] =?UTF-8?q?test(508-1b=20=EC=98=9B=20=ED=97=AC=ED=8D=BC=20?= =?UTF-8?q?=EA=B3=B5=EC=9A=A9=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=206/7?= =?UTF-8?q?):=20=ED=97=AC=ED=8D=BC=2028=20=EA=B3=B3=20`loadTs`=20=EB=B2=A0?= =?UTF-8?q?=EB=82=8C=20=EA=B1=B7=EA=B3=A0=20`makeLoader`=20=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 헬퍼 동작 그대로(풀이 함수 본문은 옮겨 담음) · 제품 코드 안 고침 - 확인: 이 묶음 헬퍼를 쓰는 시험 428 개 전 417 통과 → 후 417 통과 (시험별 junit 대조 · 어긋남 0) Co-Authored-By: Claude Sonnet 5.5 --- .../tester/helper_54_14_balloon_lines.cjs | 22 ++++--------- .../tester/helper_54_27_soil_tier_field.cjs | 22 ++++--------- resources/tester/helper_73_4_body_guard.cjs | 32 ++++--------------- resources/tester/helper_79_guard_shape.cjs | 32 ++++--------------- resources/tester/helper_80_ford_pipe.cjs | 32 ++++--------------- resources/tester/helper_90_chute_band.cjs | 19 +++-------- resources/tester/helper_91_ground_free.cjs | 32 ++++--------------- resources/tester/helper_b05_b06_selection.cjs | 22 ++++--------- .../tester/helper_b05_curve_radius_floor.cjs | 22 ++++--------- .../helper_b05_routeedit_cross_width.cjs | 22 ++++--------- .../tester/helper_b05_routeedit_initial.cjs | 22 ++++--------- .../helper_b05_routeedit_initial_apply.cjs | 22 ++++--------- .../tester/helper_b05_routeedit_lock.cjs | 24 ++++---------- .../tester/helper_b05_routeedit_pick.cjs | 22 ++++--------- .../tester/helper_b05_routeedit_view.cjs | 22 ++++--------- .../tester/helper_b05_station_roundtrip.cjs | 22 ++++--------- .../helper_b05_structures_form_summary.cjs | 22 ++++--------- .../tester/helper_b06_adjust_single_form.cjs | 21 ++++-------- .../tester/helper_b06_draft_pipe_replay.cjs | 22 ++++--------- .../tester/helper_design_profile_single.cjs | 22 +++---------- resources/tester/helper_design_store_save.cjs | 22 ++++--------- .../tester/helper_design_view_parity.cjs | 22 ++++--------- .../tester/helper_item_picker_project.cjs | 22 ++++--------- resources/tester/helper_m02_hopyo_check.cjs | 21 ++++-------- resources/tester/helper_m02_hopyo_pick.cjs | 21 ++++-------- resources/tester/helper_m02_hopyo_seam.cjs | 21 ++++-------- .../tester/helper_m02_labor_national.cjs | 21 ++++-------- .../tester/helper_m02_precombo_scope.cjs | 21 ++++-------- 28 files changed, 170 insertions(+), 479 deletions(-) diff --git a/resources/tester/helper_54_14_balloon_lines.cjs b/resources/tester/helper_54_14_balloon_lines.cjs index ac8c8d76f..2d90c4da4 100644 --- a/resources/tester/helper_54_14_balloon_lines.cjs +++ b/resources/tester/helper_54_14_balloon_lines.cjs @@ -6,28 +6,18 @@ const fs = require("fs"); const path = require("path"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; // 구조물 표(본보기 · 323-7) if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const { balloonLines } = loadTs( path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_Structures_Balloon.ts"), diff --git a/resources/tester/helper_54_27_soil_tier_field.cjs b/resources/tester/helper_54_27_soil_tier_field.cjs index 3e60b790d..27b9a9e5c 100644 --- a/resources/tester/helper_54_27_soil_tier_field.cjs +++ b/resources/tester/helper_54_27_soil_tier_field.cjs @@ -4,11 +4,10 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // ── 화면 그릇 흉내 — 태그 · 클래스 · data · 이벤트만 ───────────────────────── class FakeNode { @@ -144,25 +143,16 @@ const STUBS = { }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; if (STUBS[request]) return STUBS[request]; if (request.startsWith("@util/")) return loadTs(path.join(ROOT, "common_util", `${request.slice(6)}.ts`)); return loadTs(path.join(path.dirname(full), `${request}.ts`)); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const { createFacilityOptionsForm } = loadTs( path.join(ROOT, "B05_Profile", "B05_Profile_UI_Drainage_Facility.ts"), diff --git a/resources/tester/helper_73_4_body_guard.cjs b/resources/tester/helper_73_4_body_guard.cjs index 71de877e6..ba0734a27 100644 --- a/resources/tester/helper_73_4_body_guard.cjs +++ b/resources/tester/helper_73_4_body_guard.cjs @@ -4,44 +4,26 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 화면 전용 모듈(토스트 · 글) — 기하 계산엔 안 쓰임 const STUBS = { "@ui/ui_template_toast": { showToast: () => undefined }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - if (full.endsWith(".json")) { - const data = JSON.parse(fs.readFileSync(full, "utf8")); - cache.set(full, data); - return data; - } - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2020, - esModuleInterop: true, - }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + interop: true, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" }; for (const [prefix, dir] of Object.entries(alias)) if (request.startsWith(prefix)) return loadTs(resolve(path.join(ROOT, dir, request.slice(prefix.length)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const resolve = (base) => [base, `${base}.ts`, path.join(base, "index.ts")].find( (p) => fs.existsSync(p) && fs.statSync(p).isFile(), diff --git a/resources/tester/helper_79_guard_shape.cjs b/resources/tester/helper_79_guard_shape.cjs index 4fa0852ee..b0b53c880 100644 --- a/resources/tester/helper_79_guard_shape.cjs +++ b/resources/tester/helper_79_guard_shape.cjs @@ -3,44 +3,26 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 화면 전용 모듈(토스트 · 글) — 기하 계산엔 안 쓰임 const STUBS = { "@ui/ui_template_toast": { showToast: () => undefined }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - if (full.endsWith(".json")) { - const data = JSON.parse(fs.readFileSync(full, "utf8")); - cache.set(full, data); - return data; - } - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2020, - esModuleInterop: true, - }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + interop: true, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" }; for (const [prefix, dir] of Object.entries(alias)) if (request.startsWith(prefix)) return loadTs(resolve(path.join(ROOT, dir, request.slice(prefix.length)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const resolve = (base) => [base, `${base}.ts`, path.join(base, "index.ts")].find( (p) => fs.existsSync(p) && fs.statSync(p).isFile(), diff --git a/resources/tester/helper_80_ford_pipe.cjs b/resources/tester/helper_80_ford_pipe.cjs index 5e8833494..34ca92bb7 100644 --- a/resources/tester/helper_80_ford_pipe.cjs +++ b/resources/tester/helper_80_ford_pipe.cjs @@ -3,44 +3,26 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 화면 전용 모듈(토스트 · 글) — 기하 계산엔 안 쓰임 const STUBS = { "@ui/ui_template_toast": { showToast: () => undefined }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - if (full.endsWith(".json")) { - const data = JSON.parse(fs.readFileSync(full, "utf8")); - cache.set(full, data); - return data; - } - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2020, - esModuleInterop: true, - }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + interop: true, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" }; for (const [prefix, dir] of Object.entries(alias)) if (request.startsWith(prefix)) return loadTs(resolve(path.join(ROOT, dir, request.slice(prefix.length)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const resolve = (base) => [base, `${base}.ts`, path.join(base, "index.ts")].find( (p) => fs.existsSync(p) && fs.statSync(p).isFile(), diff --git a/resources/tester/helper_90_chute_band.cjs b/resources/tester/helper_90_chute_band.cjs index d61db73a6..461c58ba2 100644 --- a/resources/tester/helper_90_chute_band.cjs +++ b/resources/tester/helper_90_chute_band.cjs @@ -3,22 +3,13 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => loadTs(path.join(path.dirname(full), `${request}.ts`)); - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => loadTs(path.join(path.dirname(full), `${request}.ts`)), +}); class Node { constructor(tag) { diff --git a/resources/tester/helper_91_ground_free.cjs b/resources/tester/helper_91_ground_free.cjs index b2e5208f2..ae12a5ccf 100644 --- a/resources/tester/helper_91_ground_free.cjs +++ b/resources/tester/helper_91_ground_free.cjs @@ -3,44 +3,26 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 화면 전용 모듈(토스트 · 글) — 기하 계산엔 안 쓰임 const STUBS = { "@ui/ui_template_toast": { showToast: () => undefined }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - if (full.endsWith(".json")) { - const data = JSON.parse(fs.readFileSync(full, "utf8")); - cache.set(full, data); - return data; - } - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2020, - esModuleInterop: true, - }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + interop: true, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" }; for (const [prefix, dir] of Object.entries(alias)) if (request.startsWith(prefix)) return loadTs(resolve(path.join(ROOT, dir, request.slice(prefix.length)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const resolve = (base) => [base, `${base}.ts`, path.join(base, "index.ts")].find( (p) => fs.existsSync(p) && fs.statSync(p).isFile(), diff --git a/resources/tester/helper_b05_b06_selection.cjs b/resources/tester/helper_b05_b06_selection.cjs index e38ec452e..a1b845999 100644 --- a/resources/tester/helper_b05_b06_selection.cjs +++ b/resources/tester/helper_b05_b06_selection.cjs @@ -5,10 +5,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); const session = new Map(); const fakeStorage = { @@ -21,22 +20,13 @@ globalThis.sessionStorage = fakeStorage; globalThis.localStorage = fakeStorage; globalThis.requestAnimationFrame = (fn) => fn(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) - : require(request); - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + : require(request), +}); const sel = loadTs(path.join(ROOT, "A00_Common", "design", "design_selection.ts")); const pickPage = loadTs(path.join(ROOT, "B06_Section", "B06_Section_UI_Page_Structure_Pick.ts")); diff --git a/resources/tester/helper_b05_curve_radius_floor.cjs b/resources/tester/helper_b05_curve_radius_floor.cjs index c97d8812a..e115c907e 100644 --- a/resources/tester/helper_b05_curve_radius_floor.cjs +++ b/resources/tester/helper_b05_curve_radius_floor.cjs @@ -6,28 +6,18 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); /** TS 한 장을 CommonJS 로 옮겨 실행한다. 상대 import 는 같은 길로 다시 들어온다. */ -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) - : require(request); - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + : require(request), +}); const edits = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Edits.ts")); const { applyCurveLimits, curveShortfalls, radiusFloorM } = edits; diff --git a/resources/tester/helper_b05_routeedit_cross_width.cjs b/resources/tester/helper_b05_routeedit_cross_width.cjs index 1a655ee86..aa9e8abba 100644 --- a/resources/tester/helper_b05_routeedit_cross_width.cjs +++ b/resources/tester/helper_b05_routeedit_cross_width.cjs @@ -5,7 +5,7 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); function memoryStorage() { @@ -115,24 +115,14 @@ const STUBS = { }, }; -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const { createCrossPreview } = loadTs( path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Cross.ts"), diff --git a/resources/tester/helper_b05_routeedit_initial.cjs b/resources/tester/helper_b05_routeedit_initial.cjs index a829a8ddc..da6e4ea33 100644 --- a/resources/tester/helper_b05_routeedit_initial.cjs +++ b/resources/tester/helper_b05_routeedit_initial.cjs @@ -6,10 +6,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); function memoryStorage() { const map = new Map(); @@ -30,26 +29,17 @@ globalThis.fetch = () => Promise.resolve({ ok: false }); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith("@ui/")) return loadTs(path.join(ROOT, "ui_template", `${request.slice(4)}.ts`)); if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const model = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Initial_Model.ts")); const { DEFAULT_WEIGHTS } = model; diff --git a/resources/tester/helper_b05_routeedit_initial_apply.cjs b/resources/tester/helper_b05_routeedit_initial_apply.cjs index 83245679a..8754ecf17 100644 --- a/resources/tester/helper_b05_routeedit_initial_apply.cjs +++ b/resources/tester/helper_b05_routeedit_initial_apply.cjs @@ -11,10 +11,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); function memoryStorage() { const map = new Map(); @@ -33,23 +32,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false }); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const model = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Initial_Model.ts")); const edits = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Edits.ts")); diff --git a/resources/tester/helper_b05_routeedit_lock.cjs b/resources/tester/helper_b05_routeedit_lock.cjs index 6df7fd975..ae942e25e 100644 --- a/resources/tester/helper_b05_routeedit_lock.cjs +++ b/resources/tester/helper_b05_routeedit_lock.cjs @@ -6,10 +6,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 브라우저 저장소 흉내 — `b_page_state` 가 읽고 쓰는 자리. function memoryStorage() { @@ -31,23 +30,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false }); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const lock = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Lock.ts")); @@ -86,7 +76,7 @@ const arcAll = [1, 2].map((index) => lock.arcLocked([true, true, true, true], in // ⑤ 노선을 못 읽은(노드 1개 이하) 채 닫으면 적어 둔 고정을 안 지운다 · 깨진 값은 기본값. lock.writeRouteLocks("p-1", [], []); const keptAfterEmpty = lock.readRouteLocks("p-1"); -local.setItem("aislo:pref:routeedit-locks:p-3", "{\"start\":false,\"apex\":[[1,\"x\"],[2,3]]}"); +local.setItem("aislo:pref:routeedit-locks:p-3", '{"start":false,"apex":[[1,"x"],[2,3]]}'); const broken = lock.readRouteLocks("p-3"); process.stdout.write( diff --git a/resources/tester/helper_b05_routeedit_pick.cjs b/resources/tester/helper_b05_routeedit_pick.cjs index 1859f0238..28c99443f 100644 --- a/resources/tester/helper_b05_routeedit_pick.cjs +++ b/resources/tester/helper_b05_routeedit_pick.cjs @@ -4,10 +4,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback }, "@util/common_util_svg": { @@ -15,23 +14,14 @@ const STUBS = { }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const input = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Input.ts")); const curve = loadTs(path.join(ROOT, "B05_Profile", "logic", "B05_Profile_UI_RouteEdit_Curve.ts")); diff --git a/resources/tester/helper_b05_routeedit_view.cjs b/resources/tester/helper_b05_routeedit_view.cjs index 5380bd918..2bf2b8154 100644 --- a/resources/tester/helper_b05_routeedit_view.cjs +++ b/resources/tester/helper_b05_routeedit_view.cjs @@ -6,10 +6,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // 브라우저 저장소 흉내 — `b_page_state` 가 읽고 쓰는 자리. function memoryStorage() { @@ -31,23 +30,14 @@ globalThis.fetch = () => Promise.resolve({ ok: false }); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const viewMod = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_View.ts")); const render = loadTs(path.join(ROOT, "B04_PreProcess", "B04_PreProcess_UI_MapRender.ts")); diff --git a/resources/tester/helper_b05_station_roundtrip.cjs b/resources/tester/helper_b05_station_roundtrip.cjs index ab81f8aef..717fdd8f8 100644 --- a/resources/tester/helper_b05_station_roundtrip.cjs +++ b/resources/tester/helper_b05_station_roundtrip.cjs @@ -4,30 +4,20 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => CATALOG.isCatalogRequest(request) ? CATALOG : request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) - : require(request); - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + : require(request), +}); // 측점 칸이 쓰는 만큼만 흉내 낸 DOM function fakeElement() { diff --git a/resources/tester/helper_b05_structures_form_summary.cjs b/resources/tester/helper_b05_structures_form_summary.cjs index 1cd5f9cda..8338d6767 100644 --- a/resources/tester/helper_b05_structures_form_summary.cjs +++ b/resources/tester/helper_b05_structures_form_summary.cjs @@ -5,11 +5,10 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // ── 화면 그릇 흉내 — 요소 · 클래스 · 이벤트 · 글자만 ───────────────────────── class FakeNode { @@ -115,15 +114,9 @@ const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api", API_TIMEOUT_MS: 1000 }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; if (STUBS[request]) return STUBS[request]; // 화면 공용 부품(@ui/…) — 이 시험이 안 쓰는 것이라 뭘 불러도 아무 일 안 하는 함수로 막아 둠 @@ -138,11 +131,8 @@ function loadTs(file) { return request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) : require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const B05 = (name) => loadTs(path.join(ROOT, "B05_Profile", `${name}.ts`)); const item = loadTs(path.join(ROOT, "common_util", "common_util_summary_item.ts")); diff --git a/resources/tester/helper_b06_adjust_single_form.cjs b/resources/tester/helper_b06_adjust_single_form.cjs index ec94f4aaf..7fe94db76 100644 --- a/resources/tester/helper_b06_adjust_single_form.cjs +++ b/resources/tester/helper_b06_adjust_single_form.cjs @@ -5,7 +5,7 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); @@ -93,25 +93,16 @@ const STUBS = { }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; if (STUBS[request]) return STUBS[request]; if (request.startsWith("@util/")) return loadTs(path.join(ROOT, "common_util", `${request.slice(6)}.ts`)); return loadTs(path.join(path.dirname(full), `${request}.ts`)); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const B06 = (name) => loadTs(path.join(ROOT, "B06_Section", `${name}.ts`)); const { buildStructurePanel } = B06("B06_Section_UI_Cross_Structure_Panel"); diff --git a/resources/tester/helper_b06_draft_pipe_replay.cjs b/resources/tester/helper_b06_draft_pipe_replay.cjs index df2316c72..2d6d86544 100644 --- a/resources/tester/helper_b06_draft_pipe_replay.cjs +++ b/resources/tester/helper_b06_draft_pipe_replay.cjs @@ -7,11 +7,10 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); const session = new Map(); const fakeStorage = { @@ -23,15 +22,9 @@ globalThis.window = { sessionStorage: fakeStorage, localStorage: fakeStorage }; globalThis.sessionStorage = fakeStorage; globalThis.localStorage = fakeStorage; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; // 화면 공용 부품(@ui/…)은 이 시험이 안 쓰는 것이라 아무 일 안 하는 함수로 막아 둠 if (request.startsWith("@ui/")) return new Proxy({}, { get: () => () => {} }); @@ -42,11 +35,8 @@ function loadTs(file) { return request.startsWith(".") ? loadTs(path.join(path.dirname(full), `${request}.ts`)) : require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const DEF = JSON.parse( fs.readFileSync(path.join(ROOT, "resources", "master_template", "구조물정의.json"), "utf8"), diff --git a/resources/tester/helper_design_profile_single.cjs b/resources/tester/helper_design_profile_single.cjs index 06f20767b..b14a5244f 100644 --- a/resources/tester/helper_design_profile_single.cjs +++ b/resources/tester/helper_design_profile_single.cjs @@ -5,7 +5,7 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); @@ -27,23 +27,9 @@ const local = memoryStorage(); globalThis.window = { sessionStorage: session, localStorage: local }; globalThis.sessionStorage = session; -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { - if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); - return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} +const { loadTs } = makeLoader({ + root: ROOT, +}); const { useDesignStore } = loadTs(path.join(ROOT, "A00_Common", "design", "design_store.ts")); const history = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_History.ts")); diff --git a/resources/tester/helper_design_store_save.cjs b/resources/tester/helper_design_store_save.cjs index 4495215e8..d77b34df1 100644 --- a/resources/tester/helper_design_store_save.cjs +++ b/resources/tester/helper_design_store_save.cjs @@ -4,7 +4,7 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); @@ -121,24 +121,14 @@ const STUBS = { "./design_leave": { designSignature: () => "", markDesignClean: () => undefined }, }; -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const { useDesignStore } = loadTs(path.join(ROOT, "A00_Common", "design", "design_store.ts")); const edit = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_Edit.ts")); diff --git a/resources/tester/helper_design_view_parity.cjs b/resources/tester/helper_design_view_parity.cjs index e8a83b677..cb2fd68a1 100644 --- a/resources/tester/helper_design_view_parity.cjs +++ b/resources/tester/helper_design_view_parity.cjs @@ -6,10 +6,9 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); // ── 화면 그릇 흉내 — 요소 · 클래스 · 속성 · 글자 · 자식 ────────────────────────── class FakeNode { @@ -147,24 +146,15 @@ const STUBS = { }, }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith(".")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const panel = loadTs(path.join(ROOT, "A00_Common", "design", "design_panel.ts")); loadTs(path.join(ROOT, "A00_Common", "design", "design_sections.ts")); diff --git a/resources/tester/helper_item_picker_project.cjs b/resources/tester/helper_item_picker_project.cjs index 18928fc96..350a58372 100644 --- a/resources/tester/helper_item_picker_project.cjs +++ b/resources/tester/helper_item_picker_project.cjs @@ -9,31 +9,21 @@ */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); -const cache = new Map(); const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith(".")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return require(request); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const reply = (status, body) => ({ status, diff --git a/resources/tester/helper_m02_hopyo_check.cjs b/resources/tester/helper_m02_hopyo_check.cjs index bc42f6022..b83a8f709 100644 --- a/resources/tester/helper_m02_hopyo_check.cjs +++ b/resources/tester/helper_m02_hopyo_check.cjs @@ -3,7 +3,7 @@ * stdin = {lines, rows, ledger} · stdout = {check, choose, ledger, sheet, calls, pick} JSON. */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } }; @@ -28,25 +28,16 @@ const stub = new Proxy( : () => {}, }, ); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (STUB_FILES.some((name) => request.endsWith(name))) return stub; if (request.startsWith(".") && !request.endsWith(".css")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return stub; - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const store = new Map(); global.sessionStorage = { diff --git a/resources/tester/helper_m02_hopyo_pick.cjs b/resources/tester/helper_m02_hopyo_pick.cjs index 3434f4991..7ae44299e 100644 --- a/resources/tester/helper_m02_hopyo_pick.cjs +++ b/resources/tester/helper_m02_hopyo_pick.cjs @@ -4,7 +4,7 @@ * stdin = {rows, built} · stdout = {calls, kinds, rows, picked, project, view, sheet} JSON. */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } }; @@ -17,25 +17,16 @@ const STUB_FILES = [ "M01_MasterData_UI_LogicLab_Source", ]; const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) }); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (STUB_FILES.some((name) => request.endsWith(name))) return stub; if (request.startsWith(".") && !request.endsWith(".css")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return stub; - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); (async () => { const input = JSON.parse(fs.readFileSync(0, "utf8")); diff --git a/resources/tester/helper_m02_hopyo_seam.cjs b/resources/tester/helper_m02_hopyo_seam.cjs index 705d02497..675e1a957 100644 --- a/resources/tester/helper_m02_hopyo_seam.cjs +++ b/resources/tester/helper_m02_hopyo_seam.cjs @@ -5,7 +5,7 @@ * count: {top}} JSON — count = 「후보」 줄 1순위 근거 맞음. */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } }; @@ -17,25 +17,16 @@ const STUB_FILES = [ "M01_MasterData_UI_LogicLab_Source", ]; const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) }); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (STUB_FILES.some((name) => request.endsWith(name))) return stub; if (request.startsWith(".") && !request.endsWith(".css")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return stub; - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const input = JSON.parse(fs.readFileSync(0, "utf8")); const M02 = path.join(ROOT, "M02_MasterTemplete"); diff --git a/resources/tester/helper_m02_labor_national.cjs b/resources/tester/helper_m02_labor_national.cjs index 6cea2ca9c..73b686eda 100644 --- a/resources/tester/helper_m02_labor_national.cjs +++ b/resources/tester/helper_m02_labor_national.cjs @@ -2,7 +2,7 @@ * `el` 대역 = 나무 꼴 {tag, className, text, attrs, children} · stdin = {origin} · stdout = 나무 JSON. */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const el = (tag, o = {}) => ({ tag, ...o, children: o.children ?? [] }); @@ -11,24 +11,15 @@ const STUBS = { "@ui/ui_template_locale": { currentLanguageIndex: 0 }, "@config/config_frontend": { API_BASE_URL: "/api" }, }; -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".") && !request.endsWith(".css")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return new Proxy({}, { get: () => () => ({}) }); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const input = JSON.parse(fs.readFileSync(0, "utf8")); const national = loadTs( diff --git a/resources/tester/helper_m02_precombo_scope.cjs b/resources/tester/helper_m02_precombo_scope.cjs index 71261dffc..c6a04c4c4 100644 --- a/resources/tester/helper_m02_precombo_scope.cjs +++ b/resources/tester/helper_m02_precombo_scope.cjs @@ -4,29 +4,20 @@ * stdin = {rows, def?, view?} · stdout = {urls, tree, classes} JSON. */ const fs = require("fs"); const path = require("path"); -const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const STUBS = { "@config/config_frontend": { API_BASE_URL: "/api" } }; const stub = new Proxy({}, { get: (_t, k) => (k === "currentLanguageIndex" ? () => 0 : () => {}) }); -const cache = new Map(); -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - cache.set(full, box.exports); - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.startsWith(".") && !request.endsWith(".css")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`); return stub; - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const urls = []; global.fetch = async (url) => {