Skip to content

Commit

Permalink
feat: useProviders 和 discardProviders 增加严格模式
Browse files Browse the repository at this point in the history
  • Loading branch information
geekdada committed May 4, 2020
1 parent ef4946c commit bcd9fe9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 13 deletions.
16 changes: 11 additions & 5 deletions docs/guide/advance/custom-filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,17 @@ module.exports = {
```

:::warning 注意
1. 不能合并排序型过滤器
2. 若某个节点同时匹配多个规则,只会出现在第一次匹配的位置
3. Provider 的配置项 `nodeFilter` 也支持排序类型的过滤器,但我们并不建议您这么用,因为 Provider 的 `nodeFilter` 配置项仅针对当前 Provider 而非合并进来的所有的节点,再者如果你同时在 `nodeFilter``getNodeNames`(包括但不限于)中使用排序过滤器,会进行多次排序,很难避免不出错。所以请尽可能在 `nodeFilter` 中使用普通的过滤器
1. 不能合并排序型过滤器
2. 若某个节点同时匹配多个规则,只会出现在第一次匹配的位置
3. Provider 的配置项 `nodeFilter` 也支持排序类型的过滤器,但我们并不建议您这么用,因为 Provider 的 `nodeFilter` 配置项仅针对当前 Provider 而非合并进来的所有的节点,再者如果你同时在 `nodeFilter``getNodeNames`(包括但不限于)中使用排序过滤器,会进行多次排序,很难避免不出错。所以请尽可能在 `nodeFilter` 中使用普通的过滤器
:::

### useProviders <Badge text="v1.11.0" vertical="middle" />

合并 Provider 之后若是想快速地过滤出某几个 Provider 中的节点作为一个策略组,可以使用该过滤器。

第二个入参是开启严格模式。严格模式下会严格匹配 Provider 名称(注意和 `useKeywords` 的严格模式不同)。

```js
// surgio.conf.js
const { utils } = require('surgio');
Expand All @@ -173,13 +175,16 @@ module.exports = {
```

:::warning 注意
该过滤器不保证顺序。
1. 该过滤器不保证顺序;
2. 在后面的版本中会默认开启严格模式;
:::

### discardProviders <Badge text="v1.11.0" vertical="middle" />

合并 Provider 之后若是想快速地舍弃某几个 Provider 中的节点作为一个策略组,可以使用该过滤器。

第二个入参是开启严格模式。严格模式下会严格匹配 Provider 名称(注意和 `useKeywords` 的严格模式不同)。

```js
// surgio.conf.js
const { utils } = require('surgio');
Expand All @@ -192,5 +197,6 @@ module.exports = {
```

:::warning 注意
该过滤器不保证顺序。
1. 该过滤器不保证顺序;
2. 在后面的版本中会默认开启严格模式;
:::
2 changes: 2 additions & 0 deletions lib/misc/deprecation.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export const DEP001 = 'nowHandler 已不推荐使用,请参考 http://bit.ly/2q5daCK 尽快更新您的代码';
export const DEP002 = 'udp-relay 的值已改为布尔类型,字符串类型依然可用但推荐更改';
export const DEP003 = 'useProvider 将在之后版本改为默认使用严格模式';
export const DEP004 = 'discardProviders 将在之后版本改为默认使用严格模式';
21 changes: 17 additions & 4 deletions lib/utils/filter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import _ from 'lodash';
import { deprecate } from 'util';

import { DEP003, DEP004 } from '../misc/deprecation';
import flag, { TAIWAN } from '../misc/flag_cn';
import { NodeNameFilterType, SimpleNodeConfig, SortedNodeNameFilterType } from '../types';

const showDEP003 = deprecate(_.noop, DEP003, 'DEP003');
const showDEP004 = deprecate(_.noop, DEP004, 'DEP004');

// tslint:disable-next-line:max-classes-per-file
export class SortFilterWithSortedFilters implements SortedNodeNameFilterType {
public supportSort = true;
Expand Down Expand Up @@ -94,22 +99,30 @@ export const useRegexp = (regexp: RegExp): NodeNameFilterType => {
return item => regexp.test(item.nodeName);
};

export const useProviders = (keywords: ReadonlyArray<string>): NodeNameFilterType => {
export const useProviders = (keywords: ReadonlyArray<string>, isStrict?: boolean): NodeNameFilterType => {
// istanbul ignore next
if (!Array.isArray(keywords)) {
throw new Error('keywords 请使用数组');
}

return item => keywords.some(keyword => item?.provider?.name.includes(keyword));
if (!isStrict) {
showDEP003();
}

return item => keywords.some(keyword => isStrict ? item?.provider?.name === keyword : item?.provider?.name.includes(keyword));
};

export const discardProviders = (keywords: ReadonlyArray<string>): NodeNameFilterType => {
export const discardProviders = (keywords: ReadonlyArray<string>, isStrict?: boolean): NodeNameFilterType => {
// istanbul ignore next
if (!Array.isArray(keywords)) {
throw new Error('keywords 请使用数组');
}

return item => !keywords.some(keyword => item?.provider?.name.includes(keyword));
if (!isStrict) {
showDEP004();
}

return item => !keywords.some(keyword => isStrict ? item?.provider?.name === keyword : item?.provider?.name.includes(keyword));
};

export const useSortedKeywords = (keywords: ReadonlyArray<string>): SortedNodeNameFilterType => {
Expand Down
36 changes: 32 additions & 4 deletions test/utils/filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,36 +273,64 @@ test('mergeFilters', t => {

test('useProviders', t => {
const fn = filter.useProviders(['测试', 'test']);
const fn2 = filter.useProviders(['测试', 'test'], true);

t.is(fn({
...generateVmessNode('test'),
provider: { name: '测试' }
provider: { name: '测试 asdf' }
} as any), true);
t.is(fn({
...generateVmessNode('test'),
provider: { name: 'test' }
provider: { name: 'test asdf' }
} as any), true);
t.is(fn({
...generateVmessNode('test'),
provider: { name: 'other' }
} as any), false);

t.is(fn2({
...generateVmessNode('test'),
provider: { name: '测试 asdf' }
} as any), false);
t.is(fn2({
...generateVmessNode('test'),
provider: { name: 'test asdf' }
} as any), false);
t.is(fn2({
...generateVmessNode('test'),
provider: { name: 'test' }
} as any), true);
});

test('discardProviders', t => {
const fn = filter.discardProviders(['测试', 'test']);
const fn2 = filter.discardProviders(['测试', 'test'], true);

t.is(fn({
...generateVmessNode('test'),
provider: { name: '测试' }
provider: { name: '测试 asdf' }
} as any), false);
t.is(fn({
...generateVmessNode('test'),
provider: { name: 'test' }
provider: { name: 'test asdf' }
} as any), false);
t.is(fn({
...generateVmessNode('test'),
provider: { name: 'other' }
} as any), true);

t.is(fn2({
...generateVmessNode('test'),
provider: { name: 'test' }
} as any), false);
t.is(fn2({
...generateVmessNode('test'),
provider: { name: 'test asdf' }
} as any), true);
t.is(fn2({
...generateVmessNode('test'),
provider: { name: 'other' }
} as any), true);
});

function generateVmessNode(nodeName: string): VmessNodeConfig {
Expand Down

0 comments on commit bcd9fe9

Please sign in to comment.