Files
Aislo/resources/tester/helper_472_3_graph.mjs
T
eomsangdonandClaude Opus 5.5 4313eda5ac feat(472-3 등록부): B05 · B06 계산 등록부 · 서버 Node 입구 하나 · 경계 시험
- design_calc_registry.ts — 순수 자료 · 1.1 표 # 마다 id 하나(43) · 입력 · 출력 · 실행 자리 · 단계 · 실행기 · 짝 · 거울
- design_calc_node.ts — id → 함수 표(구조물 면적 · 관 길이 · 누가토량 · 유토 배분 · 터파기 · 3D) · build:design-calc
- 나머지 id 실행기 = 지금 파이썬 이름 · 472-4 동안 표시
- test_472_3_calc_registry — 실행기 있음 · STAGE_DEPS 같음 · 서버 쪽 코드 브라우저 밖 · Node 입구 도달 경계(알려진 끌림 목록) · server-calc · corridor 묶음과 같은 값
- 기존 묶음 · 파이썬 · design_pipeline.ts 그대로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 08:49:28 +09:00

52 lines
2.0 KiB
JavaScript

/* 472-3 헬퍼 — TS import 도달 집합(472-0 g472/graph.mjs 꼴 · 읽기만).
* node helper_472_3_graph.mjs <저장소 뿌리> <입구.ts> [<입구.ts> …]
* 입구마다 도달 파일(뿌리 상대 · `/`)을 JSON 한 벌로 표준출력 — 정적 import · export from · 동적
* import() · new URL(…, import.meta.url)(워커) · `import type` · `export type` 은 뺌(지워짐). */
import fs from "node:fs";
import path from "node:path";
const [root, ...entries] = process.argv.slice(2);
const alias = { "@ui/": "ui_template/", "@config/": "config/", "@util/": "common_util/" };
const rel = (p) => path.relative(root, p).split(path.sep).join("/");
const exists = (p) => {
for (const c of [p, `${p}.ts`, `${p}/index.ts`])
if (fs.existsSync(c) && fs.statSync(c).isFile()) return c;
return null;
};
function resolve(from, spec) {
let base;
if (spec.startsWith(".")) base = path.resolve(path.dirname(from), spec);
else {
const a = Object.keys(alias).find((k) => spec.startsWith(k));
if (!a) return null;
base = path.resolve(root, alias[a] + spec.slice(a.length));
}
return exists(base.replace(/\.js$/, ""));
}
const re =
/(?:import|export)\s+(?:type\s+)?(?:[^;"'`]*?\sfrom\s+)?["']([^"']+)["']|import\(\s*["']([^"']+)["']\s*\)|new URL\(\s*["']([^"']+)["']\s*,\s*import\.meta\.url/g;
function deps(file) {
if (!/\.(ts|mts)$/.test(file)) return [];
const src = fs.readFileSync(file, "utf8");
const out = [];
for (const m of src.matchAll(re)) {
if (/^(?:import|export)\s+type\s/.test(m[0])) continue;
const target = resolve(file, m[1] || m[2] || m[3]);
if (target) out.push(target);
}
return out;
}
const result = {};
for (const entry of entries) {
const seen = new Set();
const stack = [path.resolve(root, entry)];
while (stack.length) {
const file = stack.pop();
if (seen.has(file)) continue;
seen.add(file);
stack.push(...deps(file));
}
result[entry] = [...seen].map(rel).sort();
}
process.stdout.write(JSON.stringify(result));