Skip to content

Commit 711bd7e

Browse files
committed
feat(regex): EXPORT_LIST_REGEX
Signed-off-by: Lexus Drumgold <[email protected]>
1 parent a84be11 commit 711bd7e

File tree

4 files changed

+248
-0
lines changed

4 files changed

+248
-0
lines changed

src/__snapshots__/export-list.snap

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Vitest Snapshot v1
2+
3+
exports[`unit:EXPORT_LIST_REGEX > exports > should match named export(s) in multi-line statement 1`] = `
4+
{
5+
"0": "export {
6+
addFive,
7+
addFour,
8+
addThree,
9+
addTwo,
10+
squareFive,
11+
squareFour,
12+
squareThree,
13+
squareTwo
14+
}",
15+
"1": undefined,
16+
"2": "{
17+
addFive,
18+
addFour,
19+
addThree,
20+
addTwo,
21+
squareFive,
22+
squareFour,
23+
squareThree,
24+
squareTwo
25+
}",
26+
"groups": {
27+
"exports": "{
28+
addFive,
29+
addFour,
30+
addThree,
31+
addTwo,
32+
squareFive,
33+
squareFour,
34+
squareThree,
35+
squareTwo
36+
}",
37+
"type": undefined,
38+
},
39+
"index": 0,
40+
}
41+
`;
42+
43+
exports[`unit:EXPORT_LIST_REGEX > exports > should match named export(s) in single-line statement 1`] = `
44+
{
45+
"0": "export { defineBuildConfig, type BuildConfig }",
46+
"1": undefined,
47+
"2": "{ defineBuildConfig, type BuildConfig }",
48+
"groups": {
49+
"exports": "{ defineBuildConfig, type BuildConfig }",
50+
"type": undefined,
51+
},
52+
"index": 0,
53+
}
54+
`;
55+
56+
exports[`unit:EXPORT_LIST_REGEX > exports > should match named type export(s) in multi-line statement 1`] = `
57+
{
58+
"0": "export type {
59+
JsonObject,
60+
LiteralUnion,
61+
Nullable
62+
}",
63+
"1": "type",
64+
"2": "{
65+
JsonObject,
66+
LiteralUnion,
67+
Nullable
68+
}",
69+
"groups": {
70+
"exports": "{
71+
JsonObject,
72+
LiteralUnion,
73+
Nullable
74+
}",
75+
"type": "type",
76+
},
77+
"index": 0,
78+
}
79+
`;
80+
81+
exports[`unit:EXPORT_LIST_REGEX > exports > should match named type export(s) in single-line statement 1`] = `
82+
{
83+
"0": "export type { default as Options }",
84+
"1": "type",
85+
"2": "{ default as Options }",
86+
"groups": {
87+
"exports": "{ default as Options }",
88+
"type": "type",
89+
},
90+
"index": 0,
91+
}
92+
`;

src/__tests__/export-list.spec.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/**
2+
* @file Unit Tests - EXPORT_LIST_REGEX
3+
* @module export-regex/tests/list/unit
4+
*/
5+
6+
import { omit } from 'radash'
7+
import { dedent } from 'ts-dedent'
8+
import TEST_SUBJECT from '../export-list'
9+
10+
describe('unit:EXPORT_LIST_REGEX', () => {
11+
beforeEach(() => {
12+
TEST_SUBJECT.lastIndex = 0
13+
})
14+
15+
describe('comments', () => {
16+
it('should ignore export in multi-line comment', () => {
17+
// Arrange
18+
const code = dedent`
19+
/**
20+
* @example
21+
* export { name1, name2, name3 }
22+
*/
23+
`
24+
25+
// Act + Expect
26+
expect(TEST_SUBJECT.test(code)).to.be.false
27+
})
28+
29+
it('should ignore export in single-line comment', () => {
30+
expect(TEST_SUBJECT.test('// export { foo, bar }')).to.be.false
31+
})
32+
})
33+
34+
describe('exports', () => {
35+
it('should match named export(s) in multi-line statement', () => {
36+
// Arrange
37+
const code = dedent`
38+
export {
39+
addFive,
40+
addFour,
41+
addThree,
42+
addTwo,
43+
squareFive,
44+
squareFour,
45+
squareThree,
46+
squareTwo
47+
}
48+
`
49+
50+
// Act
51+
const result = TEST_SUBJECT.exec(code)
52+
53+
// Expect
54+
expect(result).to.not.be.null
55+
expect(omit(result!, ['input'])).toMatchSnapshot()
56+
})
57+
58+
it('should match named export(s) in single-line statement', () => {
59+
// Arrange
60+
const code = 'export { defineBuildConfig, type BuildConfig }'
61+
62+
// Act
63+
const result = TEST_SUBJECT.exec(code)
64+
65+
// Expect
66+
expect(result).to.not.be.null
67+
expect(omit(result!, ['input'])).toMatchSnapshot()
68+
})
69+
70+
it('should match named type export(s) in multi-line statement', () => {
71+
// Arrange
72+
const code = dedent`
73+
export type {
74+
JsonObject,
75+
LiteralUnion,
76+
Nullable
77+
}
78+
`
79+
80+
// Act
81+
const result = TEST_SUBJECT.exec(code)
82+
83+
// Expect
84+
expect(result).to.not.be.null
85+
expect(omit(result!, ['input'])).toMatchSnapshot()
86+
})
87+
88+
it('should match named type export(s) in single-line statement', () => {
89+
// Act
90+
const result = TEST_SUBJECT.exec('export type { default as Options }')
91+
92+
// Expect
93+
expect(result).to.not.be.null
94+
expect(omit(result!, ['input'])).toMatchSnapshot()
95+
})
96+
})
97+
})

src/export-list.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @file EXPORT_LIST_REGEX
3+
* @module export-regex/list
4+
*/
5+
6+
/**
7+
* List `export` statement regex. Ignores matches in comments.
8+
*
9+
* @example
10+
* import { EXPORT_LIST_REGEX } from '@flex-development/export-regex'
11+
* import { dedent } from 'ts-dedent'
12+
*
13+
* const code: string = dedent`
14+
* export { defineBuildConfig, type BuildConfig }
15+
* export type {
16+
* JsonObject,
17+
* LiteralUnion,
18+
* Nullable
19+
* }
20+
* `
21+
*
22+
* const print = (matches: IterableIterator<RegExpMatchArray>): void => {
23+
* console.debug([...matches].map(match => omit(match, ['input'])))
24+
* }
25+
*
26+
* print(code.matchAll(EXPORT_LIST_REGEX))
27+
* // [
28+
* // {
29+
* // '0': 'export { defineBuildConfig, type BuildConfig }',
30+
* // '1': undefined,
31+
* // '2': '{ defineBuildConfig, type BuildConfig }',
32+
* // index: 0,
33+
* // groups: [Object: null prototype] {
34+
* // type: undefined,
35+
* // exports: '{ defineBuildConfig, type BuildConfig }'
36+
* // }
37+
* // },
38+
* // {
39+
* // '0': 'export type {\n JsonObject,\n LiteralUnion,\n Nullable\n}',
40+
* // '1': 'type',
41+
* // '2': '{\n JsonObject,\n LiteralUnion,\n Nullable\n}',
42+
* // index: 82,
43+
* // groups: [Object: null prototype] {
44+
* // type: 'type',
45+
* // exports: '{\n JsonObject,\n LiteralUnion,\n Nullable\n}'
46+
* // }
47+
* // }
48+
* // ]
49+
*
50+
* @see https://regex101.com/r/KQEDdZ
51+
* @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/export#syntax
52+
*
53+
* @const {RegExp} EXPORT_LIST_REGEX
54+
*/
55+
const EXPORT_LIST_REGEX: RegExp =
56+
/(?<=^|[\n;])export(?:(?:\s+(?<type>type)\s*)|\s*)(?<exports>{[\w\t\n\r "$'*,./{}-]+?})/g
57+
58+
export default EXPORT_LIST_REGEX

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
*/
55

66
export { default as EXPORT_AGGREGATE_REGEX } from './export-aggregate'
7+
export { default as EXPORT_LIST_REGEX } from './export-list'

0 commit comments

Comments
 (0)