UNPKG

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