Commit 25b23d8
fix(static-config): treat absent keys as NonStatic when object has spreads (#788)
## Summary
Fixes a correctness bug in the static vite config extractor: when the
config object contained a spread (`...base`) or computed key (`[k]: v`),
any field not explicitly declared after it was left **absent** from the
result map — and the consumer treated absent as "field definitely
doesn't exist", skipping NAPI entirely even when the spread might have
introduced that field.
## Root cause
```js
export default defineConfig({ ...base })
// `run` absent from map → consumer returned Ok(None), no NAPI
// But `base` might contain `run: { cacheScripts: true }` → silent misconfiguration
```
## Fix
Introduce `FieldMap` (opaque struct) backed by a `FieldMapInner` enum
with two variants:
- **`Closed`** — no spreads or computed keys; map is exhaustive; `get()`
returns `None` for absent keys (field definitely absent).
- **`Open`** — had at least one spread or computed key; `get()` returns
`Some(NonStatic)` for absent keys (may exist via the spread); only
`Json` values for keys explicitly declared after the last spread are
stored.
When a spread is encountered, the pre-spread accumulator is **cleared**
(not marked `NonStatic` one by one — those entries would all be
redundant in an `Open` map since absent already returns `NonStatic`).
Fields explicitly declared **after** the last spread are still
extractable as `Json`.
## Test coverage
- `spread_only`: `{ ...base }` → `get("run") = Some(NonStatic)` (was
wrongly `None`)
- `spread_then_explicit_run`: `{ ...base, run: { cacheScripts: true } }`
→ `get("run") = Some(Json({...}))` (post-spread still extracted)
- `no_spread_absent_is_none`: `{ plugins: [] }` → `get("run") = None`
(Closed, definitively absent)
- Updated existing spread/computed tests to match new semantics
53 unit tests, all passing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent fde23b2 commit 25b23d8
2 files changed
Lines changed: 235 additions & 148 deletions
0 commit comments