18d307f52SEvan Baconimport { ExpoConfig } from '@expo/config';
28d307f52SEvan Baconimport os from 'os';
38d307f52SEvan Baconimport { URLSearchParams } from 'url';
48d307f52SEvan Bacon
58d307f52SEvan Baconimport { fetchAsync } from './rest/client';
6*8a424bebSJames Ideimport { CommandError } from '../utils/errors';
78d307f52SEvan Bacon
88d307f52SEvan Bacon/** Create the expected session info. */
98d307f52SEvan Baconexport function createSessionInfo({
108d307f52SEvan Bacon  exp,
118d307f52SEvan Bacon  runtime,
128d307f52SEvan Bacon  url,
138d307f52SEvan Bacon}: {
148d307f52SEvan Bacon  exp: Pick<ExpoConfig, 'name' | 'description' | 'slug' | 'primaryColor'>;
158d307f52SEvan Bacon  runtime: 'native' | 'web';
168d307f52SEvan Bacon  url: string;
178d307f52SEvan Bacon}) {
188d307f52SEvan Bacon  return {
198d307f52SEvan Bacon    session: {
208d307f52SEvan Bacon      description: `${exp.name} on ${os.hostname()}`,
218d307f52SEvan Bacon      hostname: os.hostname(),
228d307f52SEvan Bacon      platform: runtime,
238d307f52SEvan Bacon      config: {
248d307f52SEvan Bacon        // TODO: if icons are specified, upload a url for them too so people can distinguish
258d307f52SEvan Bacon        description: exp.description,
268d307f52SEvan Bacon        name: exp.name,
278d307f52SEvan Bacon        slug: exp.slug,
288d307f52SEvan Bacon        primaryColor: exp.primaryColor,
298d307f52SEvan Bacon      },
308d307f52SEvan Bacon      url,
318d307f52SEvan Bacon      source: 'desktop',
328d307f52SEvan Bacon    },
338d307f52SEvan Bacon  };
348d307f52SEvan Bacon}
358d307f52SEvan Bacon
368d307f52SEvan Bacon/** Send a request to Expo API to keep the 'development session' alive for the provided devices. */
378d307f52SEvan Baconexport async function updateDevelopmentSessionAsync({
388d307f52SEvan Bacon  deviceIds,
398d307f52SEvan Bacon  exp,
408d307f52SEvan Bacon  runtime,
418d307f52SEvan Bacon  url,
428d307f52SEvan Bacon}: {
438d307f52SEvan Bacon  deviceIds: string[];
448d307f52SEvan Bacon  exp: Pick<ExpoConfig, 'name' | 'description' | 'slug' | 'primaryColor'>;
458d307f52SEvan Bacon  runtime: 'native' | 'web';
468d307f52SEvan Bacon  url: string;
478d307f52SEvan Bacon}) {
488d307f52SEvan Bacon  const searchParams = new URLSearchParams();
498d307f52SEvan Bacon  deviceIds.forEach((id) => {
508d307f52SEvan Bacon    searchParams.append('deviceId', id);
518d307f52SEvan Bacon  });
528d307f52SEvan Bacon
538d307f52SEvan Bacon  const results = await fetchAsync('development-sessions/notify-alive', {
548d307f52SEvan Bacon    searchParams,
558d307f52SEvan Bacon    method: 'POST',
568d307f52SEvan Bacon    body: JSON.stringify({
578d307f52SEvan Bacon      data: createSessionInfo({ exp, runtime, url }),
588d307f52SEvan Bacon    }),
598d307f52SEvan Bacon  });
608d307f52SEvan Bacon
618d307f52SEvan Bacon  if (!results.ok) {
628d307f52SEvan Bacon    throw new CommandError(
638d307f52SEvan Bacon      'API',
648d307f52SEvan Bacon      `Unexpected response when updating the development session on Expo servers: ${results.statusText}.`
658d307f52SEvan Bacon    );
668d307f52SEvan Bacon  }
678d307f52SEvan Bacon}
68edc92349SJuwan Wheatley
69edc92349SJuwan Wheatley/** Send a request to Expo API to close the 'development session' for the provided devices. */
70edc92349SJuwan Wheatleyexport async function closeDevelopmentSessionAsync({
71edc92349SJuwan Wheatley  deviceIds,
72edc92349SJuwan Wheatley  url,
73edc92349SJuwan Wheatley}: {
74edc92349SJuwan Wheatley  deviceIds: string[];
75edc92349SJuwan Wheatley  url: string;
76edc92349SJuwan Wheatley}) {
77edc92349SJuwan Wheatley  const searchParams = new URLSearchParams();
78edc92349SJuwan Wheatley  deviceIds.forEach((id) => {
79edc92349SJuwan Wheatley    searchParams.append('deviceId', id);
80edc92349SJuwan Wheatley  });
81edc92349SJuwan Wheatley
82edc92349SJuwan Wheatley  const results = await fetchAsync('development-sessions/notify-close', {
83edc92349SJuwan Wheatley    searchParams,
84edc92349SJuwan Wheatley    method: 'POST',
85edc92349SJuwan Wheatley    body: JSON.stringify({
86edc92349SJuwan Wheatley      session: { url },
87edc92349SJuwan Wheatley    }),
88edc92349SJuwan Wheatley  });
89edc92349SJuwan Wheatley
90edc92349SJuwan Wheatley  if (!results.ok) {
91edc92349SJuwan Wheatley    throw new CommandError(
92edc92349SJuwan Wheatley      'API',
93edc92349SJuwan Wheatley      `Unexpected response when closing the development session on Expo servers: ${results.statusText}.`
94edc92349SJuwan Wheatley    );
95edc92349SJuwan Wheatley  }
96edc92349SJuwan Wheatley}
97