1import { parse } from 'url';
2
3import { CommandError } from '../../../utils/errors';
4import { ServerRequest } from './server.types';
5
6/** Supported platforms */
7export type RuntimePlatform = 'ios' | 'android';
8
9/**
10 * Extract the runtime platform from the server request.
11 * 1. Query param `platform`: `?platform=ios`
12 * 2. Header `expo-platform`: `'expo-platform': ios`
13 * 2. Legacy header `exponent-platform`: `'exponent-platform': ios`
14 *
15 * Returns first item in the case of an array.
16 */
17export function parsePlatformHeader(req: ServerRequest): string | null {
18  const url = parse(req.url!, /* parseQueryString */ true);
19  const platform =
20    url.query?.platform || req.headers['expo-platform'] || req.headers['exponent-platform'];
21  return (Array.isArray(platform) ? platform[0] : platform) ?? null;
22}
23
24/** Assert if the runtime platform is not included. */
25export function assertMissingRuntimePlatform(platform?: any): asserts platform {
26  if (!platform) {
27    throw new CommandError(
28      'PLATFORM_HEADER',
29      `Must specify "expo-platform" header or "platform" query parameter`
30    );
31  }
32}
33
34/** Assert if the runtime platform is not correct. */
35export function assertRuntimePlatform(platform: string): asserts platform is RuntimePlatform {
36  const stringifiedPlatform = String(platform);
37  if (!['android', 'ios'].includes(stringifiedPlatform)) {
38    throw new CommandError(
39      'PLATFORM_HEADER',
40      `platform must be "android" or "ios". Received: "${platform}"`
41    );
42  }
43}
44