diff --git a/resources/tester/helper_172_1_loft_wrinkle.cjs b/resources/tester/helper_172_1_loft_wrinkle.cjs index 236f43ef6..4eee129c0 100644 --- a/resources/tester/helper_172_1_loft_wrinkle.cjs +++ b/resources/tester/helper_172_1_loft_wrinkle.cjs @@ -7,28 +7,23 @@ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const NM = path.join(ROOT, "config", "node_modules"); -const ts = require(path.join(NM, "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const THREE = require(path.join(NM, "three")); const LIBS = { three: THREE, delaunator: require(path.join(NM, "delaunator", "index.js")), - "three/examples/jsm/utils/BufferGeometryUtils.js": require(path.join(NM, "three", "examples", "jsm", "utils", "BufferGeometryUtils.js")), + "three/examples/jsm/utils/BufferGeometryUtils.js": require( + path.join(NM, "three", "examples", "jsm", "utils", "BufferGeometryUtils.js"), + ), "@kninnug/constrainautor": { __esModule: true, default: require(path.join(NM, "@kninnug", "constrainautor", "lib", "Constrainautor.cjs")), }, }; -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 (LIBS[request]) return LIBS[request]; if (request.startsWith("@ui/") || request.startsWith("@config/")) { return new Proxy({}, { get: () => () => undefined }); @@ -38,10 +33,8 @@ function loadTs(file) { : path.join(path.dirname(full), request); if (request.endsWith(".json")) return JSON.parse(fs.readFileSync(target, "utf8")); return loadTs(fs.existsSync(`${target}.ts`) ? `${target}.ts` : path.join(target, "index.ts")); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const B05 = (name) => path.join(ROOT, "B05_Profile", `${name}.ts`); const { buildCorridor } = loadTs(B05("B05_Profile_UI_Corridor_Build")); @@ -134,7 +127,10 @@ function gridTerrain(heightAt) { } const geometry = new THREE.BufferGeometry(); geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute("color", new THREE.BufferAttribute(new Uint8Array(nx * ny * 4).fill(200), 4, true)); + geometry.setAttribute( + "color", + new THREE.BufferAttribute(new Uint8Array(nx * ny * 4).fill(200), 4, true), + ); geometry.setIndex(index); return new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ vertexColors: true })); } @@ -151,7 +147,12 @@ function gapCount(root, out) { const onFrame = (p) => { const x = p[0] + OX; const y = -p[2] + OY; - return Math.abs(x - X0) < 1e-3 || Math.abs(x - X1) < 1e-3 || Math.abs(y - Y0) < 1e-3 || Math.abs(y - Y1) < 1e-3; + return ( + Math.abs(x - X0) < 1e-3 || + Math.abs(x - X1) < 1e-3 || + Math.abs(y - Y0) < 1e-3 || + Math.abs(y - Y1) < 1e-3 + ); }; const uses = new Map(); root.traverse((child) => { @@ -193,7 +194,8 @@ function gapCount(root, out) { function tinHeights(out) { const p = out.root.getObjectByName("terrain-tin-mesh").geometry.getAttribute("position"); const tris = []; - for (let t = 0; t < p.count; t += 3) tris.push([0, 1, 2].map((k) => [p.getX(t + k), p.getY(t + k), p.getZ(t + k)])); + for (let t = 0; t < p.count; t += 3) + tris.push([0, 1, 2].map((k) => [p.getX(t + k), p.getY(t + k), p.getZ(t + k)])); return (x, y) => { const sx = x - OX; const sz = -(y - OY); diff --git a/resources/tester/helper_173_7_inlet_animal.cjs b/resources/tester/helper_173_7_inlet_animal.cjs index 863ba5493..6f783a723 100644 --- a/resources/tester/helper_173_7_inlet_animal.cjs +++ b/resources/tester/helper_173_7_inlet_animal.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(); class FakeNode { constructor(tag) { @@ -97,25 +96,16 @@ const STUBS = { "../../B05_Profile/B05_Profile_UI_Structures_Summary_Row": { buildSummaryRow: () => null }, }; -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 { createSpecForm } = loadTs( path.join(ROOT, "A00_Common", "design", "design_structure_form.ts"), diff --git a/resources/tester/helper_176_1_seam.cjs b/resources/tester/helper_176_1_seam.cjs index 9f364de98..08bdd37e6 100644 --- a/resources/tester/helper_176_1_seam.cjs +++ b/resources/tester/helper_176_1_seam.cjs @@ -7,28 +7,23 @@ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const NM = path.join(ROOT, "config", "node_modules"); -const ts = require(path.join(NM, "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const THREE = require(path.join(NM, "three")); const LIBS = { three: THREE, delaunator: require(path.join(NM, "delaunator", "index.js")), - "three/examples/jsm/utils/BufferGeometryUtils.js": require(path.join(NM, "three", "examples", "jsm", "utils", "BufferGeometryUtils.js")), + "three/examples/jsm/utils/BufferGeometryUtils.js": require( + path.join(NM, "three", "examples", "jsm", "utils", "BufferGeometryUtils.js"), + ), "@kninnug/constrainautor": { __esModule: true, default: require(path.join(NM, "@kninnug", "constrainautor", "lib", "Constrainautor.cjs")), }, }; -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 (LIBS[request]) return LIBS[request]; if (request.startsWith("@ui/") || request.startsWith("@config/")) { return new Proxy({}, { get: () => () => undefined }); @@ -38,10 +33,8 @@ function loadTs(file) { : path.join(path.dirname(full), request); if (request.endsWith(".json")) return JSON.parse(fs.readFileSync(target, "utf8")); return loadTs(fs.existsSync(`${target}.ts`) ? `${target}.ts` : path.join(target, "index.ts")); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const B05 = (name) => path.join(ROOT, "B05_Profile", `${name}.ts`); const { buildCorridor } = loadTs(B05("B05_Profile_UI_Corridor_Build")); @@ -139,7 +132,10 @@ function gridTerrain(heightAt) { } const geometry = new THREE.BufferGeometry(); geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute("color", new THREE.BufferAttribute(new Uint8Array(nx * ny * 4).fill(200), 4, true)); + geometry.setAttribute( + "color", + new THREE.BufferAttribute(new Uint8Array(nx * ny * 4).fill(200), 4, true), + ); geometry.setIndex(index); return new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ vertexColors: true })); } @@ -156,7 +152,12 @@ function gapCount(root, out) { const onFrame = (p) => { const x = p[0] + OX; const y = -p[2] + OY; - return Math.abs(x - X0) < 1e-3 || Math.abs(x - X1) < 1e-3 || Math.abs(y - Y0) < 1e-3 || Math.abs(y - Y1) < 1e-3; + return ( + Math.abs(x - X0) < 1e-3 || + Math.abs(x - X1) < 1e-3 || + Math.abs(y - Y0) < 1e-3 || + Math.abs(y - Y1) < 1e-3 + ); }; const uses = new Map(); root.traverse((child) => { diff --git a/resources/tester/helper_178_3_slope_tiers.cjs b/resources/tester/helper_178_3_slope_tiers.cjs index 869a134f0..de8e4164f 100644 --- a/resources/tester/helper_178_3_slope_tiers.cjs +++ b/resources/tester/helper_178_3_slope_tiers.cjs @@ -5,31 +5,16 @@ */ 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 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 (CATALOG.isCatalogRequest(request)) return CATALOG; if (STUBS[request]) return STUBS[request]; const alias = { "@util/": "common_util", "@ui/": "ui_template", "@config/": "config" }; @@ -37,11 +22,8 @@ function loadTs(file) { 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_179_4_detail_table.cjs b/resources/tester/helper_179_4_detail_table.cjs index 743921ada..f0cd798be 100644 --- a/resources/tester/helper_179_4_detail_table.cjs +++ b/resources/tester/helper_179_4_detail_table.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, "..", ".."); const B06 = path.join(ROOT, "B06_Section"); @@ -33,21 +33,17 @@ const STUBS = { "./B06_Section_UI_Section_Common": { CROSS_PAD }, }; const resolve = (base) => (fs.existsSync(`${base}.ts`) ? `${base}.ts` : base); -function loadTs(full) { - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith("@util/")) return loadTs(resolve(path.join(ROOT, "common_util", request.slice(6)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const T = loadTs(path.join(B06, "B06_Section_UI_Cross_Detail_Table.ts")); const input = JSON.parse(fs.readFileSync(0, "utf8")); diff --git a/resources/tester/helper_180_3_b07_guide_toggle.cjs b/resources/tester/helper_180_3_b07_guide_toggle.cjs index 5dd7883f8..3950f80d7 100644 --- a/resources/tester/helper_180_3_b07_guide_toggle.cjs +++ b/resources/tester/helper_180_3_b07_guide_toggle.cjs @@ -3,10 +3,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 { constructor(tag) { @@ -53,15 +52,9 @@ class FakeNode { } globalThis.document = { createElement: (tag) => new FakeNode(tag) }; -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 (request === "@ui/ui_template_elements") return loadTs(path.join(ROOT, "ui_template", "ui_template_elements.ts")); if (request.startsWith(".")) { @@ -69,11 +62,8 @@ function loadTs(file) { return fs.existsSync(target) ? loadTs(target) : {}; } return {}; - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - cache.set(full, box.exports); - return box.exports; -} + }, +}); const { buildGuideToggle, guideShown } = loadTs( path.join(ROOT, "B07_DesignDetail", "B07_DesignDetail_UI_GuideToggle.ts"), diff --git a/resources/tester/helper_186_1_outlet_fold.cjs b/resources/tester/helper_186_1_outlet_fold.cjs index 14d84df96..0b754a8b7 100644 --- a/resources/tester/helper_186_1_outlet_fold.cjs +++ b/resources/tester/helper_186_1_outlet_fold.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_188_1_last_pick.cjs b/resources/tester/helper_188_1_last_pick.cjs index b3e1aa938..ea1bbf61f 100644 --- a/resources/tester/helper_188_1_last_pick.cjs +++ b/resources/tester/helper_188_1_last_pick.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 = { @@ -29,23 +28,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) => STUBS[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 sync = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Selection.ts")); diff --git a/resources/tester/helper_190_1_basin_pick.cjs b/resources/tester/helper_190_1_basin_pick.cjs index a09a1949b..2206c2fae 100644 --- a/resources/tester/helper_190_1_basin_pick.cjs +++ b/resources/tester/helper_190_1_basin_pick.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 STUBS = { "@ui/ui_template_toast": { showToast: () => undefined }, "@ui/ui_template_elements": { showToast: () => undefined }, @@ -63,35 +62,18 @@ globalThis.document = { createElementNS: (_ns, tag) => new FakeNode(tag), }; -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_193_1_line_axis.cjs b/resources/tester/helper_193_1_line_axis.cjs index 4be2feca6..6ec7479f9 100644 --- a/resources/tester/helper_193_1_line_axis.cjs +++ b/resources/tester/helper_193_1_line_axis.cjs @@ -3,10 +3,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 Node { constructor(tag) { @@ -81,22 +80,13 @@ const key = (name) => fn({ key: name, target: null, preventDefault: () => undefined }), ); -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 req = (r) => +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (r) => r.startsWith("@util/") ? loadTs(path.join(ROOT, "common_util", `${r.slice(6)}.ts`)) - : loadTs(path.join(path.dirname(full), `${r}.ts`)); - new Function("exports", "module", "require", js)(box.exports, box, req); - cache.set(full, box.exports); - return box.exports; -} + : loadTs(path.join(path.dirname(full), `${r}.ts`)), +}); globalThis.Element = Node; const pick = loadTs(path.join(ROOT, "B06_Section", "B06_Section_UI_Cross_Design_Pick.ts")); diff --git a/resources/tester/helper_194_1_berm_pick.cjs b/resources/tester/helper_194_1_berm_pick.cjs index d0f8a57e2..f2bcccc4f 100644 --- a/resources/tester/helper_194_1_berm_pick.cjs +++ b/resources/tester/helper_194_1_berm_pick.cjs @@ -3,10 +3,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 Node { constructor(tag) { @@ -81,22 +80,13 @@ const key = (name) => fn({ key: name, target: null, preventDefault: () => undefined }), ); -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 req = (r) => +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => (r) => r.startsWith("@util/") ? loadTs(path.join(ROOT, "common_util", `${r.slice(6)}.ts`)) - : loadTs(path.join(path.dirname(full), `${r}.ts`)); - new Function("exports", "module", "require", js)(box.exports, box, req); - cache.set(full, box.exports); - return box.exports; -} + : loadTs(path.join(path.dirname(full), `${r}.ts`)), +}); globalThis.Element = Node; const pick = loadTs(path.join(ROOT, "B06_Section", "B06_Section_UI_Cross_Design_Pick.ts")); diff --git a/resources/tester/helper_209_1_detail_select.cjs b/resources/tester/helper_209_1_detail_select.cjs index 9390a94c6..157e36606 100644 --- a/resources/tester/helper_209_1_detail_select.cjs +++ b/resources/tester/helper_209_1_detail_select.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, "..", ".."); const B06 = path.join(ROOT, "B06_Section"); @@ -18,21 +18,17 @@ const STUBS = { "./B06_Section_UI_Section_Common": { CROSS_PAD }, }; const resolve = (base) => (fs.existsSync(`${base}.ts`) ? `${base}.ts` : base); -function loadTs(full) { - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith("@util/")) return loadTs(resolve(path.join(ROOT, "common_util", request.slice(6)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const G = loadTs(path.join(B06, "logic/B06_Section_UI_Cross_Detail_Geom.ts")); const S = loadTs(path.join(B06, "B06_Section_UI_Cross_Detail_Select.ts")); const T = loadTs(path.join(B06, "B06_Section_UI_Cross_Detail_Table.ts")); diff --git a/resources/tester/helper_215_1_free_profile.cjs b/resources/tester/helper_215_1_free_profile.cjs index e5a7e9181..7021dbcb8 100644 --- a/resources/tester/helper_215_1_free_profile.cjs +++ b/resources/tester/helper_215_1_free_profile.cjs @@ -4,26 +4,12 @@ */ 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) => { - 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 free = loadTs(path.join(ROOT, "A00_Common", "design", "logic", "design_profile_free.ts")); const align = loadTs( diff --git a/resources/tester/helper_216_1_b05_station_panel.cjs b/resources/tester/helper_216_1_b05_station_panel.cjs index ba1547ed4..462a7d347 100644 --- a/resources/tester/helper_216_1_b05_station_panel.cjs +++ b/resources/tester/helper_216_1_b05_station_panel.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 = { @@ -28,23 +27,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) => STUBS[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 sync = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Selection.ts")); diff --git a/resources/tester/helper_219_1_arrow_owner.cjs b/resources/tester/helper_219_1_arrow_owner.cjs index 04aa20ff3..7a8431b8f 100644 --- a/resources/tester/helper_219_1_arrow_owner.cjs +++ b/resources/tester/helper_219_1_arrow_owner.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(); const listeners = { window: {}, document: {} }; const on = (where) => (type, fn) => (listeners[where][type] ??= new Set()).add(fn); @@ -61,24 +60,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) => (CATALOG.isCatalogRequest(request) ? CATALOG : null) ?? STUBS[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 tools = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_Panel_Tools.ts")); const base = loadTs(path.join(ROOT, "B06_Section", "B06_Section_UI_Cross_Panel_Base.ts")); diff --git a/resources/tester/helper_224_1_picker_top_table.cjs b/resources/tester/helper_224_1_picker_top_table.cjs index 724e246b3..02c68252c 100644 --- a/resources/tester/helper_224_1_picker_top_table.cjs +++ b/resources/tester/helper_224_1_picker_top_table.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, "..", ".."); const UI = path.join(ROOT, "ui_template"); @@ -57,24 +57,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.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 flush = () => new Promise((resolve) => setTimeout(resolve, 20)); const row = (key, 열, layer, owner) => ({ key, 열, layer, owner }); diff --git a/resources/tester/helper_224_1a_drainage_rehome.cjs b/resources/tester/helper_224_1a_drainage_rehome.cjs index 1f3bbea85..0ebc645ff 100644 --- a/resources/tester/helper_224_1a_drainage_rehome.cjs +++ b/resources/tester/helper_224_1a_drainage_rehome.cjs @@ -5,27 +5,19 @@ * · disconnect = 지금 관찰자 끊음 */ 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 stub = new Proxy({}, { get: () => () => "" }); /** TS 한 장을 CommonJS 로 — 상대 경로는 진짜(공용 창 · 지도 셈만), 나머지는 빈 함수. */ -function loadTs(full) { - 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) => /common_util_view_window|B04_PreProcess_UI_MapRender/.test(request) ? loadTs(path.join(path.dirname(full), `${request}.ts`)) - : stub; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + : stub, +}); /** 가짜 창 — 관찰자를 모아 두고 크기를 바꿔 울림. */ function fakeWindow(name) { diff --git a/resources/tester/helper_225_1_pipe_round.cjs b/resources/tester/helper_225_1_pipe_round.cjs index 64919dca3..92f1b33fb 100644 --- a/resources/tester/helper_225_1_pipe_round.cjs +++ b/resources/tester/helper_225_1_pipe_round.cjs @@ -3,10 +3,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 noop = new Proxy({}, { get: () => () => "" }); /** 아주 작은 SVG 가짜 — 글 자리 판정에 쓰는 것만(class 고르기 · 속성 · 부모). */ @@ -47,26 +46,20 @@ class El { } globalThis.document = { addEventListener: () => undefined, createElementNS: (_ns, t) => new El(t) }; -function loadTs(file) { - const full = path.resolve(file); - if (cache.has(full)) return cache.get(full); - if (full.endsWith(".json")) return JSON.parse(fs.readFileSync(full, "utf8")); - 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 resolve = (base) => - fs.existsSync(base) && fs.statSync(base).isFile() ? base : `${base}.ts`; - const req = (r) => { - if (r.startsWith("@ui/") || r.startsWith("@config/")) return noop; - if (r.startsWith("@util/")) return loadTs(resolve(path.join(ROOT, "common_util", r.slice(6)))); - return loadTs(resolve(path.join(path.dirname(full), r))); - }; - new Function("exports", "module", "require", js)(box.exports, box, req); - cache.set(full, box.exports); - return box.exports; -} +const { loadTs } = makeLoader({ + root: ROOT, + requireFor: (full) => { + const resolve = (base) => + fs.existsSync(base) && fs.statSync(base).isFile() ? base : `${base}.ts`; + const req = (r) => { + if (r.startsWith("@ui/") || r.startsWith("@config/")) return noop; + if (r.startsWith("@util/")) + return loadTs(resolve(path.join(ROOT, "common_util", r.slice(6)))); + return loadTs(resolve(path.join(path.dirname(full), r))); + }; + return req; + }, +}); const B06 = (name) => loadTs(path.join(ROOT, "B06_Section", `${name}.ts`)); const { computeCulvertLayout } = B06("B06_Section_UI_Cross_Culvert_Geom"); diff --git a/resources/tester/helper_231_1_pave_reload.cjs b/resources/tester/helper_231_1_pave_reload.cjs index b548502e1..7d05d6c81 100644 --- a/resources/tester/helper_231_1_pave_reload.cjs +++ b/resources/tester/helper_231_1_pave_reload.cjs @@ -4,23 +4,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 CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1) const ROOT = path.join(__dirname, "..", ".."); function loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(file, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (CATALOG.isCatalogRequest(request)) return CATALOG; - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (CATALOG.isCatalogRequest(request)) return CATALOG; + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request}`); + }, + }).loadTs(file); } global.requestAnimationFrame = (fn) => fn(); diff --git a/resources/tester/helper_232_1_3d_press.cjs b/resources/tester/helper_232_1_3d_press.cjs index 4d6083250..33d0ab7bd 100644 --- a/resources/tester/helper_232_1_3d_press.cjs +++ b/resources/tester/helper_232_1_3d_press.cjs @@ -6,21 +6,19 @@ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const NM = path.join(ROOT, "config", "node_modules"); -const ts = require(path.join(NM, "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const THREE = require(path.join(NM, "three", "build", "three.cjs")); function loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (request === "three") return THREE; - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (request === "three") return THREE; + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request}`); + }, + }).loadTs(path.join(ROOT, file)); } /* ── 창 · 캔버스 흉내(듣개 차례 = 창 캡처 → 캔버스 등록 차례) ── */ diff --git a/resources/tester/helper_233_1_profile_pick.cjs b/resources/tester/helper_233_1_profile_pick.cjs index a6f6b058e..26cb179b9 100644 --- a/resources/tester/helper_233_1_profile_pick.cjs +++ b/resources/tester/helper_233_1_profile_pick.cjs @@ -5,19 +5,17 @@ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); -const ts = require(path.join(ROOT, "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); function loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request}`); + }, + }).loadTs(path.join(ROOT, file)); } const store = new Map(); diff --git a/resources/tester/helper_233_2_view_pick.cjs b/resources/tester/helper_233_2_view_pick.cjs index a774d28c4..0dc35175b 100644 --- a/resources/tester/helper_233_2_view_pick.cjs +++ b/resources/tester/helper_233_2_view_pick.cjs @@ -9,20 +9,19 @@ const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const NM = path.join(ROOT, "config", "node_modules"); const ts = require(path.join(NM, "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const THREE = require(path.join(NM, "three", "build", "three.cjs")); function loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (request === "three") return THREE; - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (request === "three") return THREE; + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request}`); + }, + }).loadTs(path.join(ROOT, file)); } /* ── 가짜 DOM(라벨 캔버스 · [상세] 값 칸 · 조각) ── */ diff --git a/resources/tester/helper_233_3_release.cjs b/resources/tester/helper_233_3_release.cjs index 413e18288..e73539659 100644 --- a/resources/tester/helper_233_3_release.cjs +++ b/resources/tester/helper_233_3_release.cjs @@ -5,19 +5,17 @@ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); -const ts = require(path.join(ROOT, "config", "node_modules", "typescript")); +const { makeLoader } = require("./helper_ts_stub_loader.cjs"); function loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request}`); + }, + }).loadTs(path.join(ROOT, file)); } /* 창 키 듣기 · 창(모달) 흉내 */ diff --git a/resources/tester/helper_234_1_structure_station.cjs b/resources/tester/helper_234_1_structure_station.cjs index a4698de53..2d68c1598 100644 --- a/resources/tester/helper_234_1_structure_station.cjs +++ b/resources/tester/helper_234_1_structure_station.cjs @@ -4,21 +4,19 @@ */ 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 loadTs(file, stubs = {}) { - const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, file), "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { - if (stubs[request]) return stubs[request]; - throw new Error(`stub 없음: ${request} (${file})`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; + return makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { + if (stubs[request]) return stubs[request]; + throw new Error(`stub 없음: ${request} (${file})`); + }, + }).loadTs(path.join(ROOT, file)); } /* 가짜 DOM — 폼 칸(input · label · span)만. */ diff --git a/resources/tester/helper_259_detail_region.cjs b/resources/tester/helper_259_detail_region.cjs index 1ce888c3e..c63fd68ff 100644 --- a/resources/tester/helper_259_detail_region.cjs +++ b/resources/tester/helper_259_detail_region.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, "..", ".."); const B06 = path.join(ROOT, "B06_Section"); @@ -18,21 +18,17 @@ const STUBS = { "./B06_Section_UI_Section_Common": { CROSS_PAD }, }; const resolve = (base) => (fs.existsSync(`${base}.ts`) ? `${base}.ts` : base); -function loadTs(full) { - const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith("@util/")) return loadTs(resolve(path.join(ROOT, "common_util", request.slice(6)))); return loadTs(resolve(path.join(path.dirname(full), request))); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); const Z = loadTs(path.join(ROOT, "A00_Common", "b_svg_zoom_pan.ts")); const G = loadTs(path.join(B06, "logic/B06_Section_UI_Cross_Detail_Geom.ts")); const S = loadTs(path.join(B06, "B06_Section_UI_Cross_Detail_Select.ts")); diff --git a/resources/tester/helper_260_note_cad.cjs b/resources/tester/helper_260_note_cad.cjs index fd8965aed..1676a7684 100644 --- a/resources/tester/helper_260_note_cad.cjs +++ b/resources/tester/helper_260_note_cad.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, "..", ".."); // 인자 `load` = 표준입력 {pipes, structures, types} 를 세션 · 서버 흉내로 `loadNoteThings`(265-2) @@ -27,18 +27,14 @@ const STUBS = { "../B05_Profile/logic/B05_Profile_UI_Structures_Balloon": { structureOptionLines: () => [] }, }; -function loadTs(file) { - const js = ts.transpileModule(fs.readFileSync(file, "utf8"), { - compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, - }).outputText; - const box = { exports: {} }; - const localRequire = (request) => { +const { loadTs } = makeLoader({ + root: ROOT, + cache: false, + requireFor: (full) => (request) => { if (STUBS[request]) return STUBS[request]; throw new Error(`흉내 없는 모듈: ${request}`); - }; - new Function("exports", "module", "require", js)(box.exports, box, localRequire); - return box.exports; -} + }, +}); // 관 길이 정수(265-3) = 실제 `pipeLengthWhole` · 조합 참조 읽기(265-2) = 실제(둘 다 import 없음) STUBS["./logic/B06_Section_UI_Cross_Culvert_Const"] = loadTs(