1import { ExpoConfig } from 'expo/config';
2
3/*
4 * Converts the slug from app configuration to a string that's a valid URI scheme.
5 * From RFC3986 Section 3.1.
6 * scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
7 */
8export default function getDefaultScheme(config: Pick<ExpoConfig, 'slug'>): string {
9  if (typeof config !== 'object') {
10    throw new TypeError('getDefaultScheme: config is not object');
11  }
12  if (!config.slug || typeof config.slug !== 'string') {
13    throw new TypeError('getDefaultScheme: config missing required property "slug"');
14  }
15
16  // Remove unallowed characters. Also remove `-` to keep this shorter.
17  let scheme = config.slug.replace(/[^A-Za-z0-9+\-.]/g, '');
18  // Edge case: if the slug didn't include any allowed characters we may end up with an empty string.
19  if (scheme.length === 0) {
20    throw new Error(
21      'Could not autogenerate a scheme. Please make sure the "slug" property in app config consists of URL friendly characters.'
22    );
23  }
24
25  // Lowercasing might not be strictly necessary, but let's do it for stylistic purposes.
26  scheme = scheme.toLowerCase();
27
28  // Add a prefix to avoid leading digits and to distinguish from user-defined schemes.
29  return `exp+${scheme}`;
30}
31