Skip to content

Commit

Permalink
flow: Annotate exported functions that return the result of a fetch.
Browse files Browse the repository at this point in the history
To bring us closer to annotating all our exports, for zulip#4907.

Most of these use a new `FixmeUntypedFetchResult` type; see its
jsdoc.

`apiFetch` can be unexported; so, do that, removing the need for an
annotation [1].

`savePushToken` and `forgetPushToken` get `Promise<mixed>` because
we don't actually inspect the returned result at all [2].

`checkCompatibility` gets `Promise<{ status: number, ... }>` because
we'll always be looking at the response status [3].

[1] zulip#4927 (comment)
[2] zulip#4927 (comment)
[3] zulip#4927 (comment)
  • Loading branch information
chrisbobbe committed Aug 4, 2021
1 parent ab9c903 commit 2165914
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 13 deletions.
45 changes: 35 additions & 10 deletions src/api/apiFetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as Sentry from '@sentry/react-native';
import type { UrlParams } from '../utils/url';
import type { Auth } from './transportTypes';
import type { FixmeUntypedFetchResult } from './apiTypes';
import { getAuthHeaders } from './transport';
import { encodeParamsForUrl } from '../utils/url';
import userAgent from '../utils/userAgent';
Expand Down Expand Up @@ -36,7 +37,7 @@ export const getFetchParams = <P: $Diff<$Exact<RequestOptions>, {| headers: mixe
};
};

export const apiFetch = async (
const apiFetch = async (
auth: Auth,
route: string,
params: $Diff<$Exact<RequestOptions>, {| headers: mixed |}>,
Expand All @@ -48,7 +49,7 @@ export const apiCall = async (
route: string,
params: $Diff<$Exact<RequestOptions>, {| headers: mixed |}>,
isSilent: boolean = false,
): Promise<empty> => {
): Promise<FixmeUntypedFetchResult> => {
try {
networkActivityStart(isSilent);

Expand All @@ -67,7 +68,7 @@ export const apiCall = async (
}

const result = interpretApiResponse(response.status, json);
/* $FlowFixMe[incompatible-type] We let the caller pretend this data
/* $FlowFixMe[incompatible-return] We let the caller pretend this data
is whatever it wants it to be. */
return result;
} catch (errorIllTyped) {
Expand Down Expand Up @@ -97,7 +98,7 @@ export const apiGet = async (
route: string,
params: UrlParams = {},
isSilent: boolean = false,
) =>
): Promise<FixmeUntypedFetchResult> =>
apiCall(
auth,
`${route}?${encodeParamsForUrl(params)}`,
Expand All @@ -107,37 +108,61 @@ export const apiGet = async (
isSilent,
);

export const apiPost = async (auth: Auth, route: string, params: UrlParams = {}) =>
export const apiPost = async (
auth: Auth,
route: string,
params: UrlParams = {},
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, route, {
method: 'post',
body: encodeParamsForUrl(params),
});

export const apiFile = async (auth: Auth, route: string, body: FormData) =>
export const apiFile = async (
auth: Auth,
route: string,
body: FormData,
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, route, {
method: 'post',
body,
});

export const apiPut = async (auth: Auth, route: string, params: UrlParams = {}) =>
export const apiPut = async (
auth: Auth,
route: string,
params: UrlParams = {},
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, route, {
method: 'put',
body: encodeParamsForUrl(params),
});

export const apiDelete = async (auth: Auth, route: string, params: UrlParams = {}) =>
export const apiDelete = async (
auth: Auth,
route: string,
params: UrlParams = {},
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, route, {
method: 'delete',
body: encodeParamsForUrl(params),
});

export const apiPatch = async (auth: Auth, route: string, params: UrlParams = {}) =>
export const apiPatch = async (
auth: Auth,
route: string,
params: UrlParams = {},
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, route, {
method: 'patch',
body: encodeParamsForUrl(params),
});

export const apiHead = async (auth: Auth, route: string, params: UrlParams = {}) =>
export const apiHead = async (
auth: Auth,
route: string,
params: UrlParams = {},
): Promise<FixmeUntypedFetchResult> =>
apiCall(auth, `${route}?${encodeParamsForUrl(params)}`, {
method: 'head',
});
9 changes: 9 additions & 0 deletions src/api/apiTypes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
/* @flow strict-local */

/**
* Temporary placeholder for the resolve type of a `fetch`.
*
* The `empty` is bogus, as we saw in 4ef0f061e. As mentioned there, it's
* because React Native defeats type-checking on `fetch` calls. We expect
* that'll be fixed in RN v0.65, with facebook/react-native@6651b7c59.
*/
export type FixmeUntypedFetchResult = empty;

export type * from './transportTypes';
export type * from './modelTypes';
export type * from './eventTypes';
Expand Down
2 changes: 1 addition & 1 deletion src/api/checkCompatibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import userAgent from '../utils/userAgent';

// check with server if current mobile app is compatible with latest backend
// compatibility fails only if server responds with 400 (but not with 200 or 404)
export default () =>
export default (): Promise<{ status: number, ... }> =>
fetch('https://zulip.com/compatibility', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
Expand Down
2 changes: 1 addition & 1 deletion src/api/notifications/forgetPushToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { apiDelete } from '../apiFetch';
*
* @param mobileOS - Choose the server-side API intended for iOS or Android clients.
*/
export default (auth: Auth, mobileOS: 'ios' | 'android', token: string) => {
export default (auth: Auth, mobileOS: 'ios' | 'android', token: string): Promise<mixed> => {
const routeName = mobileOS === 'android' ? 'android_gcm_reg_id' : 'apns_device_token';
return apiDelete(auth, `users/me/${routeName}`, { token });
};
2 changes: 1 addition & 1 deletion src/api/notifications/savePushToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { apiPost } from '../apiFetch';
*
* @param mobileOS - Choose the server-side API intended for iOS or Android clients.
*/
export default async (auth: Auth, mobileOS: 'ios' | 'android', token: string) => {
export default async (auth: Auth, mobileOS: 'ios' | 'android', token: string): Promise<mixed> => {
const routeName = mobileOS === 'android' ? 'android_gcm_reg_id' : 'apns_device_token';
const extraParams = mobileOS === 'android' ? {} : { appid: 'org.zulip.Zulip' };
return apiPost(auth, `users/me/${routeName}`, {
Expand Down

0 comments on commit 2165914

Please sign in to comment.