Skip to content

Commit

Permalink
Merge branch 'main' into fix/export-setup-class-instead-of-interface
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Jan 24, 2023
2 parents 0553ff6 + b4ac829 commit 914bae8
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 56 deletions.
4 changes: 2 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "msw",
"version": "0.49.1",
"version": "0.49.3",
"description": "Seamless REST/GraphQL API mocking library for browser and Node.js.",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
Expand Down Expand Up @@ -102,7 +102,7 @@
"node-fetch": "^2.6.7",
"outvariant": "^1.3.0",
"path-to-regexp": "^6.2.0",
"strict-event-emitter": "^0.2.6",
"strict-event-emitter": "^0.4.3",
"type-fest": "^2.19.0",
"yargs": "^17.3.1"
},
Expand Down
22 changes: 11 additions & 11 deletions src/SetupApi.ts
@@ -1,5 +1,5 @@
import { invariant } from 'outvariant'
import { EventMapType, StrictEventEmitter } from 'strict-event-emitter'
import { EventMap, Emitter } from 'strict-event-emitter'
import {
DefaultBodyType,
RequestHandler,
Expand All @@ -14,11 +14,11 @@ import { MockedRequest } from './utils/request/MockedRequest'
/**
* Generic class for the mock API setup.
*/
export abstract class SetupApi<EventsMap extends EventMapType> {
export abstract class SetupApi<EventsMap extends EventMap> {
protected initialHandlers: ReadonlyArray<RequestHandler>
protected currentHandlers: Array<RequestHandler>
protected readonly emitter: StrictEventEmitter<EventsMap>
protected readonly publicEmitter: StrictEventEmitter<EventsMap>
protected readonly emitter: Emitter<EventsMap>
protected readonly publicEmitter: Emitter<EventsMap>

public readonly events: LifeCycleEventEmitter<EventsMap>

Expand All @@ -28,8 +28,8 @@ export abstract class SetupApi<EventsMap extends EventMapType> {
this.initialHandlers = toReadonlyArray(initialHandlers)
this.currentHandlers = [...initialHandlers]

this.emitter = new StrictEventEmitter<EventsMap>()
this.publicEmitter = new StrictEventEmitter<EventsMap>()
this.emitter = new Emitter<EventsMap>()
this.publicEmitter = new Emitter<EventsMap>()
pipeEvents(this.emitter, this.publicEmitter)

this.events = this.createLifeCycleEvents()
Expand Down Expand Up @@ -81,13 +81,13 @@ export abstract class SetupApi<EventsMap extends EventMapType> {

private createLifeCycleEvents(): LifeCycleEventEmitter<EventsMap> {
return {
on: (...args) => {
return this.publicEmitter.on(...args)
on: (...args: any[]) => {
return (this.publicEmitter.on as any)(...args)
},
removeListener: (...args) => {
return this.publicEmitter.removeListener(...args)
removeListener: (...args: any[]) => {
return (this.publicEmitter.removeListener as any)(...args)
},
removeAllListeners: (...args: any) => {
removeAllListeners: (...args: any[]) => {
return this.publicEmitter.removeAllListeners(...args)
},
}
Expand Down
2 changes: 1 addition & 1 deletion src/context/fetch.ts
Expand Up @@ -8,7 +8,7 @@ const useFetch: (input: RequestInfo, init?: RequestInit) => Promise<Response> =
import('node-fetch').then(({ default: nodeFetch }) =>
(nodeFetch as unknown as typeof window.fetch)(input, init),
)
: window.fetch
: globalThis.fetch

export const augmentRequestInit = (requestInit: RequestInit): RequestInit => {
const headers = new Headers(requestInit.headers)
Expand Down
7 changes: 7 additions & 0 deletions src/index.ts
@@ -1,4 +1,5 @@
import * as context from './context'
import { checkGlobals } from './utils/internal/checkGlobals'
export { context }

export { setupWorker } from './setupWorker/setupWorker'
Expand Down Expand Up @@ -66,3 +67,9 @@ export type {
export type { Path, PathParams, Match } from './utils/matching/matchRequestUrl'
export type { DelayMode } from './context/delay'
export { ParsedGraphQLRequest } from './utils/internal/parseGraphQLRequest'

// Validate environmental globals before executing any code.
// This ensures that the library gives user-friendly errors
// when ran in the environments that require additional polyfills
// from the end user.
checkGlobals()
4 changes: 2 additions & 2 deletions src/setupWorker/glossary.ts
@@ -1,5 +1,5 @@
import { FlatHeadersObject } from 'headers-polyfill'
import { StrictEventEmitter } from 'strict-event-emitter'
import { Emitter } from 'strict-event-emitter'
import {
LifeCycleEventEmitter,
LifeCycleEventsMap,
Expand Down Expand Up @@ -103,7 +103,7 @@ export interface SetupWorkerInternalContext {
worker: ServiceWorker | null
registration: ServiceWorkerRegistration | null
requestHandlers: RequestHandler[]
emitter: StrictEventEmitter<WorkerLifecycleEventsMap>
emitter: Emitter<WorkerLifecycleEventsMap>
keepAliveInterval?: number
workerChannel: {
/**
Expand Down
22 changes: 10 additions & 12 deletions src/sharedOptions.ts
@@ -1,4 +1,4 @@
import { StrictEventEmitter } from 'strict-event-emitter'
import { Emitter } from 'strict-event-emitter'
import { MockedRequest } from './utils/request/MockedRequest'
import { UnhandledRequestStrategy } from './utils/request/onUnhandledRequest'

Expand All @@ -15,18 +15,16 @@ export interface SharedOptions {
}

export interface LifeCycleEventsMap<ResponseType> {
'request:start': (request: MockedRequest) => void
'request:match': (request: MockedRequest) => void
'request:unhandled': (request: MockedRequest) => void
'request:end': (request: MockedRequest) => void
'response:mocked': (response: ResponseType, requestId: string) => void
'response:bypass': (response: ResponseType, requestId: string) => void
unhandledException: (error: Error, request: MockedRequest) => void
'request:start': [MockedRequest]
'request:match': [MockedRequest]
'request:unhandled': [MockedRequest]
'request:end': [MockedRequest]
'response:mocked': [response: ResponseType, requestId: string]
'response:bypass': [response: ResponseType, requestId: string]
unhandledException: [error: Error, request: MockedRequest]
[key: string]: Array<unknown>
}

export type LifeCycleEventEmitter<
ResponseType extends Record<string | symbol, any>,
> = Pick<
StrictEventEmitter<ResponseType>,
'on' | 'removeListener' | 'removeAllListeners'
>
> = Pick<Emitter<ResponseType>, 'on' | 'removeListener' | 'removeAllListeners'>
4 changes: 2 additions & 2 deletions src/utils/handleRequest.test.ts
@@ -1,5 +1,5 @@
import { Headers } from 'headers-polyfill'
import { StrictEventEmitter } from 'strict-event-emitter'
import { Emitter } from 'strict-event-emitter'
import { ServerLifecycleEventsMap } from '../node/glossary'
import { SharedOptions } from '../sharedOptions'
import { RequestHandler } from '../handlers/RequestHandler'
Expand All @@ -18,7 +18,7 @@ const callbacks: Partial<Record<keyof HandleRequestOptions<any>, any>> = {
}

function setup() {
const emitter = new StrictEventEmitter<ServerLifecycleEventsMap>()
const emitter = new Emitter<ServerLifecycleEventsMap>()
const listener = jest.fn()

const createMockListener = (name: string) => {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/handleRequest.ts
@@ -1,5 +1,5 @@
import { until } from '@open-draft/until'
import { StrictEventEmitter } from 'strict-event-emitter'
import { Emitter } from 'strict-event-emitter'
import { RequestHandler } from '../handlers/RequestHandler'
import { ServerLifecycleEventsMap } from '../node/glossary'
import { MockedResponse } from '../response'
Expand Down Expand Up @@ -45,7 +45,7 @@ export async function handleRequest<
request: MockedRequest,
handlers: RequestHandler[],
options: RequiredDeep<SharedOptions>,
emitter: StrictEventEmitter<ServerLifecycleEventsMap>,
emitter: Emitter<ServerLifecycleEventsMap>,
handleRequestOptions?: HandleRequestOptions<ResponseType>,
): Promise<ResponseType | undefined> {
emitter.emit('request:start', request)
Expand Down
17 changes: 17 additions & 0 deletions src/utils/internal/checkGlobals.ts
@@ -0,0 +1,17 @@
import { invariant } from 'outvariant'
import { devUtils } from './devUtils'

export function checkGlobals() {
/**
* MSW expects the "URL" constructor to be defined.
* It's not present in React Native so suggest a polyfill
* instead of failing silently.
* @see https://github.com/mswjs/msw/issues/1408
*/
invariant(
typeof URL !== 'undefined',
devUtils.formatMessage(
`Global "URL" class is not defined. This likely means that you're running MSW in an environment that doesn't support all Node.js standard API (e.g. React Native). If that's the case, please use an appropriate polyfill for the "URL" class, like "react-native-url-polyfill".`,
),
)
}
8 changes: 4 additions & 4 deletions src/utils/internal/pipeEvents.ts
@@ -1,11 +1,11 @@
import { EventEmitter } from 'stream'
import { Emitter, EventMap } from 'strict-event-emitter'

/**
* Pipes all emitted events from one emitter to another.
*/
export function pipeEvents(
source: EventEmitter,
destination: EventEmitter,
export function pipeEvents<Events extends EventMap>(
source: Emitter<Events>,
destination: Emitter<Events>,
): void {
const rawEmit = source.emit

Expand Down
43 changes: 23 additions & 20 deletions yarn.lock
Expand Up @@ -3180,9 +3180,9 @@ babel-preset-minify@^0.5.1:
lodash "^4.17.11"

balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==

base64-js@^1.3.1:
version "1.5.1"
Expand Down Expand Up @@ -3792,7 +3792,7 @@ compression@^1.7.4:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==

connect-history-api-fallback@^1.6.0:
version "1.6.0"
Expand Down Expand Up @@ -4087,9 +4087,9 @@ decimal.js@^10.2.1:
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==

decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
version "0.2.2"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==

dedent@0.7.0:
version "0.7.0"
Expand Down Expand Up @@ -6829,9 +6829,9 @@ json3@^3.3.3:
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==

json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
dependencies:
minimist "^1.2.0"

Expand Down Expand Up @@ -7315,9 +7315,9 @@ minimalistic-assert@^1.0.0:
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==

minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"

Expand All @@ -7330,11 +7330,16 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"

minimist@1.2.5, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
minimist@1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==

minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==

mixin-deep@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
Expand Down Expand Up @@ -9225,12 +9230,10 @@ strict-event-emitter@^0.2.4:
dependencies:
events "^3.3.0"

strict-event-emitter@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.6.tgz#7bb2022bdabcbf0058cec7118a7bbbfd64367366"
integrity sha512-qDZOqEBoNtKLPb/qAutkXUt7hs3zXgYA1xX4pVa+gZHCZZVLr2r81AzHsK5YrQQhRNphMtkOUyAyOr9e1IxJTw==
dependencies:
events "^3.3.0"
strict-event-emitter@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.4.3.tgz#45d0f75e1dc071eeb7cfbdff864fd2b9172bc257"
integrity sha512-uD0y7Wp3+ifPyfzIS+JrMvSnxFExHytmD5gTkndF1fi8Vrk2uiOY/2At73AwzLHz+RwrchegD8tHdowsfG7raQ==

string-argv@^0.3.1:
version "0.3.1"
Expand Down

0 comments on commit 914bae8

Please sign in to comment.