UNPKG

@stevesouth/expo-auth-session

Version:

Expo module for browser-based authentication

74 lines (61 loc) 2.15 kB
import { Platform } from 'expo-modules-core'; import qs from 'qs'; export type Headers = Record<string, string> & { 'Content-Type': string; Authorization?: string; Accept?: string; }; export type FetchRequest = { headers?: Headers; body?: Record<string, string>; dataType?: string; method?: string; }; // TODO(Bacon): pending react-native-adapter publish after sdk 38 const isDOMAvailable = Platform.OS === 'web' && typeof window !== 'undefined' && !!window.document?.createElement && typeof URL !== 'undefined'; export async function requestAsync<T>(requestUrl: string, fetchRequest: FetchRequest): Promise<T> { if (Platform.OS === 'web' && !isDOMAvailable) { // @ts-ignore return; } const url = new URL(requestUrl); const request: Omit<RequestInit, 'headers'> & { headers: HeadersInit } = { method: fetchRequest.method, mode: 'cors', headers: {}, }; const isJsonDataType = fetchRequest.dataType?.toLowerCase() === 'json'; if (fetchRequest.headers) { for (const i in fetchRequest.headers) { if (i in fetchRequest.headers) { request.headers[i] = fetchRequest.headers[i] as string; } } } if (fetchRequest.body) { if (fetchRequest.method?.toUpperCase() === 'POST') { request.body = qs.stringify(fetchRequest.body); } else { for (const key of Object.keys(fetchRequest.body)) { url.searchParams.append(key, fetchRequest.body[key]); } } } if (isJsonDataType && !('Accept' in request.headers)) { // NOTE: Github authentication will return XML if this includes the standard `*/*` request.headers['Accept'] = 'application/json, text/javascript; q=0.01'; } // Fix a problem with React Native `URL` causing a trailing slash to be added. const correctedUrl = url.toString().replace(/\/$/, ''); const response = await fetch(correctedUrl, request); const contentType = response.headers.get('content-type'); if (isJsonDataType || contentType?.includes('application/json')) { return response.json(); } // @ts-ignore: Type 'string' is not assignable to type 'T'. return response.text(); }