@zendesk/laika
Version:
Test, mock, intercept and modify Apollo Client's operations — in both browser and unit tests!
144 lines (121 loc) • 3.54 kB
text/typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
import type {
FetchResult,
NextLink,
Observable,
ObservableSubscription,
Operation,
} from '@apollo/client/core'
import type { Laika } from './laika'
interface SubscriptionObserver<T> {
closed: boolean
next: (value: T) => void
error: (errorValue: any) => void
complete: () => void
}
/** @ignore */
export type { FetchResult, NextLink, Operation } from '@apollo/client/core'
/** @ignore */
export type Variables = Operation['variables']
/** @ignore */
export type FetchResultSubscriptionObserver = SubscriptionObserver<FetchResult>
/** @ignore */
export type Subscription = ObservableSubscription
export type OnSubscribeCallback = (options: {
operation: Operation
observer: FetchResultSubscriptionObserver
removeCallback: () => void
}) => (() => void) | void
export type OperationObserverCallback = (
operation: Operation,
observer: FetchResultSubscriptionObserver,
) => void
export interface Result {
result?: FetchResult
error?: Error
}
export type ResultFn = (operation: Operation) => Result
export type ResultOrFn = Result | ResultFn
export interface SubscribeMeta {
operation: Operation
observer: FetchResultSubscriptionObserver
forward: NextLink
enablePassthrough: PassthroughEnableFn
disablePassthrough: PassthroughDisableFn
}
export type InterceptorFn = (
operation: Operation,
forward: NextLink,
) => Observable<FetchResult>
export type ManInTheMiddleFn = (
options: SubscribeMeta,
) => Observable<FetchResult>
export type PassthroughDisableFn = () => boolean
export type PassthroughEnableFn = (mitm?: ManInTheMiddleFn) => boolean
export type OnSubscribe = (options: SubscribeMeta) => () => void
export type MatcherFn = (operation: Operation) => boolean
export interface Behavior {
matcher: MatcherFn
onSubscribe: OnSubscribe
}
export interface MatcherObject {
operationName?: string
clientName?: string
feature?: string
variables?: Variables
}
/** [[include:matcher.md]] */
export type Matcher = MatcherFn | MatcherObject
export type RecordingElement = RecordingMarker | RecordingPoint
export type RecordingElementWithFixtureMeta =
| RecordingMarker
| RecordingPointWithFixtureMeta
export type RecordingElementWithFixtureData =
| RecordingMarker
| RecordingPointWithFixtureData
export interface RecordingPoint {
clientName: string
timeDelta: number
operationName: string | null | undefined
feature?: string
variables: Variables
type: 'push' | 'response:mutation' | 'response:query'
result: FetchResult
action: string
}
export type Replacements = {
key: string
value: unknown
}[]
export interface RecordingPointWithFixtureMeta extends RecordingPoint {
fixtureFnName: string
reuseFixture?: string
valueAsStringToVariableName?: Map<string, string>
replacedVariables?: Map<string, Replacements>
stringifiedResult?: string
}
export interface RecordingPointWithFixtureData
extends RecordingPointWithFixtureMeta {
fixtureFnString?: string
fixtureFnName: string
fixtureCallString: string
}
export interface RecordingMarker {
type: 'marker'
timeDelta: number
action: string
}
export type EventFilterFn = (event: RecordingElement) => boolean
export interface CreateLaikaLinkOptions {
clientName: string
globalPropertyName?: string
startLoggingImmediately?: boolean
onLaikaReady?: (laika: Laika) => void
}
// helpers
/** @ignore */
export type ArgsType<T extends (...args: any) => any> = T extends (
...args: infer R
) => any
? R
: any