mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-25 11:03:57 +03:00
feat(extension): replace whitelist/blacklist with allowlist/denylist (#851)
This commit is contained in:
parent
1695dee135
commit
42728c2114
|
@ -100,7 +100,7 @@ To specify [extension’s options](https://github.com/zalmoxisus/redux-devtools-
|
|||
const composeEnhancers =
|
||||
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
|
||||
// Specify extension’s options like name, actionsDenylist, actionsCreators, serialize...
|
||||
})
|
||||
: compose;
|
||||
|
||||
|
@ -143,7 +143,7 @@ import { createStore, applyMiddleware } from 'redux';
|
|||
import { composeWithDevTools } from 'redux-devtools-extension';
|
||||
|
||||
const composeEnhancers = composeWithDevTools({
|
||||
// Specify name here, actionsBlacklist, actionsCreators and other options if needed
|
||||
// Specify name here, actionsDenylist, actionsCreators and other options if needed
|
||||
});
|
||||
const store = createStore(
|
||||
reducer,
|
||||
|
@ -165,7 +165,7 @@ import { devToolsEnhancer } from 'redux-devtools-extension';
|
|||
const store = createStore(
|
||||
reducer,
|
||||
/* preloadedState, */ devToolsEnhancer()
|
||||
// Specify name here, actionsBlacklist, actionsCreators and other options if needed
|
||||
// Specify name here, actionsDenylist, actionsCreators and other options if needed
|
||||
);
|
||||
```
|
||||
|
||||
|
|
|
@ -240,9 +240,9 @@ const store = createStore(
|
|||
);
|
||||
```
|
||||
|
||||
### `actionsBlacklist` / `actionsWhitelist`
|
||||
### `actionsDenylist` / `actionsAllowlist`
|
||||
|
||||
_string or array of strings as regex_ - actions types to be hidden / shown in the monitors (while passed to the reducers). If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
|
||||
_string or array of strings as regex_ - actions types to be hidden / shown in the monitors (while passed to the reducers). If `actionsAllowlist` specified, `actionsDenylist` is ignored.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -251,16 +251,16 @@ createStore(
|
|||
reducer,
|
||||
remotedev({
|
||||
sendTo: 'http://localhost:8000',
|
||||
actionsBlacklist: 'SOME_ACTION',
|
||||
// or actionsBlacklist: ['SOME_ACTION', 'SOME_OTHER_ACTION']
|
||||
// or just actionsBlacklist: 'SOME_' to omit both
|
||||
actionsDenylist: 'SOME_ACTION',
|
||||
// or actionsDenylist: ['SOME_ACTION', 'SOME_OTHER_ACTION']
|
||||
// or just actionsDenylist: 'SOME_' to omit both
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
### `predicate`
|
||||
|
||||
_function_ - called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor. Use it as a more advanced version of `actionsBlacklist`/`actionsWhitelist` parameters.
|
||||
_function_ - called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor. Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
|
||||
Example of usage:
|
||||
|
||||
```js
|
||||
|
|
|
@ -65,13 +65,13 @@ const store = createStore(
|
|||
/* preloadedState, */ compose(
|
||||
devToolsEnhancer({
|
||||
instaceID: 1,
|
||||
name: 'Blacklisted',
|
||||
actionsBlacklist: '...',
|
||||
name: 'Denylisted',
|
||||
actionsDenylist: '...',
|
||||
}),
|
||||
devToolsEnhancer({
|
||||
instaceID: 2,
|
||||
name: 'Whitelisted',
|
||||
actionsWhitelist: '...',
|
||||
name: 'Allowlisted',
|
||||
actionsAllowlist: '...',
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
|
@ -5,13 +5,13 @@ import { LiftedState, PerformAction } from '@redux-devtools/instrument';
|
|||
|
||||
export type FilterStateValue =
|
||||
| 'DO_NOT_FILTER'
|
||||
| 'BLACKLIST_SPECIFIC'
|
||||
| 'WHITELIST_SPECIFIC';
|
||||
| 'DENYLIST_SPECIFIC'
|
||||
| 'ALLOWLIST_SPECIFIC';
|
||||
|
||||
export const FilterState: { [K in FilterStateValue]: FilterStateValue } = {
|
||||
DO_NOT_FILTER: 'DO_NOT_FILTER',
|
||||
BLACKLIST_SPECIFIC: 'BLACKLIST_SPECIFIC',
|
||||
WHITELIST_SPECIFIC: 'WHITELIST_SPECIFIC',
|
||||
DENYLIST_SPECIFIC: 'DENYLIST_SPECIFIC',
|
||||
ALLOWLIST_SPECIFIC: 'ALLOWLIST_SPECIFIC',
|
||||
};
|
||||
|
||||
function isArray(arg: unknown): arg is readonly unknown[] {
|
||||
|
@ -19,19 +19,17 @@ function isArray(arg: unknown): arg is readonly unknown[] {
|
|||
}
|
||||
|
||||
interface LocalFilter {
|
||||
readonly whitelist: string | undefined;
|
||||
readonly blacklist: string | undefined;
|
||||
readonly allowlist: string | undefined;
|
||||
readonly denylist: string | undefined;
|
||||
}
|
||||
|
||||
export function getLocalFilter(config: Config): LocalFilter | undefined {
|
||||
if (config.actionsBlacklist || config.actionsWhitelist) {
|
||||
const denylist = config.actionsDenylist ?? config.actionsBlacklist;
|
||||
const allowlist = config.actionsAllowlist ?? config.actionsWhitelist;
|
||||
if (denylist || allowlist) {
|
||||
return {
|
||||
whitelist: isArray(config.actionsWhitelist)
|
||||
? config.actionsWhitelist.join('|')
|
||||
: config.actionsWhitelist,
|
||||
blacklist: isArray(config.actionsBlacklist)
|
||||
? config.actionsBlacklist.join('|')
|
||||
: config.actionsBlacklist,
|
||||
allowlist: isArray(allowlist) ? allowlist.join('|') : allowlist,
|
||||
denylist: isArray(denylist) ? denylist.join('|') : denylist,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
|
@ -56,11 +54,11 @@ export function isFiltered<A extends Action<unknown>>(
|
|||
return false;
|
||||
}
|
||||
|
||||
const { whitelist, blacklist } = localFilter || window.devToolsOptions || {};
|
||||
const { allowlist, denylist } = localFilter || window.devToolsOptions || {};
|
||||
const actionType = ((action as A).type || action) as string;
|
||||
return (
|
||||
(whitelist && !actionType.match(whitelist)) ||
|
||||
(blacklist && actionType.match(blacklist))
|
||||
(allowlist && !actionType.match(allowlist)) ||
|
||||
(denylist && actionType.match(denylist))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ let reportId: string | null | undefined;
|
|||
function deprecateParam(oldParam: string, newParam: string) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(
|
||||
`${oldParam} parameter is deprecated, use ${newParam} instead: https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md`
|
||||
`${oldParam} parameter is deprecated, use ${newParam} instead: https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md`
|
||||
);
|
||||
/* eslint-enable no-console */
|
||||
}
|
||||
|
@ -84,8 +84,16 @@ export interface SerializeWithImmutable extends Serialize {
|
|||
|
||||
export interface ConfigWithExpandedMaxAge {
|
||||
instanceId?: number;
|
||||
/**
|
||||
* @deprecated Use actionsDenylist instead.
|
||||
*/
|
||||
readonly actionsBlacklist?: string | readonly string[];
|
||||
/**
|
||||
* @deprecated Use actionsAllowlist instead.
|
||||
*/
|
||||
readonly actionsWhitelist?: string | readonly string[];
|
||||
readonly actionsDenylist?: string | readonly string[];
|
||||
readonly actionsAllowlist?: string | readonly string[];
|
||||
serialize?: boolean | SerializeWithImmutable;
|
||||
readonly serializeState?:
|
||||
| boolean
|
||||
|
@ -213,6 +221,14 @@ function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<unknown>>(
|
|||
latency = 500,
|
||||
} = config;
|
||||
|
||||
// Deprecate actionsWhitelist and actionsBlacklist
|
||||
if (config.actionsWhitelist) {
|
||||
deprecateParam('actionsWhiteList', 'actionsAllowlist');
|
||||
}
|
||||
if (config.actionsBlacklist) {
|
||||
deprecateParam('actionsBlacklist', 'actionsDenylist');
|
||||
}
|
||||
|
||||
// Deprecate statesFilter and actionsFilter
|
||||
if (statesFilter) {
|
||||
deprecateParam('statesFilter', 'stateSanitizer');
|
||||
|
|
|
@ -29,8 +29,8 @@ export default ({ options, saveOption }: OptionsProps) => {
|
|||
id="filter-hide"
|
||||
name="filter"
|
||||
type="radio"
|
||||
checked={options.filter === FilterState.BLACKLIST_SPECIFIC}
|
||||
onChange={() => saveOption('filter', FilterState.BLACKLIST_SPECIFIC)}
|
||||
checked={options.filter === FilterState.DENYLIST_SPECIFIC}
|
||||
onChange={() => saveOption('filter', FilterState.DENYLIST_SPECIFIC)}
|
||||
/>
|
||||
<label className="option__label" htmlFor="filter-hide">
|
||||
Hide the following:
|
||||
|
@ -38,9 +38,9 @@ export default ({ options, saveOption }: OptionsProps) => {
|
|||
<br />
|
||||
<textarea
|
||||
className="option__textarea"
|
||||
value={options.blacklist}
|
||||
disabled={options.filter !== FilterState.BLACKLIST_SPECIFIC}
|
||||
onChange={(e) => saveOption('blacklist', e.target.value)}
|
||||
value={options.denylist}
|
||||
disabled={options.filter !== FilterState.DENYLIST_SPECIFIC}
|
||||
onChange={(e) => saveOption('denylist', e.target.value)}
|
||||
/>
|
||||
<div className="option__hint">Each action from the new line</div>
|
||||
</div>
|
||||
|
@ -51,8 +51,8 @@ export default ({ options, saveOption }: OptionsProps) => {
|
|||
id="filter-show"
|
||||
name="filter"
|
||||
type="radio"
|
||||
checked={options.filter === FilterState.WHITELIST_SPECIFIC}
|
||||
onChange={() => saveOption('filter', FilterState.WHITELIST_SPECIFIC)}
|
||||
checked={options.filter === FilterState.ALLOWLIST_SPECIFIC}
|
||||
onChange={() => saveOption('filter', FilterState.ALLOWLIST_SPECIFIC)}
|
||||
/>
|
||||
<label className="option__label" htmlFor="filter-show">
|
||||
Show the following:
|
||||
|
@ -60,9 +60,9 @@ export default ({ options, saveOption }: OptionsProps) => {
|
|||
<br />
|
||||
<textarea
|
||||
className="option__textarea"
|
||||
value={options.whitelist}
|
||||
disabled={options.filter !== FilterState.WHITELIST_SPECIFIC}
|
||||
onChange={(e) => saveOption('whitelist', e.target.value)}
|
||||
value={options.allowlist}
|
||||
disabled={options.filter !== FilterState.ALLOWLIST_SPECIFIC}
|
||||
onChange={(e) => saveOption('allowlist', e.target.value)}
|
||||
/>
|
||||
<div className="option__hint">Each action from the new line</div>
|
||||
</div>
|
||||
|
|
|
@ -6,8 +6,8 @@ export interface Options {
|
|||
readonly projectPath: string;
|
||||
readonly maxAge: number;
|
||||
readonly filter: FilterStateValue;
|
||||
readonly whitelist: string;
|
||||
readonly blacklist: string;
|
||||
readonly allowlist: string;
|
||||
readonly denylist: string;
|
||||
readonly shouldCatchErrors: boolean;
|
||||
readonly inject: boolean;
|
||||
readonly urls: string;
|
||||
|
@ -19,7 +19,13 @@ interface OldOrNewOptions {
|
|||
readonly editor: string;
|
||||
readonly projectPath: string;
|
||||
readonly maxAge: number;
|
||||
readonly filter: FilterStateValue | boolean;
|
||||
readonly filter:
|
||||
| FilterStateValue
|
||||
| 'WHITELIST_SPECIFIC'
|
||||
| 'BLACKLIST_SPECIFIC'
|
||||
| boolean;
|
||||
readonly allowlist: string;
|
||||
readonly denylist: string;
|
||||
readonly whitelist: string;
|
||||
readonly blacklist: string;
|
||||
readonly shouldCatchErrors: boolean;
|
||||
|
@ -54,10 +60,14 @@ const migrateOldOptions = (oldOptions: OldOrNewOptions): Options => ({
|
|||
// Migrate the old `filter` option from 2.2.1
|
||||
typeof oldOptions.filter === 'boolean'
|
||||
? oldOptions.filter && oldOptions.whitelist.length > 0
|
||||
? FilterState.WHITELIST_SPECIFIC
|
||||
? FilterState.ALLOWLIST_SPECIFIC
|
||||
: oldOptions.filter
|
||||
? FilterState.BLACKLIST_SPECIFIC
|
||||
? FilterState.DENYLIST_SPECIFIC
|
||||
: FilterState.DO_NOT_FILTER
|
||||
: oldOptions.filter === 'WHITELIST_SPECIFIC'
|
||||
? FilterState.ALLOWLIST_SPECIFIC
|
||||
: oldOptions.filter === 'BLACKLIST_SPECIFIC'
|
||||
? FilterState.DENYLIST_SPECIFIC
|
||||
: oldOptions.filter,
|
||||
});
|
||||
|
||||
|
@ -73,6 +83,8 @@ const get = (callback: (options: Options) => void) => {
|
|||
filter: FilterState.DO_NOT_FILTER,
|
||||
whitelist: '',
|
||||
blacklist: '',
|
||||
allowlist: '',
|
||||
denylist: '',
|
||||
shouldCatchErrors: false,
|
||||
inject: true,
|
||||
urls: '^https?://localhost|0\\.0\\.0\\.0:\\d+\n^https?://.+\\.github\\.io',
|
||||
|
@ -98,14 +110,14 @@ export const injectOptions = (newOptions: Options) => {
|
|||
|
||||
options = {
|
||||
...newOptions,
|
||||
whitelist:
|
||||
allowlist:
|
||||
newOptions.filter !== FilterState.DO_NOT_FILTER
|
||||
? toReg(newOptions.whitelist)!
|
||||
: newOptions.whitelist,
|
||||
blacklist:
|
||||
? toReg(newOptions.allowlist)!
|
||||
: newOptions.allowlist,
|
||||
denylist:
|
||||
newOptions.filter !== FilterState.DO_NOT_FILTER
|
||||
? toReg(newOptions.blacklist)!
|
||||
: newOptions.blacklist,
|
||||
? toReg(newOptions.denylist)!
|
||||
: newOptions.denylist,
|
||||
};
|
||||
let s = document.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
|
|
|
@ -181,7 +181,7 @@ describe('Redux enhancer', () => {
|
|||
window.store = createStore(
|
||||
counter,
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__({
|
||||
actionsBlacklist: ['SOME_ACTION'],
|
||||
actionsDenylist: ['SOME_ACTION'],
|
||||
statesFilter: (state) => state,
|
||||
serializeState: (key, value) => value,
|
||||
})
|
||||
|
|
|
@ -32,7 +32,7 @@ import { createStore, applyMiddleware } from 'redux';
|
|||
import { composeWithDevTools } from 'redux-devtools-extension';
|
||||
|
||||
const composeEnhancers = composeWithDevTools({
|
||||
// Specify here name, actionsBlacklist, actionsCreators and other options
|
||||
// Specify here name, actionsDenylist, actionsCreators and other options
|
||||
});
|
||||
const store = createStore(
|
||||
reducer,
|
||||
|
|
14
packages/redux-devtools-extension/index.d.ts
vendored
14
packages/redux-devtools-extension/index.d.ts
vendored
|
@ -56,16 +56,28 @@ export interface EnhancerOptions {
|
|||
/**
|
||||
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
||||
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
|
||||
* @deprecated Use actionsDenylist instead.
|
||||
*/
|
||||
actionsBlacklist?: string | string[];
|
||||
/**
|
||||
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
||||
* If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
|
||||
* @deprecated Use actionsAllowlist instead.
|
||||
*/
|
||||
actionsWhitelist?: string | string[];
|
||||
/**
|
||||
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
||||
* If `actionsAllowlist` specified, `actionsDenylist` is ignored.
|
||||
*/
|
||||
actionsDenylist?: string | string[];
|
||||
/**
|
||||
* *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
|
||||
* If `actionsAllowlist` specified, `actionsDenylist` is ignored.
|
||||
*/
|
||||
actionsAllowlist?: string | string[];
|
||||
/**
|
||||
* called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
|
||||
* Use it as a more advanced version of `actionsBlacklist`/`actionsWhitelist` parameters.
|
||||
* Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
|
||||
*/
|
||||
predicate?: <S, A extends Action>(state: S, action: A) => boolean;
|
||||
/**
|
||||
|
|
|
@ -10,8 +10,8 @@ interface State {
|
|||
|
||||
export const FilterState = {
|
||||
DO_NOT_FILTER: 'DO_NOT_FILTER',
|
||||
BLACKLIST_SPECIFIC: 'BLACKLIST_SPECIFIC',
|
||||
WHITELIST_SPECIFIC: 'WHITELIST_SPECIFIC',
|
||||
DENYLIST_SPECIFIC: 'DENYLIST_SPECIFIC',
|
||||
ALLOWLIST_SPECIFIC: 'ALLOWLIST_SPECIFIC',
|
||||
};
|
||||
|
||||
export function arrToRegex(v: string | string[]) {
|
||||
|
@ -41,20 +41,20 @@ function filterStates(
|
|||
}
|
||||
|
||||
interface Config {
|
||||
actionsBlacklist?: string[];
|
||||
actionsWhitelist?: string[];
|
||||
actionsDenylist?: string[];
|
||||
actionsAllowlist?: string[];
|
||||
}
|
||||
|
||||
interface LocalFilter {
|
||||
whitelist?: string;
|
||||
blacklist?: string;
|
||||
allowlist?: string;
|
||||
denylist?: string;
|
||||
}
|
||||
|
||||
export function getLocalFilter(config: Config): LocalFilter | undefined {
|
||||
if (config.actionsBlacklist || config.actionsWhitelist) {
|
||||
if (config.actionsDenylist || config.actionsAllowlist) {
|
||||
return {
|
||||
whitelist: config.actionsWhitelist && config.actionsWhitelist.join('|'),
|
||||
blacklist: config.actionsBlacklist && config.actionsBlacklist.join('|'),
|
||||
allowlist: config.actionsAllowlist && config.actionsAllowlist.join('|'),
|
||||
denylist: config.actionsDenylist && config.actionsDenylist.join('|'),
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
|
@ -63,10 +63,10 @@ export function getLocalFilter(config: Config): LocalFilter | undefined {
|
|||
interface DevToolsOptions {
|
||||
filter?:
|
||||
| typeof FilterState.DO_NOT_FILTER
|
||||
| typeof FilterState.BLACKLIST_SPECIFIC
|
||||
| typeof FilterState.WHITELIST_SPECIFIC;
|
||||
whitelist?: string;
|
||||
blacklist?: string;
|
||||
| typeof FilterState.DENYLIST_SPECIFIC
|
||||
| typeof FilterState.ALLOWLIST_SPECIFIC;
|
||||
allowlist?: string;
|
||||
denylist?: string;
|
||||
}
|
||||
function getDevToolsOptions() {
|
||||
return (
|
||||
|
@ -90,12 +90,12 @@ export function isFiltered(
|
|||
)
|
||||
return false;
|
||||
|
||||
const { whitelist, blacklist } = localFilter || opts;
|
||||
const { allowlist, denylist } = localFilter || opts;
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
||||
(whitelist && !(type as string).match(whitelist)) ||
|
||||
(allowlist && !(type as string).match(allowlist)) ||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
||||
(blacklist && (type as string).match(blacklist))
|
||||
(denylist && (type as string).match(denylist))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user