xref: /expo/home/utils/UrlUtils.ts (revision c3f10bd5)
1import url from 'url';
2
3import Config from '../api/Config';
4
5const HTTPS_HOSTS = [Config.api.host, 'exp.host', 'exponentjs.com', 'getexponent.com'];
6
7export function normalizeUrl(rawUrl: string): string {
8  let components = url.parse(rawUrl, false, true);
9  if (
10    components.protocol === 'localhost:' ||
11    (components.host == null && !components.protocol && !components.slashes)
12  ) {
13    if (components.path && components.path.charAt(0) === '@') {
14      // try parsing as @user/experience-id shortcut
15      components = url.parse(`exp://${Config.api.host}/${rawUrl}`);
16    } else {
17      // just treat it as a url with no protocol and assume exp://
18      components = url.parse('exp://' + rawUrl);
19    }
20  }
21  if (!components.protocol) {
22    components.protocol = 'exp:';
23    components.slashes = true;
24  }
25  return url.format(components);
26}
27
28export function toHttp(expUrl: string): string {
29  if (!(expUrl.startsWith('exp:') || expUrl.startsWith('exps:'))) {
30    return expUrl;
31  }
32
33  const components = url.parse(expUrl);
34  if (components.host && HTTPS_HOSTS.includes(components.host)) {
35    components.protocol = 'https:';
36  } else {
37    components.protocol = 'http:';
38  }
39  return url.format(components);
40}
41
42export function toExp(httpUrl: string): string {
43  const components = url.parse(httpUrl);
44  components.protocol = 'exp:';
45  return url.format(components);
46}
47
48export function toExps(httpUrl: string): string {
49  const components = url.parse(httpUrl);
50  components.protocol = 'exps:';
51  return url.format(components);
52}
53
54export function conformsToExpoProtocol(str: string): boolean {
55  if (!str) {
56    return false;
57  }
58
59  // @username/experience
60  if (str.match(/^@\w+\/\w+/)) {
61    return true;
62  } else if (str.startsWith('exp://')) {
63    return true;
64  } else if (
65    str.startsWith(`${Config.website.origin}/`) ||
66    str.startsWith(`${Config.api.origin}/`)
67  ) {
68    return true;
69  }
70
71  return false;
72}
73