1import { Platform } from 'react-native';
2
3import { restClient } from '../apiClient';
4import { DevSession } from '../types';
5
6// TODO -- move this into context / make it settable via JS
7const baseAddress = Platform.select({
8  ios: 'http://localhost',
9  android: 'http://10.0.2.2',
10});
11
12const statusPage = 'status';
13const portsToCheck = [8081, 8082, 19000, 19001, 19002, 19003, 19004, 19005];
14
15export async function getDevSessionsAsync({
16  isAuthenticated = false,
17  installationID = '',
18  isDevice = false,
19}): Promise<DevSession[]> {
20  let devSessions: DevSession[] = [];
21
22  if (isAuthenticated) {
23    const sessions = await fetchDevSessions();
24    devSessions = devSessions.concat(sessions);
25  }
26
27  if (!devSessions.length && installationID) {
28    const sessions = await fetchDevSessions(installationID);
29    devSessions = devSessions.concat(sessions);
30  }
31
32  if (!devSessions.length && !isDevice) {
33    const localPackagers = await getLocalPackagersAsync();
34    devSessions = devSessions.concat(localPackagers);
35  }
36
37  return devSessions;
38}
39
40export async function getLocalPackagersAsync(): Promise<DevSession[]> {
41  const onlineDevSessions: DevSession[] = [];
42
43  await Promise.all(
44    portsToCheck.map(async (port) => {
45      try {
46        const address = `${baseAddress}:${port}`;
47        const { status } = await fetch(`${address}/${statusPage}`);
48        if (status === 200) {
49          onlineDevSessions.push({
50            url: address,
51            description: address,
52            source: 'desktop',
53          });
54        }
55      } catch (e) {}
56    })
57  );
58
59  return onlineDevSessions;
60}
61
62export async function fetchDevSessions(installationID?: string) {
63  let devSessionsEndpoint = `/development-sessions`;
64  const headers = {};
65
66  if (installationID != null) {
67    devSessionsEndpoint += `?deviceId=${installationID}`;
68    headers['Expo-Dev-Client-ID'] = installationID;
69  }
70
71  const sessions = await restClient<{ data: DevSession[] }>(devSessionsEndpoint, { headers });
72  return sessions.data ?? [];
73}
74