diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/api/api-config.ts | 4 | ||||
-rw-r--r-- | app/services/api/api-problem.test.ts | 94 | ||||
-rw-r--r-- | app/services/api/api-problem.ts | 56 | ||||
-rw-r--r-- | app/services/api/api.ts | 18 | ||||
-rw-r--r-- | app/services/api/api.types.ts | 16 | ||||
-rw-r--r-- | app/services/api/character-api.ts | 14 | ||||
-rw-r--r-- | app/services/api/index.ts | 4 | ||||
-rw-r--r-- | app/services/reactotron/index.ts | 2 | ||||
-rw-r--r-- | app/services/reactotron/reactotron-config.ts | 2 | ||||
-rw-r--r-- | app/services/reactotron/reactotron.ts | 61 | ||||
-rw-r--r-- | app/services/reactotron/tron.ts | 2 | ||||
-rw-r--r-- | app/services/reactotron/tron.web.ts | 2 |
12 files changed, 160 insertions, 115 deletions
diff --git a/app/services/api/api-config.ts b/app/services/api/api-config.ts index 3061563..b939c0e 100644 --- a/app/services/api/api-config.ts +++ b/app/services/api/api-config.ts @@ -1,7 +1,7 @@ // Use this import if you want to use "env.js" file // const { API_URL } = require("../../config/env") // Or just specify it directly like this: -const API_URL = "http://example.com" +const API_URL = 'http://example.com' /** * The options used to configure the API. @@ -22,6 +22,6 @@ export interface ApiConfig { * The default configuration for the app. */ export const DEFAULT_API_CONFIG: ApiConfig = { - url: API_URL || "https://jsonplaceholder.typicode.com", + url: API_URL || 'https://jsonplaceholder.typicode.com', timeout: 10000, } diff --git a/app/services/api/api-problem.test.ts b/app/services/api/api-problem.test.ts index ccd35c9..2b37aa9 100644 --- a/app/services/api/api-problem.test.ts +++ b/app/services/api/api-problem.test.ts @@ -1,72 +1,104 @@ -import { getGeneralApiProblem } from "./api-problem" -import { ApiErrorResponse } from "apisauce" +import { getGeneralApiProblem } from './api-problem' +import { ApiErrorResponse } from 'apisauce' -test("handles connection errors", () => { - expect(getGeneralApiProblem({ problem: "CONNECTION_ERROR" } as ApiErrorResponse<null>)).toEqual({ - kind: "cannot-connect", +test('handles connection errors', () => { + expect( + getGeneralApiProblem({ + problem: 'CONNECTION_ERROR', + } as ApiErrorResponse<null>), + ).toEqual({ + kind: 'cannot-connect', temporary: true, }) }) -test("handles network errors", () => { - expect(getGeneralApiProblem({ problem: "NETWORK_ERROR" } as ApiErrorResponse<null>)).toEqual({ - kind: "cannot-connect", +test('handles network errors', () => { + expect( + getGeneralApiProblem({ + problem: 'NETWORK_ERROR', + } as ApiErrorResponse<null>), + ).toEqual({ + kind: 'cannot-connect', temporary: true, }) }) -test("handles timeouts", () => { - expect(getGeneralApiProblem({ problem: "TIMEOUT_ERROR" } as ApiErrorResponse<null>)).toEqual({ - kind: "timeout", +test('handles timeouts', () => { + expect( + getGeneralApiProblem({ + problem: 'TIMEOUT_ERROR', + } as ApiErrorResponse<null>), + ).toEqual({ + kind: 'timeout', temporary: true, }) }) -test("handles server errors", () => { - expect(getGeneralApiProblem({ problem: "SERVER_ERROR" } as ApiErrorResponse<null>)).toEqual({ - kind: "server", +test('handles server errors', () => { + expect( + getGeneralApiProblem({ problem: 'SERVER_ERROR' } as ApiErrorResponse<null>), + ).toEqual({ + kind: 'server', }) }) -test("handles unknown errors", () => { - expect(getGeneralApiProblem({ problem: "UNKNOWN_ERROR" } as ApiErrorResponse<null>)).toEqual({ - kind: "unknown", +test('handles unknown errors', () => { + expect( + getGeneralApiProblem({ + problem: 'UNKNOWN_ERROR', + } as ApiErrorResponse<null>), + ).toEqual({ + kind: 'unknown', temporary: true, }) }) -test("handles unauthorized errors", () => { +test('handles unauthorized errors', () => { expect( - getGeneralApiProblem({ problem: "CLIENT_ERROR", status: 401 } as ApiErrorResponse<null>), + getGeneralApiProblem({ + problem: 'CLIENT_ERROR', + status: 401, + } as ApiErrorResponse<null>), ).toEqual({ - kind: "unauthorized", + kind: 'unauthorized', }) }) -test("handles forbidden errors", () => { +test('handles forbidden errors', () => { expect( - getGeneralApiProblem({ problem: "CLIENT_ERROR", status: 403 } as ApiErrorResponse<null>), + getGeneralApiProblem({ + problem: 'CLIENT_ERROR', + status: 403, + } as ApiErrorResponse<null>), ).toEqual({ - kind: "forbidden", + kind: 'forbidden', }) }) -test("handles not-found errors", () => { +test('handles not-found errors', () => { expect( - getGeneralApiProblem({ problem: "CLIENT_ERROR", status: 404 } as ApiErrorResponse<null>), + getGeneralApiProblem({ + problem: 'CLIENT_ERROR', + status: 404, + } as ApiErrorResponse<null>), ).toEqual({ - kind: "not-found", + kind: 'not-found', }) }) -test("handles other client errors", () => { +test('handles other client errors', () => { expect( - getGeneralApiProblem({ problem: "CLIENT_ERROR", status: 418 } as ApiErrorResponse<null>), + getGeneralApiProblem({ + problem: 'CLIENT_ERROR', + status: 418, + } as ApiErrorResponse<null>), ).toEqual({ - kind: "rejected", + kind: 'rejected', }) }) -test("handles cancellation errors", () => { - expect(getGeneralApiProblem({ problem: "CANCEL_ERROR" } as ApiErrorResponse<null>)).toBeNull() +test('handles cancellation errors', () => { + expect( + getGeneralApiProblem({ problem: 'CANCEL_ERROR' } as ApiErrorResponse<null>), + ).toBeNull() }) diff --git a/app/services/api/api-problem.ts b/app/services/api/api-problem.ts index 9c2aa49..d5b1445 100644 --- a/app/services/api/api-problem.ts +++ b/app/services/api/api-problem.ts @@ -1,72 +1,74 @@ -import { ApiResponse } from "apisauce" +import { ApiResponse } from 'apisauce' export type GeneralApiProblem = /** * Times up. */ - | { kind: "timeout"; temporary: true } + | { kind: 'timeout'; temporary: true } /** * Cannot connect to the server for some reason. */ - | { kind: "cannot-connect"; temporary: true } + | { kind: 'cannot-connect'; temporary: true } /** * The server experienced a problem. Any 5xx error. */ - | { kind: "server" } + | { kind: 'server' } /** * We're not allowed because we haven't identified ourself. This is 401. */ - | { kind: "unauthorized" } + | { kind: 'unauthorized' } /** * We don't have access to perform that request. This is 403. */ - | { kind: "forbidden" } + | { kind: 'forbidden' } /** * Unable to find that resource. This is a 404. */ - | { kind: "not-found" } + | { kind: 'not-found' } /** * All other 4xx series errors. */ - | { kind: "rejected" } + | { kind: 'rejected' } /** * Something truly unexpected happened. Most likely can try again. This is a catch all. */ - | { kind: "unknown"; temporary: true } + | { kind: 'unknown'; temporary: true } /** * The data we received is not in the expected format. */ - | { kind: "bad-data" } + | { kind: 'bad-data' } /** * Attempts to get a common cause of problems from an api response. * * @param response The api response. */ -export function getGeneralApiProblem(response: ApiResponse<any>): GeneralApiProblem | void { +export function getGeneralApiProblem( + response: ApiResponse<any>, +): GeneralApiProblem | void { switch (response.problem) { - case "CONNECTION_ERROR": - return { kind: "cannot-connect", temporary: true } - case "NETWORK_ERROR": - return { kind: "cannot-connect", temporary: true } - case "TIMEOUT_ERROR": - return { kind: "timeout", temporary: true } - case "SERVER_ERROR": - return { kind: "server" } - case "UNKNOWN_ERROR": - return { kind: "unknown", temporary: true } - case "CLIENT_ERROR": + case 'CONNECTION_ERROR': + return { kind: 'cannot-connect', temporary: true } + case 'NETWORK_ERROR': + return { kind: 'cannot-connect', temporary: true } + case 'TIMEOUT_ERROR': + return { kind: 'timeout', temporary: true } + case 'SERVER_ERROR': + return { kind: 'server' } + case 'UNKNOWN_ERROR': + return { kind: 'unknown', temporary: true } + case 'CLIENT_ERROR': switch (response.status) { case 401: - return { kind: "unauthorized" } + return { kind: 'unauthorized' } case 403: - return { kind: "forbidden" } + return { kind: 'forbidden' } case 404: - return { kind: "not-found" } + return { kind: 'not-found' } default: - return { kind: "rejected" } + return { kind: 'rejected' } } - case "CANCEL_ERROR": + case 'CANCEL_ERROR': return null } diff --git a/app/services/api/api.ts b/app/services/api/api.ts index 15f6815..4093d34 100644 --- a/app/services/api/api.ts +++ b/app/services/api/api.ts @@ -1,7 +1,7 @@ -import { ApisauceInstance, create, ApiResponse } from "apisauce" -import { getGeneralApiProblem } from "./api-problem" -import { ApiConfig, DEFAULT_API_CONFIG } from "./api-config" -import * as Types from "./api.types" +import { ApisauceInstance, create, ApiResponse } from 'apisauce' +import { getGeneralApiProblem } from './api-problem' +import { ApiConfig, DEFAULT_API_CONFIG } from './api-config' +import * as Types from './api.types' /** * Manages all requests to the API. @@ -39,7 +39,7 @@ export class Api { baseURL: this.config.url, timeout: this.config.timeout, headers: { - Accept: "application/json", + Accept: 'application/json', }, }) } @@ -68,9 +68,9 @@ export class Api { try { const rawUsers = response.data const resultUsers: Types.User[] = rawUsers.map(convertUser) - return { kind: "ok", users: resultUsers } + return { kind: 'ok', users: resultUsers } } catch { - return { kind: "bad-data" } + return { kind: 'bad-data' } } } @@ -94,9 +94,9 @@ export class Api { id: response.data.id, name: response.data.name, } - return { kind: "ok", user: resultUser } + return { kind: 'ok', user: resultUser } } catch { - return { kind: "bad-data" } + return { kind: 'bad-data' } } } } diff --git a/app/services/api/api.types.ts b/app/services/api/api.types.ts index dde58c0..5090e74 100644 --- a/app/services/api/api.types.ts +++ b/app/services/api/api.types.ts @@ -1,13 +1,17 @@ -import { GeneralApiProblem } from "./api-problem" -import { Character } from "../../models/character/character" +import { GeneralApiProblem } from './api-problem' +import { Character } from '../../models/character/character' export interface User { id: number name: string } -export type GetUsersResult = { kind: "ok"; users: User[] } | GeneralApiProblem -export type GetUserResult = { kind: "ok"; user: User } | GeneralApiProblem +export type GetUsersResult = { kind: 'ok'; users: User[] } | GeneralApiProblem +export type GetUserResult = { kind: 'ok'; user: User } | GeneralApiProblem -export type GetCharactersResult = { kind: "ok"; characters: Character[] } | GeneralApiProblem -export type GetCharacterResult = { kind: "ok"; character: Character } | GeneralApiProblem +export type GetCharactersResult = + | { kind: 'ok'; characters: Character[] } + | GeneralApiProblem +export type GetCharacterResult = + | { kind: 'ok'; character: Character } + | GeneralApiProblem diff --git a/app/services/api/character-api.ts b/app/services/api/character-api.ts index 7755006..e28ec48 100644 --- a/app/services/api/character-api.ts +++ b/app/services/api/character-api.ts @@ -1,7 +1,7 @@ -import { ApiResponse } from "apisauce" -import { Api } from "./api" -import { GetCharactersResult } from "./api.types" -import { getGeneralApiProblem } from "./api-problem" +import { ApiResponse } from 'apisauce' +import { Api } from './api' +import { GetCharactersResult } from './api.types' +import { getGeneralApiProblem } from './api-problem' const API_PAGE_SIZE = 50 @@ -16,7 +16,7 @@ export class CharacterApi { try { // make the api call const response: ApiResponse<any> = await this.api.apisauce.get( - "https://raw.githubusercontent.com/infinitered/ignite/master/data/rick-and-morty.json", + 'https://raw.githubusercontent.com/infinitered/ignite/master/data/rick-and-morty.json', { amount: API_PAGE_SIZE }, ) @@ -28,10 +28,10 @@ export class CharacterApi { const characters = response.data.results - return { kind: "ok", characters } + return { kind: 'ok', characters } } catch (e) { __DEV__ && console.tron.log(e.message) - return { kind: "bad-data" } + return { kind: 'bad-data' } } } } diff --git a/app/services/api/index.ts b/app/services/api/index.ts index a12bb55..f133e64 100644 --- a/app/services/api/index.ts +++ b/app/services/api/index.ts @@ -1,2 +1,2 @@ -export * from "./api" -export * from "./api.types" +export * from './api' +export * from './api.types' diff --git a/app/services/reactotron/index.ts b/app/services/reactotron/index.ts index 60a8b40..0c02f1f 100644 --- a/app/services/reactotron/index.ts +++ b/app/services/reactotron/index.ts @@ -1 +1 @@ -export * from "./reactotron" +export * from './reactotron' diff --git a/app/services/reactotron/reactotron-config.ts b/app/services/reactotron/reactotron-config.ts index dd87bd7..40e9c93 100644 --- a/app/services/reactotron/reactotron-config.ts +++ b/app/services/reactotron/reactotron-config.ts @@ -21,7 +21,7 @@ export interface ReactotronConfig { */ export const DEFAULT_REACTOTRON_CONFIG: ReactotronConfig = { clearOnLoad: true, - host: "localhost", + host: 'localhost', useAsyncStorage: true, state: { initial: true, diff --git a/app/services/reactotron/reactotron.ts b/app/services/reactotron/reactotron.ts index 0ec12ad..eda9ed9 100644 --- a/app/services/reactotron/reactotron.ts +++ b/app/services/reactotron/reactotron.ts @@ -1,12 +1,15 @@ -import { Tron } from "./tron" -import AsyncStorage from "@react-native-async-storage/async-storage" -import { RootStore } from "../../models/root-store/root-store" -import { onSnapshot } from "mobx-state-tree" -import { ReactotronConfig, DEFAULT_REACTOTRON_CONFIG } from "./reactotron-config" -import { mst } from "reactotron-mst" -import { clear } from "../../utils/storage" -import { RootNavigation } from "../../navigators" -import { Platform } from "react-native" +import { Tron } from './tron' +import AsyncStorage from '@react-native-async-storage/async-storage' +import { RootStore } from '../../models/root-store/root-store' +import { onSnapshot } from 'mobx-state-tree' +import { + ReactotronConfig, + DEFAULT_REACTOTRON_CONFIG, +} from './reactotron-config' +import { mst } from 'reactotron-mst' +import { clear } from '../../utils/storage' +import { RootNavigation } from '../../navigators' +import { Platform } from 'react-native' // Teach TypeScript about the bad things we want to do. declare global { @@ -67,7 +70,7 @@ export class Reactotron { constructor(config: ReactotronConfig = DEFAULT_REACTOTRON_CONFIG) { // merge the passed in config with some defaults this.config = { - host: "localhost", + host: 'localhost', useAsyncStorage: true, ...config, state: { @@ -89,16 +92,20 @@ export class Reactotron { this.rootStore = rootStore const { initial, snapshots } = this.config.state - const name = "ROOT STORE" + const name = 'ROOT STORE' // logging features if (initial) { - console.tron.display({ name, value: initialData, preview: "Initial State" }) + console.tron.display({ + name, + value: initialData, + preview: 'Initial State', + }) } // log state changes? if (snapshots) { onSnapshot(rootStore, (snapshot) => { - console.tron.display({ name, value: snapshot, preview: "New State" }) + console.tron.display({ name, value: snapshot, preview: 'New State' }) }) } @@ -114,12 +121,12 @@ export class Reactotron { if (__DEV__) { // configure reactotron Tron.configure({ - name: this.config.name || require("../../../package.json").name, + name: this.config.name || require('../../../package.json').name, host: this.config.host, }) // hookup middleware - if (Platform.OS !== "web") { + if (Platform.OS !== 'web') { if (this.config.useAsyncStorage) { Tron.setAsyncStorageHandler(AsyncStorage) } @@ -143,31 +150,31 @@ export class Reactotron { // Register Custom Commands Tron.onCustomCommand({ - title: "Reset Root Store", - description: "Resets the MST store", - command: "resetStore", + title: 'Reset Root Store', + description: 'Resets the MST store', + command: 'resetStore', handler: () => { - console.tron.log("resetting store") + console.tron.log('resetting store') clear() }, }) Tron.onCustomCommand({ - title: "Reset Navigation State", - description: "Resets the navigation state", - command: "resetNavigation", + title: 'Reset Navigation State', + description: 'Resets the navigation state', + command: 'resetNavigation', handler: () => { - console.tron.log("resetting navigation state") + console.tron.log('resetting navigation state') RootNavigation.resetRoot({ routes: [] }) }, }) Tron.onCustomCommand({ - title: "Go Back", - description: "Goes back", - command: "goBack", + title: 'Go Back', + description: 'Goes back', + command: 'goBack', handler: () => { - console.tron.log("Going back") + console.tron.log('Going back') RootNavigation.goBack() }, }) diff --git a/app/services/reactotron/tron.ts b/app/services/reactotron/tron.ts index f6c872d..6086e48 100644 --- a/app/services/reactotron/tron.ts +++ b/app/services/reactotron/tron.ts @@ -1,2 +1,2 @@ -import Reactotron from "reactotron-react-native" +import Reactotron from 'reactotron-react-native' export const Tron = Reactotron diff --git a/app/services/reactotron/tron.web.ts b/app/services/reactotron/tron.web.ts index bcee53b..a525c06 100644 --- a/app/services/reactotron/tron.web.ts +++ b/app/services/reactotron/tron.web.ts @@ -1,2 +1,2 @@ -import Reactotron from "reactotron-react-js" +import Reactotron from 'reactotron-react-js' export const Tron = Reactotron |