src/amo/reducers/api.js (149 lines of code) (raw):

/* @flow */ import invariant from 'invariant'; import UAParser from 'ua-parser-js'; import { LOG_OUT_USER } from 'amo/reducers/users'; import type { LogOutUserAction } from 'amo/reducers/users'; import type { Exact } from 'amo/types/util'; export const SET_AUTH_TOKEN: 'SET_AUTH_TOKEN' = 'SET_AUTH_TOKEN'; export const SET_CLIENT_APP: 'SET_CLIENT_APP' = 'SET_CLIENT_APP'; export const SET_LANG: 'SET_LANG' = 'SET_LANG'; export const SET_REGION_CODE: 'SET_REGION_CODE' = 'SET_REGION_CODE'; export const SET_REQUEST_ID: 'SET_REQUEST_ID' = 'SET_REQUEST_ID'; export const SET_USER_AGENT: 'SET_USER_AGENT' = 'SET_USER_AGENT'; export const USER_AGENT_BROWSER_FIREFOX = 'Firefox'; export const USER_AGENT_OS_ANDROID: 'Android' = 'Android'; export const USER_AGENT_OS_IOS: 'iOS' = 'iOS'; // For details, see https://github.com/faisalman/ua-parser-js export type UserAgentInfoType = {| browser: { major?: string, name?: string, version?: string, }, device: { model?: string, type?: string, vendor?: string }, os: { // This is not a complete enumeration. They're just the ones // we have special cases for. name?: typeof USER_AGENT_OS_ANDROID | typeof USER_AGENT_OS_IOS, version?: string, }, |}; export type RegionCodeType = string | null; export type ApiState = { clientApp: string, // See config.get('langs') for all possible values. lang: string, regionCode: RegionCodeType, requestId: string | null, token: string | null, userAgent: string | null, userAgentInfo: UserAgentInfoType, }; export const initialApiState: ApiState = { clientApp: '', lang: '', regionCode: null, requestId: null, token: null, userAgent: null, userAgentInfo: { browser: {}, device: {}, os: {} }, }; export type SetAuthTokenAction = {| payload: {| token: string |}, type: typeof SET_AUTH_TOKEN, |}; export function setAuthToken(token: string): SetAuthTokenAction { if (!token) { throw new Error('token cannot be falsey'); } return { type: SET_AUTH_TOKEN, payload: { token }, }; } export type SetClientAppAction = {| payload: {| clientApp: string |}, type: typeof SET_CLIENT_APP, |}; export function setClientApp(clientApp: string): SetClientAppAction { invariant(clientApp, 'clientApp cannot be falsey'); return { type: SET_CLIENT_APP, payload: { clientApp }, }; } export type SetLangAction = {| payload: {| lang: string |}, type: typeof SET_LANG, |}; export function setLang(lang: string): SetLangAction { invariant(lang, 'lang cannot be falsey'); return { type: SET_LANG, payload: { lang }, }; } export type SetRegionCodeAction = {| payload: {| regionCode: string |}, type: typeof SET_REGION_CODE, |}; export function setRegionCode(regionCode: string): SetRegionCodeAction { return { type: SET_REGION_CODE, payload: { regionCode }, }; } export type SetUserAgentAction = {| payload: {| userAgent: string |}, type: typeof SET_USER_AGENT, |}; export function setUserAgent(userAgent: string): SetUserAgentAction { return { type: SET_USER_AGENT, payload: { userAgent }, }; } export type SetRequestIdAction = {| payload: {| requestId: string |}, type: typeof SET_REQUEST_ID, |}; export function setRequestId(requestId: string): SetRequestIdAction { return { type: SET_REQUEST_ID, payload: { requestId }, }; } type Action = | SetAuthTokenAction | SetLangAction | SetClientAppAction | SetRequestIdAction | SetUserAgentAction | LogOutUserAction; export default function api( // eslint-disable-next-line default-param-last state: Exact<ApiState> = initialApiState, action: Action, ): Exact<ApiState> { switch (action.type) { case SET_AUTH_TOKEN: return { ...state, token: action.payload.token, }; case SET_LANG: return { ...state, lang: action.payload.lang }; case SET_CLIENT_APP: return { ...state, clientApp: action.payload.clientApp }; case SET_REGION_CODE: return { ...state, regionCode: action.payload.regionCode }; case SET_REQUEST_ID: return { ...state, requestId: action.payload.requestId }; case SET_USER_AGENT: { const { browser, device, os } = UAParser(action.payload.userAgent); return { ...state, userAgent: action.payload.userAgent, userAgentInfo: { browser, device, os }, }; } case LOG_OUT_USER: return { ...state, token: null }; default: return state; } }