UNPKG

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