Bump immer, redux and @reduxjs/toolkit (#110962) (#114341)

Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>

Co-authored-by: Thomas Watson <w@tson.dk>
Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2021-10-14 07:33:32 -04:00 committed by GitHub
parent 18fc38ed6a
commit 923aa4e99d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 143 additions and 126 deletions

View file

@ -168,7 +168,7 @@
"@mapbox/mapbox-gl-draw": "1.3.0",
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
"@mapbox/vector-tile": "1.3.1",
"@reduxjs/toolkit": "^1.5.1",
"@reduxjs/toolkit": "^1.6.1",
"@slack/webhook": "^5.0.4",
"@turf/along": "6.0.1",
"@turf/area": "6.0.1",
@ -252,7 +252,7 @@
"i18n-iso-countries": "^4.3.1",
"icalendar": "0.7.1",
"idx": "^2.5.6",
"immer": "^8.0.1",
"immer": "^9.0.6",
"inline-style": "^2.0.0",
"intl": "^1.2.5",
"intl-format-cache": "^2.1.0",
@ -361,7 +361,7 @@
"reactcss": "1.2.3",
"recompose": "^0.26.0",
"reduce-reducers": "^1.0.4",
"redux": "^4.0.5",
"redux": "^4.1.0",
"redux-actions": "^2.6.5",
"redux-devtools-extension": "^2.13.8",
"redux-logger": "^3.0.6",

View file

@ -7,10 +7,10 @@
import { KibanaContext } from 'src/plugins/data/common';
import {
AnyExpressionFunctionDefinition,
Datatable,
ExpressionValueFilter,
ExpressionImage,
ExpressionFunction,
PointSeries,
Render,
Style,
@ -34,7 +34,7 @@ export interface AppState {
interface StoreAppState {
basePath: string;
serverFunctions: ExpressionFunction[];
serverFunctions: AnyExpressionFunctionDefinition[];
ready: boolean;
}

View file

@ -6,7 +6,7 @@
*/
import React, { FC, useCallback } from 'react';
import { DeepPartial } from '@reduxjs/toolkit';
import { PreloadedState } from '@reduxjs/toolkit';
import { AppMountParameters, CoreSetup, CoreStart } from 'kibana/public';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
import { HashRouter, Route, RouteComponentProps, Switch } from 'react-router-dom';
@ -192,7 +192,7 @@ export async function mountApp(
const emptyState = getPreloadedState(storeDeps) as LensAppState;
const lensStore: LensRootStore = makeConfigureStore(storeDeps, {
lens: emptyState,
} as DeepPartial<LensState>);
} as PreloadedState<LensState>);
const EditorRenderer = React.memo(
(props: { id?: string; history: History<unknown>; editByValue?: boolean }) => {

View file

@ -16,7 +16,7 @@ import moment from 'moment';
import { Provider } from 'react-redux';
import { act } from 'react-dom/test-utils';
import { ReactExpressionRendererProps } from 'src/plugins/expressions/public';
import { DeepPartial } from '@reduxjs/toolkit';
import { PreloadedState } from '@reduxjs/toolkit';
import { LensPublicStart } from '.';
import { visualizationTypes } from './xy_visualization/types';
import { navigationPluginMock } from '../../../../src/plugins/navigation/public/mocks';
@ -479,7 +479,7 @@ export function makeLensStore({
resolvedDateRange: getResolvedDateRange(data.query.timefilter.timefilter),
...preloadedState,
},
} as DeepPartial<LensState>);
} as PreloadedState<LensState>);
const origDispatch = store.dispatch;
store.dispatch = jest.fn(dispatch || origDispatch);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { configureStore, getDefaultMiddleware, DeepPartial } from '@reduxjs/toolkit';
import { configureStore, getDefaultMiddleware, PreloadedState } from '@reduxjs/toolkit';
import { createLogger } from 'redux-logger';
import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux';
import { makeLensReducer, lensActions } from './lens_slice';
@ -36,7 +36,7 @@ export const {
export const makeConfigureStore = (
storeDeps: LensStoreDeps,
preloadedState: DeepPartial<LensState>
preloadedState: PreloadedState<LensState>
) => {
const middleware = [
...getDefaultMiddleware({

View file

@ -156,11 +156,11 @@ exports[`UploadLicense should display a modal when license requires acknowledgem
<Provider
store={
Object {
"@@observable": [Function],
"dispatch": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
Symbol(observable): [Function],
}
}
>
@ -1108,11 +1108,11 @@ exports[`UploadLicense should display an error when ES says license is expired 1
<Provider
store={
Object {
"@@observable": [Function],
"dispatch": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
Symbol(observable): [Function],
}
}
>
@ -1820,11 +1820,11 @@ exports[`UploadLicense should display an error when ES says license is invalid 1
<Provider
store={
Object {
"@@observable": [Function],
"dispatch": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
Symbol(observable): [Function],
}
}
>
@ -2532,11 +2532,11 @@ exports[`UploadLicense should display an error when submitting invalid JSON 1`]
<Provider
store={
Object {
"@@observable": [Function],
"dispatch": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
Symbol(observable): [Function],
}
}
>
@ -3244,11 +3244,11 @@ exports[`UploadLicense should display error when ES returns error 1`] = `
<Provider
store={
Object {
"@@observable": [Function],
"dispatch": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
Symbol(observable): [Function],
}
}
>

View file

@ -148,14 +148,13 @@ export const OsqueryManagedPolicyCreateImportExtension = React.memo<
// }, [editMode, replace]);
const scheduledQueryGroupTableData = useMemo(() => {
const policyWithoutEmptyQueries = produce<
NewPackagePolicy,
OsqueryManagerPackagePolicy,
OsqueryManagerPackagePolicy
>(newPolicy, (draft) => {
draft.inputs[0].streams = filter(['compiled_stream.id', null], draft.inputs[0].streams);
return draft;
});
const policyWithoutEmptyQueries = produce<NewPackagePolicy, OsqueryManagerPackagePolicy>(
newPolicy,
(draft) => {
draft.inputs[0].streams = filter(['compiled_stream.id', null], draft.inputs[0].streams);
return draft;
}
);
return policyWithoutEmptyQueries;
}, [newPolicy]);
@ -198,6 +197,7 @@ export const OsqueryManagedPolicyCreateImportExtension = React.memo<
<EuiFlexGroup>
<EuiFlexItem>
<ScheduledQueryGroupQueriesTable
// @ts-expect-error update
data={scheduledQueryGroupTableData.inputs[0].streams}
/>
</EuiFlexItem>

View file

@ -44,6 +44,7 @@ const PackQueriesFieldComponent = ({ field }) => {
(newQuery) =>
setValue(
produce((draft) => {
// @ts-expect-error update
draft.push({
interval: newQuery.interval,
query: newQuery.query.attributes.query,
@ -56,6 +57,7 @@ const PackQueriesFieldComponent = ({ field }) => {
);
const handleRemoveQuery = useCallback(
// @ts-expect-error update
(query) => setValue(produce((draft) => reject(['id', query.id], draft))),
[setValue]
);

View file

@ -138,33 +138,42 @@ const QueriesFieldComponent: React.FC<QueriesFieldProps> = ({
if (showEditQueryFlyout >= 0) {
setValue(
produce((draft) => {
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.id.value = updatedQuery.id;
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.interval.value = updatedQuery.interval;
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.query.value = updatedQuery.query;
if (updatedQuery.platform?.length) {
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.platform = {
type: 'text',
value: updatedQuery.platform,
};
} else {
// @ts-expect-error update
delete draft[0].streams[showEditQueryFlyout].vars.platform;
}
if (updatedQuery.version?.length) {
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.version = {
type: 'text',
value: updatedQuery.version,
};
} else {
// @ts-expect-error update
delete draft[0].streams[showEditQueryFlyout].vars.version;
}
if (updatedQuery.ecs_mapping) {
// @ts-expect-error update
draft[0].streams[showEditQueryFlyout].vars.ecs_mapping = {
value: updatedQuery.ecs_mapping,
};
} else {
// @ts-expect-error update
delete draft[0].streams[showEditQueryFlyout].vars.ecs_mapping;
}
@ -185,6 +194,7 @@ const QueriesFieldComponent: React.FC<QueriesFieldProps> = ({
setValue(
produce((draft) => {
draft[0].streams.push(
// @ts-expect-error update
getNewStream({
...newQuery,
scheduledQueryGroupId,
@ -221,6 +231,7 @@ const QueriesFieldComponent: React.FC<QueriesFieldProps> = ({
produce((draft) => {
forEach(parsedContent.queries, (newQuery, newQueryId) => {
draft[0].streams.push(
// @ts-expect-error update
getNewStream({
id: isOsqueryPackSupported ? newQueryId : `pack_${packName}_${newQueryId}`,
interval: newQuery.interval ?? parsedContent.interval,

View file

@ -317,7 +317,7 @@ export interface ECSMappingEditorFieldRef {
}
export interface ECSMappingEditorFieldProps {
field: FieldHook<string>;
field: FieldHook<Record<string, unknown>>;
query: string;
fieldRef: MutableRefObject<ECSMappingEditorFieldRef>;
}

View file

@ -5,10 +5,14 @@
* 2.0.
*/
import { IFieldSubType } from '@kbn/es-query';
import type { IIndexPattern } from 'src/plugins/data/public';
import { IEsSearchRequest, IEsSearchResponse } from '../../../../../../src/plugins/data/common';
import { DocValueFields, Maybe } from '../common';
import type { IFieldSubType } from '@kbn/es-query';
import type {
IEsSearchRequest,
IEsSearchResponse,
IIndexPattern,
} from '../../../../../../src/plugins/data/common';
import type { DocValueFields, Maybe } from '../common';
interface FieldInfo {
category: string;
@ -66,12 +70,7 @@ export interface BrowserField {
name: string;
searchable: boolean;
type: string;
subType?: {
[key: string]: unknown;
nested?: {
path: string;
};
};
subType?: IFieldSubType;
}
export type BrowserFields = Readonly<Record<string, Partial<BrowserField>>>;

View file

@ -12,7 +12,6 @@ import {
Action,
Store,
Dispatch,
PreloadedState,
StateFromReducersMapObject,
CombinedState,
} from 'redux';
@ -39,7 +38,7 @@ import { TimelineState } from '../timelines/store/timeline/types';
export { SecurityPageName } from '../../common/constants';
export interface SecuritySubPluginStore<K extends SecuritySubPluginKeyStore, T> {
initialState: Record<K, T | undefined>;
initialState: Record<K, T>;
reducer: Record<K, Reducer<T, AnyAction>>;
middleware?: Array<Middleware<{}, State, Dispatch<AppAction | Immutable<AppAction>>>>;
}
@ -70,14 +69,12 @@ export interface SecuritySubPluginWithStore<K extends SecuritySubPluginKeyStore,
export interface SecuritySubPlugins extends SecuritySubPlugin {
store: {
initialState: PreloadedState<
CombinedState<
StateFromReducersMapObject<
/** SubPluginsInitReducer, being an interface, will not work in `StateFromReducersMapObject`.
* Picking its keys does the trick.
**/
Pick<SubPluginsInitReducer, keyof SubPluginsInitReducer>
>
initialState: CombinedState<
StateFromReducersMapObject<
/** SubPluginsInitReducer, being an interface, will not work in `StateFromReducersMapObject`.
* Picking its keys does the trick.
**/
Pick<SubPluginsInitReducer, keyof SubPluginsInitReducer>
>
>;
reducer: SubPluginsInitReducer;

View file

@ -6,6 +6,7 @@
*/
import { parseExperimentalConfigValue } from '../../..//common/experimental_features';
import { SecuritySubPlugins } from '../../app/types';
import { createInitialState } from './reducer';
jest.mock('../lib/kibana', () => ({
@ -16,30 +17,28 @@ jest.mock('../lib/kibana', () => ({
describe('createInitialState', () => {
describe('sourcerer -> default -> indicesExist', () => {
const mockPluginState = {} as Omit<
SecuritySubPlugins['store']['initialState'],
'app' | 'dragAndDrop' | 'inputs' | 'sourcerer'
>;
test('indicesExist should be TRUE if configIndexPatterns is NOT empty', () => {
const initState = createInitialState(
{},
{
kibanaIndexPatterns: [{ id: '1234567890987654321', title: 'mock-kibana' }],
configIndexPatterns: ['auditbeat-*', 'filebeat'],
signalIndexName: 'siem-signals-default',
enableExperimental: parseExperimentalConfigValue([]),
}
);
const initState = createInitialState(mockPluginState, {
kibanaIndexPatterns: [{ id: '1234567890987654321', title: 'mock-kibana' }],
configIndexPatterns: ['auditbeat-*', 'filebeat'],
signalIndexName: 'siem-signals-default',
enableExperimental: parseExperimentalConfigValue([]),
});
expect(initState.sourcerer?.sourcererScopes.default.indicesExist).toEqual(true);
});
test('indicesExist should be FALSE if configIndexPatterns is empty', () => {
const initState = createInitialState(
{},
{
kibanaIndexPatterns: [{ id: '1234567890987654321', title: 'mock-kibana' }],
configIndexPatterns: [],
signalIndexName: 'siem-signals-default',
enableExperimental: parseExperimentalConfigValue([]),
}
);
const initState = createInitialState(mockPluginState, {
kibanaIndexPatterns: [{ id: '1234567890987654321', title: 'mock-kibana' }],
configIndexPatterns: [],
signalIndexName: 'siem-signals-default',
enableExperimental: parseExperimentalConfigValue([]),
});
expect(initState.sourcerer?.sourcererScopes.default.indicesExist).toEqual(false);
});

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { combineReducers, PreloadedState, AnyAction, Reducer } from 'redux';
import { combineReducers, AnyAction, Reducer } from 'redux';
import { appReducer, initialAppState } from './app';
import { dragAndDropReducer, initialDragAndDropState } from './drag_and_drop';
@ -34,7 +34,10 @@ export type SubPluginsInitReducer = HostsPluginReducer &
* Factory for the 'initialState' that is used to preload state into the Security App's redux store.
*/
export const createInitialState = (
pluginsInitState: SecuritySubPlugins['store']['initialState'],
pluginsInitState: Omit<
SecuritySubPlugins['store']['initialState'],
'app' | 'dragAndDrop' | 'inputs' | 'sourcerer'
>,
{
kibanaIndexPatterns,
configIndexPatterns,
@ -46,11 +49,11 @@ export const createInitialState = (
signalIndexName: string | null;
enableExperimental: ExperimentalFeatures;
}
): PreloadedState<State> => {
const preloadedState: PreloadedState<State> = {
): State => {
const preloadedState: State = {
...pluginsInitState,
app: { ...initialAppState, enableExperimental },
dragAndDrop: initialDragAndDropState,
...pluginsInitState,
inputs: createInitialInputsState(),
sourcerer: {
...sourcererModel.initialSourcererState,
@ -66,6 +69,7 @@ export const createInitialState = (
signalIndexName,
},
};
return preloadedState;
};

View file

@ -27,7 +27,7 @@ export interface ManageScope {
docValueFields: DocValueFields[];
errorMessage: string | null;
id: SourcererScopeName;
indexPattern: IIndexPattern;
indexPattern: Omit<IIndexPattern, 'fieldFormatMap'>;
indicesExist: boolean | undefined | null;
loading: boolean;
selectedPatterns: string[];
@ -37,9 +37,7 @@ export interface ManageScopeInit extends Partial<ManageScope> {
id: SourcererScopeName;
}
export type SourcererScopeById = {
[id in SourcererScopeName]: ManageScope;
};
export type SourcererScopeById = Record<SourcererScopeName | string, ManageScope>;
export type KibanaIndexPatterns = Array<{ id: string; title: string }>;
@ -51,7 +49,16 @@ export interface SourcererModel {
sourcererScopes: SourcererScopeById;
}
export const initSourcererScope = {
export const initSourcererScope: Pick<
ManageScope,
| 'browserFields'
| 'docValueFields'
| 'errorMessage'
| 'indexPattern'
| 'indicesExist'
| 'loading'
| 'selectedPatterns'
> = {
browserFields: EMPTY_BROWSER_FIELDS,
docValueFields: EMPTY_DOCVALUE_FIELD,
errorMessage: null,

View file

@ -49,7 +49,7 @@ let store: Store<State, Action> | null = null;
* Factory for Security App's redux store.
*/
export const createStore = (
state: PreloadedState<State>,
state: State,
pluginsReducer: SubPluginsInitReducer,
kibana: Observable<CoreStart>,
storage: Storage,
@ -74,7 +74,7 @@ export const createStore = (
store = createReduxStore(
createReducer(pluginsReducer),
state,
state as PreloadedState<State>,
composeEnhancers(
applyMiddleware(epicMiddleware, telemetryMiddleware, ...(additionalMiddleware ?? []))
)

View file

@ -42,7 +42,12 @@ export class Management {
routes,
store: {
initialState: {
management: undefined,
/**
* Cast the state to ManagementState for compatibility with
* the subplugin architecture (which expects initialize state.)
* but you do not need it because this plugin is doing it through its middleware
*/
management: {} as ManagementState,
},
/**
* Cast the ImmutableReducer to a regular reducer for compatibility with

View file

@ -293,7 +293,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
cases: new subPluginClasses.Cases(),
hosts: new subPluginClasses.Hosts(),
network: new subPluginClasses.Network(),
...(this.experimentalFeatures.uebaEnabled ? { ueba: new subPluginClasses.Ueba() } : {}),
ueba: new subPluginClasses.Ueba(),
overview: new subPluginClasses.Overview(),
timelines: new subPluginClasses.Timelines(),
management: new subPluginClasses.Management(),
@ -319,9 +319,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
cases: subPlugins.cases.start(),
hosts: subPlugins.hosts.start(storage),
network: subPlugins.network.start(storage),
...(this.experimentalFeatures.uebaEnabled && subPlugins.ueba != null
? { ueba: subPlugins.ueba.start(storage) }
: {}),
ueba: subPlugins.ueba.start(storage),
timelines: subPlugins.timelines.start(),
management: subPlugins.management.start(core, plugins),
};
@ -375,7 +373,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
timeline: {
...subPlugins.timelines.store.initialState.timeline!,
timelineById: {
...subPlugins.timelines.store.initialState.timeline!.timelineById,
...subPlugins.timelines.store.initialState.timeline.timelineById,
...subPlugins.alerts.storageTimelines!.timelineById,
...subPlugins.rules.storageTimelines!.timelineById,
...subPlugins.exceptions.storageTimelines!.timelineById,
@ -400,9 +398,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
{
...subPlugins.hosts.store.initialState,
...subPlugins.network.store.initialState,
...(this.experimentalFeatures.uebaEnabled && subPlugins.ueba != null
? subPlugins.ueba.store.initialState
: {}),
...subPlugins.ueba.store.initialState,
...timelineInitialState,
...subPlugins.management.store.initialState,
},

View file

@ -96,8 +96,7 @@ export interface SubPlugins {
cases: Cases;
hosts: Hosts;
network: Network;
// TODO: Steph/ueba require ueba once no longer experimental
ueba?: Ueba;
ueba: Ueba;
overview: Overview;
timelines: Timelines;
management: Management;
@ -111,8 +110,7 @@ export interface StartedSubPlugins {
cases: ReturnType<Cases['start']>;
hosts: ReturnType<Hosts['start']>;
network: ReturnType<Network['start']>;
// TODO: Steph/ueba require ueba once no longer experimental
ueba?: ReturnType<Ueba['start']>;
ueba: ReturnType<Ueba['start']>;
overview: ReturnType<Overview['start']>;
timelines: ReturnType<Timelines['start']>;
management: ReturnType<Management['start']>;

View file

@ -67,12 +67,7 @@ export interface BrowserField {
name: string;
searchable: boolean;
type: string;
subType?: {
[key: string]: unknown;
nested?: {
path: string;
};
};
subType?: IFieldSubType;
}
export type BrowserFields = Readonly<Record<string, Partial<BrowserField>>>;

View file

@ -468,7 +468,7 @@ export enum TimelineTabs {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type EmptyObject = Record<any, never>;
type EmptyObject = Partial<Record<any, never>>;
export type TimelineExpandedEventType =
| {
@ -512,9 +512,9 @@ export type TimelineExpandedDetailType =
| TimelineExpandedHostType
| TimelineExpandedNetworkType;
export type TimelineExpandedDetail = {
[tab in TimelineTabs]?: TimelineExpandedDetailType;
};
export type TimelineExpandedDetail = Partial<
Record<TimelineTabs | string, TimelineExpandedDetailType>
>;
export type ToggleDetailPanel = TimelineExpandedDetailType & {
tabType?: TimelineTabs;

View file

@ -16,6 +16,8 @@ import type {
ColumnHeaderOptions,
DataProvider,
SortColumnTimeline,
TimelineExpandedDetail,
TimelineExpandedDetailType,
} from '../../../common/types/timeline';
import { getTGridManageDefaults, tGridDefaults } from './defaults';
@ -412,22 +414,20 @@ export const setSelectedTimelineEvents = ({
};
};
export const updateTimelineDetailsPanel = (action: ToggleDetailPanel) => {
const { tabType } = action;
export const updateTimelineDetailsPanel = (action: ToggleDetailPanel): TimelineExpandedDetail => {
const { tabType, timelineId, ...expandedDetails } = action;
const panelViewOptions = new Set(['eventDetail', 'hostDetail', 'networkDetail']);
const expandedTabType = tabType ?? TimelineTabs.query;
return action.panelView && panelViewOptions.has(action.panelView)
? {
[expandedTabType]: {
params: action.params ? { ...action.params } : {},
panelView: action.panelView,
},
}
: {
[expandedTabType]: {},
};
const newExpandDetails = {
params: expandedDetails.params ? { ...expandedDetails.params } : {},
panelView: expandedDetails.panelView,
} as TimelineExpandedDetailType;
return {
[expandedTabType]: panelViewOptions.has(expandedDetails.panelView ?? '')
? newExpandDetails
: {},
};
};
export const addProviderToTimelineHelper = (

View file

@ -197,7 +197,7 @@ exports[`useUrlParams deletes keys that do not have truthy values 1`] = `
},
],
},
Symbol(observable): [MockFunction],
"undefined": [MockFunction],
}
}
>
@ -427,7 +427,7 @@ exports[`useUrlParams gets the expected values using the context 1`] = `
},
],
},
Symbol(observable): [MockFunction],
"undefined": [MockFunction],
}
}
>

View file

@ -4757,13 +4757,13 @@
resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204"
integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg==
"@reduxjs/toolkit@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.5.1.tgz#05daa2f6eebc70dc18cd98a90421fab7fa565dc5"
integrity sha512-PngZKuwVZsd+mimnmhiOQzoD0FiMjqVks6ituO1//Ft5UEX5Ca9of13NEjo//pU22Jk7z/mdXVsmDfgsig1osA==
"@reduxjs/toolkit@^1.6.1":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.6.1.tgz#7bc83b47352a663bf28db01e79d17ba54b98ade9"
integrity sha512-pa3nqclCJaZPAyBhruQtiRwtTjottRrVJqziVZcWzI73i6L3miLTtUyWfauwv08HWtiXLx1xGyGt+yLFfW/d0A==
dependencies:
immer "^8.0.1"
redux "^4.0.0"
immer "^9.0.1"
redux "^4.1.0"
redux-thunk "^2.3.0"
reselect "^4.0.0"
@ -16858,11 +16858,16 @@ immediate@~3.0.5:
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
immer@8.0.1, immer@^8.0.1:
immer@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==
immer@^9.0.1, immer@^9.0.6:
version "9.0.6"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73"
integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ==
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@ -24905,13 +24910,12 @@ redux-thunks@^1.0.0:
resolved "https://registry.yarnpkg.com/redux-thunks/-/redux-thunks-1.0.0.tgz#56e03b86d281a2664c884ab05c543d9ab1673658"
integrity sha1-VuA7htKBomZMiEqwXFQ9mrFnNlg=
redux@^4.0.0, redux@^4.0.4, redux@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==
redux@^4.0.0, redux@^4.0.4, redux@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.1.tgz#76f1c439bb42043f985fbd9bf21990e60bd67f47"
integrity sha512-hZQZdDEM25UY2P493kPYuKqviVwZ58lEmGQNeQ+gXa+U0gYPUBf7NKYazbe3m+bs/DzM/ahN12DbF+NG8i0CWw==
dependencies:
loose-envify "^1.4.0"
symbol-observable "^1.2.0"
"@babel/runtime" "^7.9.2"
reflect.ownkeys@^0.2.0:
version "0.2.0"