|
1 |
| -const _rewrite = (importPath, options) => { |
2 |
| - if (typeof importPath != 'string') { |
3 |
| - throw new TypeError(`rewrite error: expected import specifier of type string, not ${typeof importPath}`); |
| 1 | +const _rewrite = (specifier, options) => { |
| 2 | + if (typeof specifier != 'string') { |
| 3 | + throw new TypeError(`rewrite error: expected specifier of type string, not ${typeof specifier}`); |
4 | 4 | }
|
5 |
| - let finalImportPath = importPath; |
6 | 5 | let replacementMap;
|
7 | 6 | replacementMap = undefined;
|
8 | 7 | if (options.replaceExtensions) {
|
9 | 8 | Object.entries(options.replaceExtensions).some(([target, replacement]) => {
|
10 | 9 | if (target.startsWith('^') || target.endsWith('$')) {
|
11 | 10 | const targetRegExp = new RegExp(target);
|
12 |
| - if (targetRegExp.test(finalImportPath)) { |
13 |
| - replacementMap = [targetRegExp, replacement]; |
| 11 | + const capturingGroups = Array.from(specifier.match(targetRegExp) || []); |
| 12 | + if (capturingGroups.length) { |
| 13 | + replacementMap = [targetRegExp, replacement, capturingGroups]; |
14 | 14 | return true;
|
15 | 15 | }
|
16 |
| - } else if (finalImportPath.endsWith(target)) { |
17 |
| - replacementMap = [target, replacement]; |
| 16 | + } else if (specifier.endsWith(target)) { |
| 17 | + replacementMap = [target, replacement, []]; |
18 | 18 | return true;
|
19 | 19 | }
|
20 | 20 | });
|
21 | 21 | }
|
| 22 | + let finalImportPath = specifier; |
22 | 23 | if (replacementMap) {
|
23 |
| - const [target, replacement] = replacementMap; |
24 |
| - finalImportPath = finalImportPath.replace(target, replacement); |
| 24 | + const [target, replacement, capturingGroups] = replacementMap; |
| 25 | + finalImportPath = finalImportPath.replace(target, typeof replacement == 'string' ? replacement : replacement({ |
| 26 | + specifier, |
| 27 | + capturingGroups |
| 28 | + })); |
25 | 29 | }
|
26 |
| - const isRelative = finalImportPath.startsWith('./') || finalImportPath.startsWith('../') || finalImportPath == '.' || finalImportPath == '..'; |
| 30 | + const isRelative = finalImportPath.startsWith('./') || finalImportPath.startsWith('.\\') || finalImportPath.startsWith('../') || finalImportPath.startsWith('..\\') || finalImportPath == '.' || finalImportPath == '..'; |
27 | 31 | if (options.appendExtension && isRelative) {
|
28 |
| - const endsWithSlash = finalImportPath.endsWith('/'); |
29 |
| - if (/(^\.?\.\/?$)|(\/\.?\.\/?$)/.test(finalImportPath)) { |
30 |
| - finalImportPath += `${endsWithSlash ? '' : '/'}index${options.appendExtension}`; |
31 |
| - } else { |
32 |
| - const hasRecognizedExtension = !endsWithSlash && options.recognizedExtensions.some(extension => { |
33 |
| - return finalImportPath.endsWith(extension); |
34 |
| - }); |
35 |
| - if (!hasRecognizedExtension) { |
36 |
| - finalImportPath = endsWithSlash ? finalImportPath + `index${options.appendExtension}` : finalImportPath + options.appendExtension; |
| 32 | + const endsWithSlash = /(\/|\\)$/.test(finalImportPath); |
| 33 | + const basenameIsDots = /(^\.?\.(\/|\\)?$)|((\/|\\)\.?\.(\/|\\)?$)/.test(finalImportPath); |
| 34 | + const extensionToAppend = typeof options.appendExtension == 'string' ? options.appendExtension : options.appendExtension({ |
| 35 | + specifier, |
| 36 | + capturingGroups: [] |
| 37 | + }); |
| 38 | + if (extensionToAppend !== undefined) { |
| 39 | + if (basenameIsDots) { |
| 40 | + finalImportPath += `${endsWithSlash ? '' : '/'}index${extensionToAppend}`; |
| 41 | + } else { |
| 42 | + const hasRecognizedExtension = !endsWithSlash && options.recognizedExtensions.some(extension => { |
| 43 | + return finalImportPath.endsWith(extension); |
| 44 | + }); |
| 45 | + if (!hasRecognizedExtension) { |
| 46 | + finalImportPath = endsWithSlash ? finalImportPath + `index${extensionToAppend}` : finalImportPath + extensionToAppend; |
| 47 | + } |
37 | 48 | }
|
38 | 49 | }
|
39 | 50 | }
|
|
0 commit comments