Followup to #447. The audit ran on \`as unknown as\` first; this PR
closes out \`as any\` separately. After this, \`grep -rn ' as any\\b'
apps/ packages/\` returns 0 (excluding tests and node_modules).
## Sites fixed
**\`apps/journal/server.ts\`** + **\`packages/jobs/src/types.ts\`** —
\`komootBulkImportJob as any\`. The job had a typed payload
(\`JobDefinition<KomootBulkImportData>\`) but the worker's
\`JobDefinition[]\` array forced a contravariance cast at every site
that mixed typed and untyped jobs. Dropped the generic from
\`JobDefinition\` entirely; handlers narrow their own \`job.data\`. Only
one job (komoot-bulk-import) used the generic, so the surface is tiny.
**\`apps/journal/app/lib/connected-services/fit.ts\`** + same pattern in
\`routes/sync.import.\$provider.server.ts\` — \`parser.parse(buffer as any,
(err: unknown, d: any) => ...)\`. fit-file-parser's TypeScript types
require \`Buffer<ArrayBuffer>\` specifically; a generic Node \`Buffer\`
is structurally \`Buffer<ArrayBufferLike>\` (which includes
SharedArrayBuffer). The runtime accepts either, so narrowed the cast
to \`as Buffer<ArrayBuffer>\` — still a cast, but precise about what
we're asserting and why. Removed the \`(err, d: any) => …\` ad-hoc
callback typings; the library exports a proper \`FitParserCallback\`.
**\`apps/mobile/lib/editor/RouteMap.tsx\`** — \`onLongPress\` handler
took \`(event: any)\`. maplibre-react-native v11 generates the event
type via React Native codegen but doesn't re-export it as a public
TypeScript type. Replaced with a local structural slice of the parts
we actually read.
Net: 4 \`as any\` sites in prod code → 0. \`pnpm typecheck\` / \`lint\` /
\`test\` all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v11 is a breaking API rework (renamed components, restructured props,
event payloads on nativeEvent) and requires React Native's new
architecture. Doing it as a manual migration instead of taking
dependabot's #268 because the renames need code changes.
Changes in apps/mobile:
- RouteMap.tsx — switch to named imports; rename MapView→Map,
ShapeSource→GeoJSONSource (with shape→data), LineLayer→Layer
(with type="line" and paint instead of style), MarkerView→
ViewAnnotation (with coordinate→lngLat); Camera uses
initialViewState with bounds as [w,s,e,n] and a separate padding
object; onLongPress reads lngLat from event.nativeEvent.
- app.config.ts — set `newArchEnabled: true`. MapLibre RN v11
supports only the new architecture, so Fabric/TurboModules must
be on for the Expo prebuild. Cast the config type since Expo SDK
55's ExpoConfig typings don't yet include the field (the runtime
does).
- package.json — `^10.4.2` → `^11.0.0`.
Supersedes dependabot #268; it'll auto-close once this merges.
Runtime verification requires an EAS dev build (native deps
changed + new arch flipped). JS-only surface typechecks + lints +
unit tests clean locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- RouteMap.tsx referenced undefined MapLibreRN namespace, causing
typecheck to fail on main and in every downstream PR
- metro.config.js is CommonJS, exclude from ESLint flat config
Changes that were pushed directly to main earlier bypassed CI and
broke both typecheck and lint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Metro couldn't resolve hoisted packages (@maplibre, @gorhom, etc.)
because it only looked in apps/mobile/node_modules. Configure
watchFolders and nodeModulesPaths to include the monorepo root.
Also revert MapLibre fallback — direct import is correct, the issue
was Metro resolution, not a missing native module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use try/catch require() for MapLibre so the app works without it
(shows fallback UI). Needed when running on builds that don't include
MapLibre native module (old EAS builds, Expo Go).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>