main did not build, so every Portainer deploy failed with npm run build exit code 2. My regression from #241.
findOrFail(items: T[], predicate: (item: T) => boolean) infers T from both parameters. The call sites annotate the predicate as documentation, and the arrays come from .json(), which is any and offers no competing candidate — so T became the one-field shape written in the lambda and every caller failed on the field it actually wanted. Array.prototype.find has no such problem, which is why the code this replaced type-checked.
The four responses are now typed at their call sites, so T is inferred from real data and the predicates need no annotation. findOrFail additionally takes NoInfer on its predicate, so a stray annotation can never drive the element type again. The specs are better typed than before this change: .json() was plain any, and the annotations only ever documented a shape nothing enforced.
I did not catch this because I verified with a bare npx tsc --noEmit, and tsconfig.json is "include": ["src"] — it structurally cannot see tests/. The specs are checked by the second command in npm run build, which is the step Docker runs and the step that failed. Verified this time with npm run build itself, plus lint, the unit suite, and two consecutive full e2e passes.
main did not build, so every Portainer deploy failed with `npm run build` exit code 2. My regression from #241.
findOrFail<T>(items: T[], predicate: (item: T) => boolean) infers T from both parameters. The call sites annotate the predicate as documentation, and the arrays come from .json(), which is any and offers no competing candidate — so T became the one-field shape written in the lambda and every caller failed on the field it actually wanted. Array.prototype.find has no such problem, which is why the code this replaced type-checked.
The four responses are now typed at their call sites, so T is inferred from real data and the predicates need no annotation. findOrFail additionally takes NoInfer<T> on its predicate, so a stray annotation can never drive the element type again. The specs are better typed than before this change: `.json()` was plain any, and the annotations only ever documented a shape nothing enforced.
I did not catch this because I verified with a bare `npx tsc --noEmit`, and tsconfig.json is `"include": ["src"]` — it structurally cannot see tests/. The specs are checked by the second command in `npm run build`, which is the step Docker runs and the step that failed. Verified this time with `npm run build` itself, plus lint, the unit suite, and two consecutive full e2e passes.
Closes #254
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
main did not build, so every Portainer deploy failed with `npm run build` exit code 2. My regression from #241.
findOrFail<T>(items: T[], predicate: (item: T) => boolean) infers T from both parameters. The call sites annotate the predicate as documentation, and the arrays come from .json(), which is any and offers no competing candidate — so T became the one-field shape written in the lambda and every caller failed on the field it actually wanted. Array.prototype.find has no such problem, which is why the code this replaced type-checked.
The four responses are now typed at their call sites, so T is inferred from real data and the predicates need no annotation. findOrFail additionally takes NoInfer<T> on its predicate, so a stray annotation can never drive the element type again. The specs are better typed than before this change: `.json()` was plain any, and the annotations only ever documented a shape nothing enforced.
I did not catch this because I verified with a bare `npx tsc --noEmit`, and tsconfig.json is `"include": ["src"]` — it structurally cannot see tests/. The specs are checked by the second command in `npm run build`, which is the step Docker runs and the step that failed. Verified this time with `npm run build` itself, plus lint, the unit suite, and two consecutive full e2e passes.
Closes#254
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
main did not build, so every Portainer deploy failed with
npm run buildexit code 2. My regression from #241.findOrFail(items: T[], predicate: (item: T) => boolean) infers T from both parameters. The call sites annotate the predicate as documentation, and the arrays come from .json(), which is any and offers no competing candidate — so T became the one-field shape written in the lambda and every caller failed on the field it actually wanted. Array.prototype.find has no such problem, which is why the code this replaced type-checked.
The four responses are now typed at their call sites, so T is inferred from real data and the predicates need no annotation. findOrFail additionally takes NoInfer on its predicate, so a stray annotation can never drive the element type again. The specs are better typed than before this change:
.json()was plain any, and the annotations only ever documented a shape nothing enforced.I did not catch this because I verified with a bare
npx tsc --noEmit, and tsconfig.json is"include": ["src"]— it structurally cannot see tests/. The specs are checked by the second command innpm run build, which is the step Docker runs and the step that failed. Verified this time withnpm run builditself, plus lint, the unit suite, and two consecutive full e2e passes.Closes #254
Co-Authored-By: Claude Opus 5 noreply@anthropic.com