UNPKG

2.73 kBJavaScriptView Raw
1import { platform } from 'os';
2import slash from 'slash';
3
4const VOLUME = /^([A-Z]:)/i;
5const IS_WINDOWS = platform() === 'win32';
6
7// Helper functions
8const noop = () => null;
9const matches = (pattern, importee) => {
10 if (pattern instanceof RegExp) {
11 return pattern.test(importee);
12 }
13 if (importee.length < pattern.length) {
14 return false;
15 }
16 if (importee === pattern) {
17 return true;
18 }
19 const importeeStartsWithKey = importee.indexOf(pattern) === 0;
20 const importeeHasSlashAfterKey = importee.substring(pattern.length)[0] === '/';
21 return importeeStartsWithKey && importeeHasSlashAfterKey;
22};
23
24const normalizeId = (id) => {
25 if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
26 return slash(id.replace(VOLUME, ''));
27 }
28 return id;
29};
30
31const getEntries = ({ entries }) => {
32 if (!entries) {
33 return [];
34 }
35
36 if (Array.isArray(entries)) {
37 return entries;
38 }
39
40 return Object.keys(entries).map((key) => {
41 return { find: key, replacement: entries[key] };
42 });
43};
44
45function alias(options = {}) {
46 const entries = getEntries(options);
47
48 // No aliases?
49 if (entries.length === 0) {
50 return {
51 resolveId: noop
52 };
53 }
54
55 return {
56 name: 'alias',
57 resolveId(importee, importer) {
58 const importeeId = normalizeId(importee);
59 const importerId = normalizeId(importer);
60
61 // First match is supposed to be the correct one
62 const matchedEntry = entries.find((entry) => matches(entry.find, importeeId));
63 if (!matchedEntry || !importerId) {
64 return null;
65 }
66
67 const updatedId = normalizeId(
68 importeeId.replace(matchedEntry.find, matchedEntry.replacement)
69 );
70
71 let customResolver = null;
72 if (typeof matchedEntry.customResolver === 'function') {
73 ({ customResolver } = matchedEntry);
74 } else if (
75 typeof matchedEntry.customResolver === 'object' &&
76 typeof matchedEntry.customResolver.resolveId === 'function'
77 ) {
78 customResolver = matchedEntry.customResolver.resolveId;
79 } else if (typeof options.customResolver === 'function') {
80 ({ customResolver } = options);
81 } else if (
82 typeof options.customResolver === 'object' &&
83 typeof options.customResolver.resolveId === 'function'
84 ) {
85 customResolver = options.customResolver.resolveId;
86 }
87
88 if (customResolver) {
89 return customResolver(updatedId, importerId);
90 }
91
92 return this.resolve(updatedId, importer, { skipSelf: true }).then((resolved) => {
93 let finalResult = resolved;
94 if (!finalResult) {
95 finalResult = { id: updatedId };
96 }
97
98 return finalResult;
99 });
100 }
101 };
102}
103
104export default alias;