build: enable noUncheckedIndexedAccess#600
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7eaa83a04a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export function resolveMaestroString(value: string, context: MaestroParseContext): string { | ||
| return value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (match, key: string) => { | ||
| return Object.prototype.hasOwnProperty.call(context.env, key) ? context.env[key] : match; | ||
| return context.env[key] ?? match; |
There was a problem hiding this comment.
Use own-property checks for Maestro variables
When a Maestro flow references an unset variable whose name exists on Object.prototype (for example ${toString} or ${__proto__}), this now reads through the prototype and treats it as a defined env value instead of preserving the literal placeholder as before. Since context.env is a normal object, this can corrupt generated actions for those inputs; keep the own-property check (or use Object.hasOwn) before indexing.
Useful? React with 👍 / 👎.
| const value = scope.values[key]; | ||
| if (value !== undefined) return value; |
There was a problem hiding this comment.
Use own-property checks for replay variables
For an unset replay variable that collides with an inherited object property, such as ${toString} or ${__proto__}, this lookup now returns the prototype value and bypasses both the fallback and the unresolved-variable error. Because replay scopes are plain objects, this changes malformed/missing variables into substituted prototype strings; restore an own-property check before accepting the value.
Useful? React with 👍 / 👎.
a23c466 to
207b7d7
Compare
|
Summary
Enable TypeScript
noUncheckedIndexedAccessso uncheckedarray[index]andrecord[key]reads now surface as| undefinedduring typecheck instead of being assumed present.This improves codebase health by making each indexed access state its invariant: loop-bounded reads use targeted non-null assertions, parser/regex boundaries use explicit guards, and several call sites now use iteration APIs that avoid indexing entirely. The result is stricter compiler coverage across parsing, replay, selectors, dispatch, snapshot, platform, and test code without broad
anyor cast escapes.Before:
After:
The tuple guard captures the parser invariant once, then downstream code can destructure
targetandtextas present strings instead of repeating unchecked indexed reads.Touched 60 files. Scope stayed within TypeScript strictness fallout from enabling the compiler option.
Validation
pnpm formatpassed.pnpm check:toolingpassed: lint, typecheck, MCP metadata check, and build/declaration generation.Focused unit coverage passed for the touched strictness areas, including replay variables, Maestro replay parsing, selector parsing, React Native overlay handling, Android snapshot/scroll helpers, snapshot processing, snapshot diff, replay heal, find, snapshot handler, and CLI batch parsing.
The replay script parser test passed after the tuple-guard cleanup. The Maestro
runScript http.postcase passed when rerun outside the sandbox; inside the sandbox it can fail on local loopback/subprocess networking.Full
pnpm check:unitwas attempted but remains blocked in this local environment by unrelated local networking/subprocess failures (EADDRNOTAVAIL, test timeouts, and local tool command failures).