source: trip-planner-front/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs@ e29cc2e

Last change on this file since e29cc2e was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/* istanbul ignore next */
2const Url = (typeof URL !== 'undefined' ? URL : require('url').URL);
3// Matches "..", which must be preceeded by "/" or the start of the string, and
4// must be followed by a "/". We do not eat the following "/", so that the next
5// iteration can match on it.
6const parentRegex = /(^|\/)\.\.(?=\/|$)/g;
7function isAbsoluteUrl(url) {
8 try {
9 return !!new Url(url);
10 }
11 catch (e) {
12 return false;
13 }
14}
15/**
16 * Creates a directory name that is guaranteed to not be in `str`.
17 */
18function uniqInStr(str) {
19 let uniq = String(Math.random()).slice(2);
20 while (str.indexOf(uniq) > -1) {
21 /* istanbul ignore next */
22 uniq += uniq;
23 }
24 return uniq;
25}
26/**
27 * Removes the filename from the path (everything trailing the last "/"). This
28 * is only safe to call on a path, never call with an absolute or protocol
29 * relative URL.
30 */
31function stripPathFilename(path) {
32 path = normalizePath(path);
33 const index = path.lastIndexOf('/');
34 return path.slice(0, index + 1);
35}
36/**
37 * Normalizes a protocol-relative URL, but keeps it protocol relative by
38 * stripping out the protocl before returning it.
39 */
40function normalizeProtocolRelative(input, absoluteBase) {
41 const { href, protocol } = new Url(input, absoluteBase);
42 return href.slice(protocol.length);
43}
44/**
45 * Normalizes a simple path (one that has no ".."s, or is absolute so ".."s can
46 * be normalized absolutely).
47 */
48function normalizeSimplePath(input) {
49 const { href } = new Url(input, 'https://foo.com/');
50 return href.slice('https://foo.com/'.length);
51}
52/**
53 * Normalizes a path, ensuring that excess ".."s are preserved for relative
54 * paths in the output.
55 *
56 * If the input is absolute, this will return an absolutey normalized path, but
57 * it will not have a leading "/".
58 *
59 * If the input has a leading "..", the output will have a leading "..".
60 *
61 * If the input has a leading ".", the output will not have a leading "."
62 * unless there are too many ".."s, in which case there will be a leading "..".
63 */
64function normalizePath(input) {
65 // If there are no ".."s, we can treat this as if it were an absolute path.
66 // The return won't be an absolute path, so it's easy.
67 if (!parentRegex.test(input))
68 return normalizeSimplePath(input);
69 // We already found one "..". Let's see how many there are.
70 let total = 1;
71 while (parentRegex.test(input))
72 total++;
73 // If there are ".."s, we need to prefix the the path with the same number of
74 // unique directories. This is to ensure that we "remember" how many parent
75 // directories we are accessing. Eg, "../../.." must keep 3, and "foo/../.."
76 // must keep 1.
77 const uniqDirectory = `z${uniqInStr(input)}/`;
78 // uniqDirectory is just a "z", followed by numbers, followed by a "/". So
79 // generating a runtime regex from it is safe. We'll use this search regex to
80 // strip out our uniq directory names and insert any needed ".."s.
81 const search = new RegExp(`^(?:${uniqDirectory})*`);
82 // Now we can resolve the total path. If there are excess ".."s, they will
83 // eliminate one or more of the unique directories we prefix with.
84 const relative = normalizeSimplePath(uniqDirectory.repeat(total) + input);
85 // We can now count the number of unique directories that were eliminated. If
86 // there were 3, and 1 was eliminated, we know we only need to add 1 "..". If
87 // 2 were eliminated, we need to insert 2 ".."s. If all 3 were eliminated,
88 // then we need 3, etc. This replace is guranteed to match (it may match 0 or
89 // more times), and we can count the total match to see how many were eliminated.
90 return relative.replace(search, (all) => {
91 const leftover = all.length / uniqDirectory.length;
92 return '../'.repeat(total - leftover);
93 });
94}
95/**
96 * Attempts to resolve `input` URL relative to `base`.
97 */
98function resolve(input, base) {
99 if (!base)
100 base = '';
101 // Absolute URLs are very easy to resolve right.
102 if (isAbsoluteUrl(input))
103 return new Url(input).href;
104 if (base) {
105 // Absolute URLs are easy...
106 if (isAbsoluteUrl(base))
107 return new Url(input, base).href;
108 // If base is protocol relative, we'll resolve with it but keep the result
109 // protocol relative.
110 if (base.startsWith('//'))
111 return normalizeProtocolRelative(input, `https:${base}`);
112 }
113 // Normalize input, but keep it protocol relative. We know base doesn't supply
114 // a protocol, because that would have been handled above.
115 if (input.startsWith('//'))
116 return normalizeProtocolRelative(input, 'https://foo.com/');
117 // We now know that base (if there is one) and input are paths. We've handled
118 // both absolute and protocol-relative variations above.
119 // Absolute paths don't need any special handling, because they cannot have
120 // extra "." or ".."s. That'll all be stripped away. Input takes priority here,
121 // because if input is an absolute path, base path won't affect it in any way.
122 if (input.startsWith('/'))
123 return '/' + normalizeSimplePath(input);
124 // Since input and base are paths, we need to join them to do any further
125 // processing. Paths are joined at the directory level, so we need to remove
126 // the base's filename before joining. We also know that input does not have a
127 // leading slash, and that the stripped base will have a trailing slash if
128 // there are any directories (or it'll be empty).
129 const joined = stripPathFilename(base) + input;
130 // If base is an absolute path, then input will be relative to it.
131 if (base.startsWith('/'))
132 return '/' + normalizeSimplePath(joined);
133 // We now know both base (if there is one) and input are relative paths.
134 const relative = normalizePath(joined);
135 // If base started with a leading ".", or there is no base and input started
136 // with a ".", then we need to ensure that the relative path starts with a
137 // ".". We don't know if relative starts with a "..", though, so check before
138 // prepending.
139 if ((base || input).startsWith('.') && !relative.startsWith('.')) {
140 return './' + relative;
141 }
142 return relative;
143}
144
145export default resolve;
146//# sourceMappingURL=resolve-uri.mjs.map
Note: See TracBrowser for help on using the repository browser.