Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ dist-ssr
docs/plans/**

# tmp
.serena
e2e/playwright-report
e2e/test-results
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"editor.codeActionsOnSave": {
"source.fixAll.biome": "explicit"
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lock, pnpm-workspace.yaml, skills-lock.json"
},
"cSpell.words": []
}
8 changes: 3 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# CHANGELOG

All notable changes to this project will be documented in this file.

## 0.0.1

- Initialize the TypeScript library boilerplate.
- Add Changesets-based release automation.
- Document npm trusted publishing bootstrap and OIDC-based publishing.
- Initial release of `@hsblabs/fetch-interceptor`.
- Add interception support for browser `fetch` and `XMLHttpRequest`.
- Normalize intercepted traffic to standard `Request` and `Response` objects.
169 changes: 82 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,119 +1,114 @@
# @your-scope/your-package
# @hsblabs/fetch-interceptor

`@your-scope/your-package` is a boilerplate repository for building and publishing TypeScript libraries to npm.
Language:
[English](https://github.com/hsblabs/fetch-interceptor/blob/main/README.md)
| [日本語](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/ja.md)
| [简体中文](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/zh-CN.md)
| [한국어](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/ko.md)

It includes a strict TypeScript setup, `tsdown` for bundling, Vitest for unit tests, Biome for linting and formatting, and GitHub Actions workflows for CI and tagged publishes.
`@hsblabs/fetch-interceptor` is a lightweight TypeScript library for transparently intercepting browser `fetch` and `XMLHttpRequest` traffic.

The exported functions in `src/index.ts` are sample code. Replace them with your library API after you clone the template.
Its key feature is that intercepted requests and responses are normalized to the standard Web API `Request` and `Response` objects. That lets you inspect and process XHR traffic without dealing with XHR-specific lifecycle complexity.

The package name in this repository is intentionally a placeholder. This repository is the template, not the final library.
## Features

## Included Tooling
- Unified around standard APIs
Both fetch and XHR traffic can be handled through `Request` and `Response`.
- Fully type-safe
The API is predictable and comfortable to use in TypeScript.
- Safe lifecycle control
A factory-based API lets you start interception when needed and restore native browser APIs cleanly.
- Zero dependencies
The library stays small and easy to embed.
- Built for browser environments
The API is intentionally simple for frontend integrations.

- TypeScript with strict compiler settings
- `tsdown` for ESM builds and `.d.ts` generation
- Vitest for unit tests
- Biome for linting and formatting
- GitHub Actions for CI and npm publish
- `prepublishOnly` checks to block broken releases

## Quick Start
## Installation

```sh
pnpm install
pnpm test
pnpm build
npm install @hsblabs/fetch-interceptor
# or
yarn add @hsblabs/fetch-interceptor
# or
pnpm add @hsblabs/fetch-interceptor
```

To turn this repository into a real package, update these fields first:

- package name, description, keywords, repository URLs in `package.json`
- README package name and usage examples
- LICENSE copyright owner if needed
- sample exports in `src/index.ts`
- release details in `.changeset/config.json` if your repository conventions differ

## Development Commands
## Development

```sh
pnpm dev
pnpm lint
pnpm test
pnpm build
pnpm check
pnpm changeset
pnpm version-packages
pnpm release
pnpm test:e2e:node
pnpm test:e2e:browser
```

## Sample API
Before running browser E2E tests for the first time, install Playwright Chromium with `pnpm test:e2e:install`.

The current sample API demonstrates a few pure utilities that are easy to test and replace.
## Usage

The library is designed to stay small at the call site. The example below intercepts only a specific API route and extracts JSON from the response.

```ts
import { chunk, clamp, uniqueBy } from "@your-scope/your-package";

const bounded = clamp(14, { min: 0, max: 10 });
const groups = chunk([1, 2, 3, 4, 5], 2);
const deduped = uniqueBy(
[
{ id: "a", group: "x" },
{ id: "b", group: "x" },
{ id: "c", group: "y" },
],
(item) => item.group,
);

console.log({ bounded, groups, deduped });
import { createFetchInterceptor } from "@hsblabs/fetch-interceptor";

const interceptor = createFetchInterceptor({
matcher: (req) => {
const url = new URL(req.url);
return url.pathname.includes("/api/target-data") && req.method === "GET";
},
onIntercept: async (req, res) => {
try {
const data = await res.json();
console.log("Intercepted data:", data);

// For example, forward data from a Chrome extension's main world
// to an isolated world:
// window.postMessage({ type: "INTERCEPTED_DATA", payload: data }, "*");
} catch (error) {
console.error("Failed to parse intercepted response:", error);
}
},
});

interceptor.start();

// ...do work...

// interceptor.stop();
```

## Release Flow

This boilerplate uses Changesets for versioning and release PR management.
## API Reference

1. Add a release note with `pnpm changeset`.
2. Merge the feature PR into `main`.
3. The `publish.yml` workflow opens or updates a release PR.
4. Review and merge the release PR.
5. The same `publish.yml` workflow publishes the package from `main`.
### `createFetchInterceptor(options: FetchInterceptorOptions): FetchInterceptor`

## Trusted Publishing Bootstrap
Creates an interceptor instance used to start and stop traffic interception.

Because npm lets you attach a Trusted Publisher only after a package exists, there is still a one-time bootstrap step.
### `FetchInterceptorOptions`

Recommended operation:
| Property | Type | Description |
| --- | --- | --- |
| `matcher` | `((req: Request) => boolean)?` | Predicate that decides whether a request should be intercepted. When omitted, all matching traffic is intercepted. |
| `onIntercept` | `(req: Request, res: Response) => void` | Callback invoked when a matching request completes. `res` is a cloned response for fetch, or an equivalent standard `Response` for XHR. |

1. Publish the package once from your local machine.
2. Open the package settings on npmjs.com and add a Trusted Publisher.
3. Set the GitHub repository and the workflow filename to `publish.yml`.
4. Leave the environment name empty unless you intentionally protect the workflow with a GitHub Environment.
5. Verify that the next publish works through GitHub Actions.
6. After verification, disallow token-based publishing in npm package settings and revoke old publish tokens.
### `FetchInterceptor`

After bootstrap, later publishes should come from GitHub Actions with OIDC only.
| Method | Description |
| --- | --- |
| `start()` | Overrides `fetch` and `XMLHttpRequest` to begin interception. Calling it more than once is safe. |
| `stop()` | Stops interception and restores the original browser APIs. |

## Trusted Publisher Notes
## Use Cases

- Trusted publishing works only on GitHub-hosted runners.
- The publish workflow must keep `id-token: write`.
- For public packages from public repositories, npm generates provenance automatically when trusted publishing is used.
- If CI needs private npm dependencies, use a read-only npm token only for install steps, not for `npm publish`.
- Data extraction in browser extensions
Capture underlying REST or GraphQL responses directly from an SPA.
- Debugging and logging
Observe requests and responses for a specific API surface.
- Test instrumentation
Watch network activity and trigger test flow based on real responses.

## Project Structure
## Why This Library

```text
src/
index.ts
index.test.ts
.github/workflows/
ci.yml
publish.yml
.changeset/
docs/plans/
```
Cross-cutting browser traffic tooling gets messy when `fetch` and XHR need separate handling. `@hsblabs/fetch-interceptor` removes that split so you can focus on monitoring, extraction, debugging, and automation with a single `Request` / `Response` mental model.

## Notes
## License

- The package is ESM-first.
- Build artifacts are emitted to `dist/`.
- Only `dist/`, `README.md`, `CHANGELOG.md`, and `LICENSE` are published.
MIT
114 changes: 114 additions & 0 deletions docs/README/ja.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# @hsblabs/fetch-interceptor

言語:
[English](https://github.com/hsblabs/fetch-interceptor/blob/main/README.md)
| [日本語](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/ja.md)
| [简体中文](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/zh-CN.md)
| [한국어](https://github.com/hsblabs/fetch-interceptor/blob/main/docs/README/ko.md)

`@hsblabs/fetch-interceptor` は、ブラウザ上の `fetch` と `XMLHttpRequest` を透過的に傍受するための軽量な TypeScript ライブラリです。

最大の特長は、傍受したリクエストとレスポンスを標準 Web API の `Request` と `Response` に正規化して扱えることです。これにより、XHR 固有のライフサイクルの複雑さを意識せずに通信内容を解析できます。

## 特長

- 標準 API に統一
fetch と XHR の両方を `Request` / `Response` で扱えます。
- 完全な型安全
TypeScript で予測しやすく扱いやすい API です。
- 安全なライフサイクル制御
必要なときに傍受を開始し、不要になればネイティブ API をきれいに復元できます。
- 依存なし
小さく、組み込みやすい構成です。
- ブラウザ向け設計
フロントエンド統合を前提としたシンプルな API です。

## インストール

```sh
npm install @hsblabs/fetch-interceptor
# or
yarn add @hsblabs/fetch-interceptor
# or
pnpm add @hsblabs/fetch-interceptor
```

## 開発

```sh
pnpm test
pnpm test:e2e:node
pnpm test:e2e:browser
```

ブラウザ E2E テストを初回実行する前に、`pnpm test:e2e:install` で Playwright Chromium をインストールしてください。

## 使い方

呼び出し側は最小限で済むように設計されています。以下の例では、特定の API だけを傍受してレスポンス JSON を取り出します。

```ts
import { createFetchInterceptor } from "@hsblabs/fetch-interceptor";

const interceptor = createFetchInterceptor({
matcher: (req) => {
const url = new URL(req.url);
return url.pathname.includes("/api/target-data") && req.method === "GET";
},
onIntercept: async (req, res) => {
try {
const data = await res.json();
console.log("Intercepted data:", data);

// たとえば Chrome 拡張の main world から isolated world へ
// データを転送する場合:
// window.postMessage({ type: "INTERCEPTED_DATA", payload: data }, "*");
} catch (error) {
console.error("Failed to parse intercepted response:", error);
}
},
});

interceptor.start();

// ...処理...

// interceptor.stop();
```

## API リファレンス

### `createFetchInterceptor(options: FetchInterceptorOptions): FetchInterceptor`

通信傍受の開始と停止を制御するインスタンスを生成します。

### `FetchInterceptorOptions`

| プロパティ | 型 | 説明 |
| --- | --- | --- |
| `matcher` | `((req: Request) => boolean)?` | リクエストを傍受するかを判定する述語です。省略時はすべての通信を傍受します。 |
| `onIntercept` | `(req: Request, res: Response) => void` | 条件に一致した通信完了時に呼ばれるコールバックです。`res` は fetch では clone されたレスポンス、XHR では等価な標準 `Response` です。 |

### `FetchInterceptor`

| メソッド | 説明 |
| --- | --- |
| `start()` | `fetch` と `XMLHttpRequest` を上書きして傍受を開始します。複数回呼んでも安全です。 |
| `stop()` | 傍受を停止し、元のブラウザ API を復元します。 |

## ユースケース

- ブラウザ拡張でのデータ抽出
SPA が内部で呼ぶ REST や GraphQL のレスポンスを直接取得できます。
- デバッグとロギング
特定 API のリクエストとレスポンスを観測できます。
- テスト補助
実際のレスポンスを見ながらテストフローを制御できます。

## このライブラリが解決すること

ブラウザ通信の横断的な監視では、`fetch` と XHR を別々に扱うことが複雑さの原因になります。`@hsblabs/fetch-interceptor` はその分断をなくし、`Request` / `Response` を中心に監視、抽出、デバッグ、自動化へ集中できるようにします。

## ライセンス

MIT
Loading
Loading