Skip to content
Back to skills

Fetcher V6 Migration

ASecurity

Upgrade a project from Fetcher 5.x to 6.0. Use when asked to upgrade `@ahoo-wang/fetcher*` to 6; when hooks or options (Wow query hooks, data-monitor hooks, `setQuery`, `propagateError`) are missing from `@ahoo-wang/fetcher-react`; when deprecated `fetcher-wow`, `fetcher-generator` or `fetcher-viewer` must go; or when behavior changed after the upgrade. Decides stay-on-5.x versus upgrade, then rewrites usages. Not for new Fetcher code.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
ai-agentstypescriptrustgoreactapisecurity

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned October 7, 2026

npx -y skills add Ahoo-Wang/skills --skill fetcher-v6-migration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fetcher V6 Migration?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fetcher V6 Migration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ahoo-wang-fetcher-v6-migration/badge)](https://www.skillsdirectory.com/skills/ahoo-wang-fetcher-v6-migration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: fetcher-v6-migration
description: >
  Upgrade a project from Fetcher 5.x to 6.0. Use when asked to upgrade `@ahoo-wang/fetcher*` to 6; when hooks or options (Wow query hooks, data-monitor hooks, `setQuery`, `propagateError`) are missing from `@ahoo-wang/fetcher-react`; when deprecated `fetcher-wow`, `fetcher-generator` or `fetcher-viewer` must go; or when behavior changed after the upgrade. Decides stay-on-5.x versus upgrade, then rewrites usages. Not for new Fetcher code.
---

# fetcher-v6-migration

Fetcher **6.0.0 is published** (`latest` on npm). It does two breaking things: (1) the Wow-coupled packages left fetcher — `@ahoo-wang/fetcher-wow`, `@ahoo-wang/fetcher-generator` and `@ahoo-wang/fetcher-viewer` are **deprecated on npm** and replaced by Wow's `@ahoo-wang/wow-*` packages; (2) `@ahoo-wang/fetcher-react` is **redesigned around cancellation** (hooks and options removed, queries controlled, `execute` never rejects). `@ahoo-wang/fetcher`, `-decorator`, `-eventbus`, `-eventstream`, `-openai`, `-openapi`, `-storage` and `-cosec` keep their API but **change behavior** in ways that pass `tsc` (section 4). Source of truth: the fetcher repository's `docs/releases/v6.0.0.md`.

## 1. Check npm — never assume

```sh
npm view @ahoo-wang/fetcher dist-tags                       # latest: 6.x; release-5 only once a 5.x patch ships after 6.0
npm view @ahoo-wang/wow-client version peerDependencies     # 9.2.1 or later: fetcher peer ^5.1.5 || ^6.0.0
npm view @ahoo-wang/fetcher-wow deprecated                  # the deprecation message names the replacement
```

Wow 9.2.0 was the first stable release of `@ahoo-wang/wow-client`, `@ahoo-wang/wow-react`, `@ahoo-wang/wow-generator` and `@ahoo-wang/wow-view-engine`, but it required fetcher `^5.1.5`; **9.2.1 is the first to accept fetcher 6**. Install the version `npm view` prints (never below 9.2.1, never invented), and keep `wow-client` and `wow-react` on the **same** version (`wow-react` peers `wow-client` with a `~` range). Wow's migration guide: https://wow.ahoo.me/guide/typescript/migration. To stay on 5.x pin `^5.1.5`; use the `release-5` dist-tag only if `dist-tags` lists it.

## 2. Detect and decide

Run the grep checklist in `references/api.md`, then classify:

| Found                                                                     | Decision                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `@ahoo-wang/fetcher-viewer`, or any data-monitor hook                     | **Stay on 5.x** (`^5.1.5`, every `@ahoo-wang/fetcher*` package: the viewer peers `^5.0.0`). `@ahoo-wang/wow-view-engine` replaces the viewer with a different model and API; the data-monitor hooks have no replacement. |
| `@ahoo-wang/fetcher-wow`, `@ahoo-wang/fetcher-generator`, Wow query hooks | Upgrade in the order of section 3: Wow packages first (on 5.x), then fetcher 6.                                                                                                                                          |
| `@ahoo-wang/fetcher-react` hooks                                          | Upgrade, then **rewrite the hook calls** (section 3, step 5).                                                                                                                                                            |
| none of the above                                                         | Bump every `@ahoo-wang/fetcher*` to `^6.0.0` together, then run the behavior checks (section 4).                                                                                                                         |

Removed from `@ahoo-wang/fetcher-react` in 6.0:

- Wow query hooks, moved **unchanged** to `@ahoo-wang/wow-react`: `useSingleQuery`, `useListQuery`, `usePagedQuery`, `useCountQuery`, `useListStreamQuery` with `UseSingleQueryOptions`/`UseSingleQueryReturn`, `UseListQueryOptions`/`UseListQueryReturn`, `UsePagedQueryOptions`/`UsePagedQueryReturn`, `UseCountQueryOptions`/`UseCountQueryReturn`, `UseListStreamQueryOptions`/`UseListStreamQueryReturn`; and `useFetcherSingleQuery`, `useFetcherListQuery`, `useFetcherPagedQuery`, `useFetcherCountQuery`, `useFetcherListStreamQuery` with `UseFetcherSingleQueryOptions`/`UseFetcherSingleQueryReturn`, `UseFetcherListQueryOptions`/`UseFetcherListQueryReturn`, `UseFetcherPagedQueryOptions`/`UseFetcherPagedQueryReturn`, `UseFetcherCountQueryOptions`/`UseFetcherCountQueryReturn`, `UseFetcherListStreamQueryOptions`/`UseFetcherListStreamQueryReturn`. `@ahoo-wang/wow-react` has its own request state and does not depend on `@ahoo-wang/fetcher-react`, so the redesign below does not apply to them (their `setQuery` stays).
- Data-monitor hooks, **no replacement**: `useDataMonitor`, `UseDataMonitorOptions`, `UseDataMonitorReturn`, `DataMonitorService`, `dataMonitorService`, `DataMonitorNotificationConfig`, `useDataMonitorEventBus`, `UseDataMonitorEventBusReturn`, `DataChangedEvent`, `dataMonitorEventBus`.
- Redesign, **no replacement** (write your own or use a library such as ahooks): `useFullscreen`, `UseFullscreenOptions`, `UseFullscreenReturn`, `FullscreenProvider`, `FullscreenProviderProps`, `FullscreenContext`, `FullscreenContextValue`, `useFullscreenContext`, `getFullscreenElement`, `isFullscreen`, `enterFullscreen`, `exitFullscreen`, `addFullscreenChangeListener`, `removeFullscreenChangeListener`, `useRefs`, `UseRefsReturn`, `useForceUpdate`, `useMounted`, `useRequestId`, `UseRequestIdReturn`.
- Redesign, **replaced by a controlled `query`**: `useQueryState`, `useCancellableQueryState`, `UseQueryStateOptions`, `UseQueryStateReturn`, `isValidateQuery`; the `initialQuery` option and the returned `setQuery`/`getQuery` on `useQuery`, `useFetcherQuery`, the query API hooks and the debounced query hooks.
- Redesign, other: `propagateError` (read the state `execute` resolves to); `onBeforeExecute` and `OnBeforeExecuteCallback` (prepare arguments before `execute`); `PromiseStateCallbacks` and `usePromiseState`'s `onSuccess`/`onError` (use `useExecutePromise`'s); `run`/`cancel`/`isPending` on `useDebouncedQuery`/`useDebouncedFetcherQuery` (now `pending`, `flush()`, `execute()`).

`useFetcher`, `useFetcherQuery`, `useQuery`, `useExecutePromise`, `usePromiseState`, the debounced hooks, `createExecuteApiHooks`/`createQueryApiHooks`, the CoSec components, storage and event hooks stay. Do not confuse `useFetcherQuery` (kept) with `useFetcherPagedQuery` (moved).

## 3. Upgrade, in this order

1. **Latest 5.x first**: every `@ahoo-wang/fetcher*` package to `^5.1.5` (the Wow packages peer `^5.1.5`; `fetcher-react`'s `fetcher-wow` peer is optional from 5.1.3).
2. **Swap the moved packages while still on 5.x**: remove `@ahoo-wang/fetcher-wow` and `@ahoo-wang/fetcher-generator`; add `@ahoo-wang/wow-client` and `@ahoo-wang/wow-react` (and `-D @ahoo-wang/wow-generator`) at the version `npm view` printed; move the imports (diffs in `references/api.md`). The app keeps working on 5.x.
3. **Generator**: replace the `fetcher-generator` command with `wow-generator` (the old name stays an alias until Wow v10) and **regenerate** — code generated earlier imports `@ahoo-wang/fetcher-wow`; `wow-generator` emits `@ahoo-wang/wow-client`. If you cannot regenerate, rewrite that import.
4. **fetcher 6**: bump every remaining `@ahoo-wang/fetcher*` package to `^6.0.0` in one change (their sibling peers are `^6.0.0`; mixing 5 and 6 breaks peer resolution). `fetcher-react` 6 needs `react` `^19.0.0` and no longer peers `fetcher-eventstream` or `react-dom`.
5. **fetcher-react hooks**: run `tsc` and fix each error with the redesign table in `references/api.md`:
   - Query in your own state: `const [query, setQuery] = useState(initial)`, pass `query`; drop `initialQuery` and the hook's `setQuery`/`getQuery`. `useQuery`'s `execute` option is `(query, abortController)` (no `attributes`). Generated query hooks take `{ query, attributes }`.
   - `execute` never rejects: replace `propagateError: true` + `try/catch` with `const { status, result, error } = await execute(…)` and branch on `status` (`'idle'` when cancelled).
   - Debounced query hooks: `pending` and `flush()` replace `run`/`cancel`/`isPending()`; they auto-execute by default and run the first query at once.
   - Generated execute hooks: drop `onBeforeExecute`; `UseApiMethodExecuteOptions` lost its first type parameter; `appendAbortController: true` forwards the controller.
   - Still compiles, behaves differently: `reset()` cancels the in-flight request; `onAbort` is synchronous; `useFetcher` no longer writes `request.abortController`; a failed `useFetcher` exposes the failed `exchange`; an auto-executing query renders `loading` on its first render; `RouteGuard` calls `onUnauthorized` after commit; `useKeyStorage`/`useSecurity` render the default during SSR and hydration.
6. **Behavior checks** (section 4) for every package you use.
7. **Verify**: type-check, run the tests, re-run the grep checklist until only intended hits remain.

## 4. Behavior changes that type-check

The ones that most often break an app (full list with grep checks in `references/api.md`):

- **Errors** (`@ahoo-wang/fetcher`): a status failure rejects with the `HttpStatusValidationError` itself — test `error instanceof HttpStatusValidationError` (before `ExchangeError`, its superclass), not `error.cause`. An **error interceptor that throws** (including a CoSec `onUnauthorized`/`onForbidden` callback) no longer escapes raw: the call rejects with an `ExchangeError` whose `cause` is the thrown value, and later error interceptors do not run — a `catch` that tested for your own error class must read `error.cause`.
- **Requests** (`@ahoo-wang/fetcher`): no default `Content-Type` (only plain-object and string bodies get `application/json`); `undefined`/`null` query values are omitted, arrays repeat (`ids=1&ids=2`, was `ids=1%2C2`), a `Date` is ISO 8601; a missing or `null` path parameter throws `Missing required path parameter`; a timeout now also applies when a `signal` is passed.
- **CoSec** (`@ahoo-wang/fetcher-cosec`): a refresh that fails on a network error, timeout, abort or **5xx keeps the session** and rejects with `RefreshUnavailableError` (inside the call's `ExchangeError`, at `cause`), **without** `onUnauthorized` — only a 4xx or a malformed refresh response signs out with `RefreshTokenError`. A custom `TokenRefresher` must reject with an error carrying `exchange.response.status` for a rejection to sign out. Add `isTrusted: sameOriginTrust` unless every absolute URL the client requests is yours. Set a `timeout` on the refresh client: browser tabs now refresh one at a time under a Web Lock.
- **Streams**: a stream that ends before its terminating event (OpenAI `data: [DONE]`) rejects with `EventStreamIncompleteError`; `ChatResponse.usage` is optional.
- **Decorator**: an array `@query('ids')` is sent as `ids=1&ids=2` (was `0=1&1=2`); a named `@attribute('x')` object is stored whole; an undecorated subclass override runs as written.
- **CDN/UMD**: `dist/index.umd.js` → `dist/index.umd.cjs` in `fetcher-cosec`, `-eventbus`, `-openai`, `-openapi`, `-storage`, `-react`.

## References

- `references/api.md`: npm facts, package mapping, the removed-export tables, the fetcher-react redesign (table, diffs, behavior), subpaths, **behavior changes by package**, the detection checklist, rewrites, generated clients and staying on 5.x. Load it for detection and for any rewrite.

## Related Skills

- $fetcher-react-hooks: the 6.x API of `@ahoo-wang/fetcher-react`, for writing the rewritten hook calls.
- $fetcher-cosec-auth: the 6.x CoSec refresh, trust and 401/403 semantics.
- $fetcher-integration: the 6.x error classes and interceptor behavior of `@ahoo-wang/fetcher`.

Files in this skill

  • SKILL.md5.9 KB
  • agents/openai.yaml241 B
  • evals/generator-script/graders/criteria.md839 B
  • evals/generator-script/graders/must-name.md117 B
  • evals/generator-script/graders/skill-fired.md183 B
  • evals/generator-script/prompt.md309 B
  • evals/grep-checklist/graders/criteria.md805 B
  • evals/grep-checklist/graders/must-name.md107 B
  • evals/grep-checklist/graders/skill-fired.md183 B
  • evals/grep-checklist/prompt.md221 B
  • evals/new-client-setup/graders/skill-not-fired.md486 B
  • evals/new-client-setup/prompt.md216 B
  • evals/upgrade-react-app-with-wow/graders/criteria.md858 B
  • evals/upgrade-react-app-with-wow/graders/must-name.md107 B
  • evals/upgrade-react-app-with-wow/graders/skill-fired.md183 B
  • evals/upgrade-react-app-with-wow/prompt.md353 B
  • evals/use-data-monitor-removed/graders/criteria.md676 B
  • evals/use-data-monitor-removed/graders/must-name.md115 B
  • evals/use-data-monitor-removed/graders/skill-fired.md183 B
  • evals/use-data-monitor-removed/prompt.md277 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.