Skip to content

feat(pluginutils): add suffixRegex & support multiple string #1886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions packages/pluginutils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export default function myPlugin(options = {}) {

Constructs a RegExp that matches the exact string specified. This is useful for plugin hook filters.

Parameters: `(str: String, flags?: String)`<br>
Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`

#### Usage
Expand All @@ -236,6 +236,7 @@ Returns: `RegExp`
import { exactRegex } from '@rollup/pluginutils';

exactRegex('foobar'); // /^foobar$/
exactRegex(['foo', 'bar']); // /^(?:foo|bar)$/
exactRegex('foo(bar)', 'i'); // /^foo\(bar\)$/i
```

Expand Down Expand Up @@ -275,7 +276,7 @@ normalizePath('foo/bar'); // 'foo/bar'

Constructs a RegExp that matches a value that has the specified prefix. This is useful for plugin hook filters.

Parameters: `(str: String, flags?: String)`<br>
Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`

#### Usage
Expand All @@ -284,9 +285,27 @@ Returns: `RegExp`
import { prefixRegex } from '@rollup/pluginutils';

prefixRegex('foobar'); // /^foobar/
prefixRegex(['foo', 'bar']); // /^(?:foo|bar)/
prefixRegex('foo(bar)', 'i'); // /^foo\(bar\)/i
```

### suffixRegex

Constructs a RegExp that matches a value that has the specified suffix. This is useful for plugin hook filters.

Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`

#### Usage

```js
import { suffixRegex } from '@rollup/pluginutils';

suffixRegex('foobar'); // /foobar$/
suffixRegex(['foo', 'bar']); // /(?:foo|bar)$/
suffixRegex('foo(bar)', 'i'); // /foo\(bar\)$/i
```

## Meta

[CONTRIBUTING](/.github/CONTRIBUTING.md)
Expand Down
22 changes: 18 additions & 4 deletions packages/pluginutils/src/filterUtils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
export function exactRegex(str: string, flags?: string): RegExp {
return new RegExp(`^${escapeRegex(str)}$`, flags);
export function exactRegex(str: string | string[], flags?: string): RegExp {
return new RegExp(`^${combineMultipleStrings(str)}$`, flags);
}

export function prefixRegex(str: string, flags?: string): RegExp {
return new RegExp(`^${escapeRegex(str)}`, flags);
export function prefixRegex(str: string | string[], flags?: string): RegExp {
return new RegExp(`^${combineMultipleStrings(str)}`, flags);
}

export function suffixRegex(str: string | string[], flags?: string): RegExp {
return new RegExp(`${combineMultipleStrings(str)}$`, flags);
}

const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
function escapeRegex(str: string): string {
return str.replace(escapeRegexRE, '\\$&');
}
function combineMultipleStrings(str: string | string[]): string {
if (Array.isArray(str)) {
const escapeStr = str.map(escapeRegex).join('|');
if (escapeStr && str.length > 1) {
return `(?:${escapeStr})`;
}
return escapeStr;
}
return escapeRegex(str);
}
8 changes: 5 additions & 3 deletions packages/pluginutils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import dataToEsm from './dataToEsm';
import extractAssignedNames from './extractAssignedNames';
import makeLegalIdentifier from './makeLegalIdentifier';
import normalizePath from './normalizePath';
import { exactRegex, prefixRegex } from './filterUtils';
import { exactRegex, prefixRegex, suffixRegex } from './filterUtils';

export {
addExtension,
Expand All @@ -16,7 +16,8 @@ export {
extractAssignedNames,
makeLegalIdentifier,
normalizePath,
prefixRegex
prefixRegex,
suffixRegex
};

// TODO: remove this in next major
Expand All @@ -29,5 +30,6 @@ export default {
extractAssignedNames,
makeLegalIdentifier,
normalizePath,
prefixRegex
prefixRegex,
suffixRegex
};
50 changes: 49 additions & 1 deletion packages/pluginutils/test/filterUtils.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,75 @@
import test from 'ava';

import { exactRegex, prefixRegex } from '../';
import { exactRegex, prefixRegex, suffixRegex } from '../';

test('exactRegex supports without flag parameter', (t) => {
t.is(exactRegex('foo').toString(), '/^foo$/');
});

test('exactRegex supports with multiple string and without flag parameter', (t) => {
t.is(exactRegex(['foo', 'bar']).toString(), '/^(?:foo|bar)$/');
});

test('exactRegex supports with flag parameter', (t) => {
t.is(exactRegex('foo', 'i').toString(), '/^foo$/i');
});

test('exactRegex supports with multiple string and flag parameter', (t) => {
t.is(exactRegex(['foo', 'bar'], 'i').toString(), '/^(?:foo|bar)$/i');
});

test('exactRegex escapes special characters for Regex', (t) => {
t.is(exactRegex('foo(bar)').toString(), '/^foo\\(bar\\)$/');
});

test('exactRegex escapes special characters with multiple string for Regex', (t) => {
t.is(exactRegex(['foo(bar)', 'baz(qux)']).toString(), '/^(?:foo\\(bar\\)|baz\\(qux\\))$/');
});

test('prefixRegex supports without flag parameter', (t) => {
t.is(prefixRegex('foo').toString(), '/^foo/');
});

test('prefixRegex supports with multiple string and without flag parameter', (t) => {
t.is(prefixRegex(['foo', 'bar']).toString(), '/^(?:foo|bar)/');
});

test('prefixRegex supports with flag parameter', (t) => {
t.is(prefixRegex('foo', 'i').toString(), '/^foo/i');
});

test('prefixRegex supports with multiple string and flag parameter', (t) => {
t.is(prefixRegex(['foo', 'bar'], 'i').toString(), '/^(?:foo|bar)/i');
});

test('prefixRegex escapes special characters for Regex', (t) => {
t.is(prefixRegex('foo(bar)').toString(), '/^foo\\(bar\\)/');
});

test('prefixRegex escapes special characters with multiple string for Regex', (t) => {
t.is(prefixRegex(['foo(bar)', 'baz(qux)']).toString(), '/^(?:foo\\(bar\\)|baz\\(qux\\))/');
});

test('suffixRegex supports without flag parameter', (t) => {
t.is(suffixRegex('foo').toString(), '/foo$/');
});

test('suffixRegex supports with multiple string and without flag parameter', (t) => {
t.is(suffixRegex(['foo', 'bar']).toString(), '/(?:foo|bar)$/');
});

test('suffixRegex supports with flag parameter', (t) => {
t.is(suffixRegex('foo', 'i').toString(), '/foo$/i');
});

test('suffixRegex supports with multiple string and flag parameter', (t) => {
t.is(suffixRegex(['foo', 'bar'], 'i').toString(), '/(?:foo|bar)$/i');
});

test('suffixRegex escapes special characters for Regex', (t) => {
t.is(suffixRegex('foo(bar)').toString(), '/foo\\(bar\\)$/');
});

test('suffixRegex escapes special characters with multiple string for Regex', (t) => {
t.is(suffixRegex(['foo(bar)', 'baz(qux)']).toString(), '/(?:foo\\(bar\\)|baz\\(qux\\))$/');
});
13 changes: 11 additions & 2 deletions packages/pluginutils/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function dataToEsm(data: unknown, options?: DataToEsmOptions): string;
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function exactRegex(str: string, flags?: string): RegExp;
export function exactRegex(str: string | string[], flags?: string): RegExp;

/**
* Extracts the names of all assignment targets based upon specified patterns.
Expand All @@ -90,7 +90,14 @@ export function normalizePath(filename: string): string;
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function prefixRegex(str: string, flags?: string): RegExp;
export function prefixRegex(str: string | string[], flags?: string): RegExp;

/**
* Constructs a RegExp that matches a value that has the specified suffix.
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function suffixRegex(str: string | string[], flags?: string): RegExp;

export type AddExtension = typeof addExtension;
export type AttachScopes = typeof attachScopes;
Expand All @@ -101,6 +108,7 @@ export type MakeLegalIdentifier = typeof makeLegalIdentifier;
export type NormalizePath = typeof normalizePath;
export type DataToEsm = typeof dataToEsm;
export type PrefixRegex = typeof prefixRegex;
export type SuffixRegex = typeof suffixRegex;

declare const defaultExport: {
addExtension: AddExtension;
Expand All @@ -112,5 +120,6 @@ declare const defaultExport: {
makeLegalIdentifier: MakeLegalIdentifier;
normalizePath: NormalizePath;
prefixRegex: PrefixRegex;
suffixRegex: SuffixRegex;
};
export default defaultExport;
Loading