File size: 3,581 Bytes
c2b7eb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import type { Middleware, UnknownAction } from 'redux'
import type { ThunkMiddleware } from 'redux-thunk'
import { thunk as thunkMiddleware, withExtraArgument } from 'redux-thunk'
import type { ActionCreatorInvariantMiddlewareOptions } from './actionCreatorInvariantMiddleware'
import { createActionCreatorInvariantMiddleware } from './actionCreatorInvariantMiddleware'
import type { ImmutableStateInvariantMiddlewareOptions } from './immutableStateInvariantMiddleware'
/* PROD_START_REMOVE_UMD */
import { createImmutableStateInvariantMiddleware } from './immutableStateInvariantMiddleware'
/* PROD_STOP_REMOVE_UMD */

import type { SerializableStateInvariantMiddlewareOptions } from './serializableStateInvariantMiddleware'
import { createSerializableStateInvariantMiddleware } from './serializableStateInvariantMiddleware'
import type { ExcludeFromTuple } from './tsHelpers'
import { Tuple } from './utils'

function isBoolean(x: any): x is boolean {
  return typeof x === 'boolean'
}

interface ThunkOptions<E = any> {
  extraArgument: E
}

interface GetDefaultMiddlewareOptions {
  thunk?: boolean | ThunkOptions
  immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions
  serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions
  actionCreatorCheck?: boolean | ActionCreatorInvariantMiddlewareOptions
}

export type ThunkMiddlewareFor<
  S,
  O extends GetDefaultMiddlewareOptions = {},
> = O extends {
  thunk: false
}
  ? never
  : O extends { thunk: { extraArgument: infer E } }
    ? ThunkMiddleware<S, UnknownAction, E>
    : ThunkMiddleware<S, UnknownAction>

export type GetDefaultMiddleware<S = any> = <
  O extends GetDefaultMiddlewareOptions = {
    thunk: true
    immutableCheck: true
    serializableCheck: true
    actionCreatorCheck: true
  },
>(
  options?: O,
) => Tuple<ExcludeFromTuple<[ThunkMiddlewareFor<S, O>], never>>

export const buildGetDefaultMiddleware = <S = any>(): GetDefaultMiddleware<S> =>
  function getDefaultMiddleware(options) {
    const {
      thunk = true,
      immutableCheck = true,
      serializableCheck = true,
      actionCreatorCheck = true,
    } = options ?? {}

    let middlewareArray = new Tuple<Middleware[]>()

    if (thunk) {
      if (isBoolean(thunk)) {
        middlewareArray.push(thunkMiddleware)
      } else {
        middlewareArray.push(withExtraArgument(thunk.extraArgument))
      }
    }

    if (process.env.NODE_ENV !== 'production') {
      if (immutableCheck) {
        /* PROD_START_REMOVE_UMD */
        let immutableOptions: ImmutableStateInvariantMiddlewareOptions = {}

        if (!isBoolean(immutableCheck)) {
          immutableOptions = immutableCheck
        }

        middlewareArray.unshift(
          createImmutableStateInvariantMiddleware(immutableOptions),
        )
        /* PROD_STOP_REMOVE_UMD */
      }

      if (serializableCheck) {
        let serializableOptions: SerializableStateInvariantMiddlewareOptions =
          {}

        if (!isBoolean(serializableCheck)) {
          serializableOptions = serializableCheck
        }

        middlewareArray.push(
          createSerializableStateInvariantMiddleware(serializableOptions),
        )
      }
      if (actionCreatorCheck) {
        let actionCreatorOptions: ActionCreatorInvariantMiddlewareOptions = {}

        if (!isBoolean(actionCreatorCheck)) {
          actionCreatorOptions = actionCreatorCheck
        }

        middlewareArray.unshift(
          createActionCreatorInvariantMiddleware(actionCreatorOptions),
        )
      }
    }

    return middlewareArray as any
  }