fix: 버리기-뽑기 카드 미선언 prop 추가 (no such field 크래시) #95

Merged
gahusb merged 1 commits from fix/discard-draw-props into main 2026-06-29 17:51:52 +09:00
3 changed files with 50 additions and 0 deletions

View File

@@ -932,6 +932,20 @@
"Attributes": [],
"Name": "DiscardShivPerPick"
},
{
"Type": "number",
"DefaultValue": "0",
"SyncDirection": 0,
"Attributes": [],
"Name": "DiscardPostDraw"
},
{
"Type": "number",
"DefaultValue": "0",
"SyncDirection": 0,
"Attributes": [],
"Name": "DiscardDrawPerPick"
},
{
"Type": "boolean",
"DefaultValue": "false",

View File

@@ -152,6 +152,8 @@ function writeCodeblocks() {
prop('number', 'DiscardSelectTotal', '0'),
prop('number', 'DiscardPostShiv', '0'),
prop('number', 'DiscardShivPerPick', '0'),
prop('number', 'DiscardPostDraw', '0'),
prop('number', 'DiscardDrawPerPick', '0'),
prop('boolean', 'RetainSelectActive', 'false'),
prop('boolean', 'ReserveSelectActive', 'false'),
prop('number', 'NextTurnBlock', '0'),

34
tools/verify/cbprops.mjs Normal file
View File

@@ -0,0 +1,34 @@
// cb/*.mjs의 `self.<Field> = ` 대입 ↔ gen-slaydeck.mjs 선언 prop 대조.
// 미선언 prop에 대입하면 MSW 런타임 "cannot set X, no such field" → 그 후보를 정적 검출.
// 사용: node tools/verify/cbprops.mjs
import { readFileSync, readdirSync } from 'node:fs';
const orch = readFileSync('tools/deck/gen-slaydeck.mjs', 'utf8');
const declared = new Set();
for (const m of orch.matchAll(/prop\(\s*'[^']*'\s*,\s*'([^']+)'/g)) declared.add(m[1]);
// MSW 빌트인/설정으로 대입 가능한 self 필드(프롭 아님) — 오탐 제외 화이트리스트.
const BUILTIN = new Set(['Entity']);
const dir = 'tools/deck/cb';
const files = readdirSync(dir).filter((f) => f.endsWith('.mjs'));
const assigns = new Map(); // name -> Set(files)
for (const f of files) {
const src = readFileSync(`${dir}/${f}`, 'utf8');
// self.Name = (단, == / ~= / .Y= / [..]= 는 제외)
for (const m of src.matchAll(/self\.([A-Za-z_]\w*)\s*=(?!=)/g)) {
const name = m[1];
if (!assigns.has(name)) assigns.set(name, new Set());
assigns.get(name).add(f);
}
}
const missing = [...assigns.keys()]
.filter((n) => !declared.has(n) && !BUILTIN.has(n))
.sort();
console.log(`선언 prop: ${declared.size} | 대입된 self.X distinct: ${assigns.size}`);
console.log(`미선언 대입 (no such field 후보): ${missing.length}`);
for (const n of missing) console.log(` - ${n} [${[...assigns.get(n)].join(', ')}]`);
console.log(missing.length ? 'RESULT: MISSING PROPS ABOVE' : 'RESULT: 모든 self 대입이 선언됨 ✓');
process.exit(missing.length ? 1 : 0);