-
-
Couldn't load subscription status.
- Fork 562
Description
Scope
Improves an existing behavior
Compatibility
- This is a breaking change
Feature description
I'd like to propose enhancing the modularity and extensibility of the msw (mock-service-worker) library by officially exposing a broader set of internal utilities and TypeScript types. This change will help advanced users extend or customize core functionality (such as building custom handlers modeled after HttpHandler) without relying on unstable deep imports. The proposal is based on prior discussions with @kettanaito (https://discord.com/channels/1147615585732132865/1345284805507547136/1371545502184767662) and practical experience from my own custom implementation.
Motivation
- Reuse of Internal Logic: While extending
HttpHandler, I found it extremely helpful to access certain internal utilities (e.g., cookie parsing, URL handling, logging, and string utilities). However, these are not publicly exposed and require cloning the project and exposing which can break with internal changes on any updates (git pull) - Type Safety & Autocomplete: Many useful TypeScript types and interfaces are not accessible via stable, public paths. This increases friction for contributors and advanced users who wish to build robust, type-safe extensions.
- Community Impact: Streamlining access to these internals would unlock new integrations, tools, and customizations that are currently cumbersome or fragile to implement. It would empower the community to innovate on top of msw without risking compatibility issues from changing deep imports.
Functions & Types Proposed for Exposure
Utilities (already tested in my fork) exposed by myself in src/core/index.ts
export { devUtils } from './utils/internal/devUtils';
export { isStringEqual } from './utils/internal/isStringEqual';
export { getAllRequestCookies } from './utils/request/getRequestCookies';
export { toPublicUrl } from './utils/request/toPublicUrl';
export { serializeRequest } from './utils/logging/serializeRequest';
export { serializeResponse } from './utils/logging/serializeResponse';
export { getStatusCodeColor } from './utils/logging/getStatusCodeColor';
export { getTimestamp } from './utils/logging/getTimestamp';
export { getSearchParams } from './utils/url/cleanUrl';Types/Interfaces (current situation: require deep import)
Instead of:
import type {
HttpHandlerInfo,
HttpRequestParsedResult,
HttpRequestResolverExtras,
} from 'msw/lib/core/handlers/HttpHandler';Suggest:
import type {
HttpHandlerInfo,
HttpRequestParsedResult,
HttpRequestResolverExtras,
} from 'msw/types';- Other potential types/interfaces: request/response shapes, handler interfaces, payload types, URL-related types, etc.
Open Questions
-
Which Internal Utils to Expose?
- Some utilities are tightly coupled to internals and should remain private.
- Suggest reviewing all core
utilsand only exposing those that are broadly useful and unlikely to cause confusion/misuse. - Consider maintaining a whitelist and documenting each exposed function's intended usage.
-
How to Structure Type Exports?
- Should core types (
HttpHandler, request/response types, etc.) be grouped under a clearly named export (e.g.,msw/core)? - What are the criteria for "public" vs. "internal" types?
- Should core types (
Proposed Actions
- Expose the listed utilities and document their intended usage with short code examples.
- Identify and re-export the main TypeScript interfaces and generics required for advanced customization, making them available from a stable path (e.g.,
msw/coreormsw/types). - Add a small note to the documentation warning that non-exposed internal utilities may change without notice and should not be imported via deep paths.
Feedback & Next Steps
I'd appreciate input on which functions or types might be unsuitable for exposure or whether a different exposure strategy would be preferred. Once there's consensus, I'm happy to help prepare the PR with documentation and migration notes.