mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 14:43:25 +00:00
remove ofetch, replace with fetch
This commit is contained in:
@@ -32,7 +32,6 @@
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@scure/bip39": "^1.3.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"ofetch": "^1.3.4"
|
||||
"node-forge": "^1.3.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type { LoginResponse } from "./types";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function getAuthHeaders(token: string): Record<string, string> {
|
||||
return {
|
||||
@@ -13,12 +12,12 @@ export async function accountLogin(
|
||||
id: string,
|
||||
deviceName: string,
|
||||
): Promise<LoginResponse> {
|
||||
return ofetch<LoginResponse>("/auth/login", {
|
||||
return f<LoginResponse>("/auth/login", {
|
||||
method: "POST",
|
||||
body: {
|
||||
id,
|
||||
device: deviceName,
|
||||
},
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,3 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
AccountWithToken,
|
||||
BookmarkInput,
|
||||
@@ -7,6 +5,7 @@ import type {
|
||||
BookmarkResponse,
|
||||
} from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function bookmarkMediaToInput(
|
||||
tmdbId: string,
|
||||
@@ -28,12 +27,12 @@ export async function addBookmark(
|
||||
account: AccountWithToken,
|
||||
input: BookmarkInput,
|
||||
) {
|
||||
return ofetch<BookmarkResponse>(
|
||||
return f<BookmarkResponse>(
|
||||
`/users/${account.userId}/bookmarks/${input.tmdbId}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
body: input,
|
||||
},
|
||||
);
|
||||
@@ -44,12 +43,9 @@ export async function removeBookmark(
|
||||
account: AccountWithToken,
|
||||
id: string,
|
||||
) {
|
||||
return ofetch<{ tmdbId: string }>(
|
||||
`/users/${account.userId}/bookmarks/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
},
|
||||
);
|
||||
return f<{ tmdbId: string }>(`/users/${account.userId}/bookmarks/${id}`, {
|
||||
method: "DELETE",
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -39,11 +39,7 @@ export function genMnemonic(): string {
|
||||
return generateMnemonic(wordlist);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function signCode(
|
||||
code: string,
|
||||
privateKey: Uint8Array,
|
||||
): Promise<Uint8Array> {
|
||||
export function signCode(code: string, privateKey: Uint8Array): Uint8Array {
|
||||
return forge.pki.ed25519.sign({
|
||||
encoding: "utf8",
|
||||
message: code,
|
||||
@@ -62,8 +58,8 @@ export function bytesToBase64Url(bytes: Uint8Array): string {
|
||||
.replace(/=+$/, "");
|
||||
}
|
||||
|
||||
export async function signChallenge(keys: Keys, challengeCode: string) {
|
||||
const signature = await signCode(challengeCode, keys.privateKey);
|
||||
export function signChallenge(keys: Keys, challengeCode: string) {
|
||||
const signature = signCode(challengeCode, keys.privateKey);
|
||||
return bytesToBase64Url(signature);
|
||||
}
|
||||
|
||||
|
53
packages/api/src/fetch.ts
Normal file
53
packages/api/src/fetch.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
export interface FetcherOptions {
|
||||
baseUrl?: string;
|
||||
headers?: Record<string, string>;
|
||||
query?: Record<string, string>;
|
||||
method?: "HEAD" | "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
||||
readHeaders?: string[];
|
||||
body?: Record<string, any>;
|
||||
}
|
||||
|
||||
export type FullUrlOptions = Pick<FetcherOptions, "query" | "baseUrl">;
|
||||
|
||||
export function makeFullUrl(url: string, ops?: FullUrlOptions): string {
|
||||
// glue baseUrl and rest of url together
|
||||
let leftSide = ops?.baseUrl ?? "";
|
||||
let rightSide = url;
|
||||
|
||||
// left side should always end with slash, if its set
|
||||
if (leftSide.length > 0 && !leftSide.endsWith("/")) leftSide += "/";
|
||||
|
||||
// right side should never start with slash
|
||||
if (rightSide.startsWith("/")) rightSide = rightSide.slice(1);
|
||||
|
||||
const fullUrl = leftSide + rightSide;
|
||||
if (!fullUrl.startsWith("http://") && !fullUrl.startsWith("https://"))
|
||||
throw new Error(
|
||||
`Invald URL -- URL doesn't start with a http scheme: '${fullUrl}'`,
|
||||
);
|
||||
|
||||
const parsedUrl = new URL(fullUrl);
|
||||
Object.entries(ops?.query ?? {}).forEach(([k, v]) => {
|
||||
parsedUrl.searchParams.set(k, v);
|
||||
});
|
||||
|
||||
return parsedUrl.toString();
|
||||
}
|
||||
|
||||
export async function f<T>(url: string, ops?: FetcherOptions): Promise<T> {
|
||||
const fullUrl = makeFullUrl(url, ops);
|
||||
const response = await fetch(fullUrl, {
|
||||
method: ops?.method ?? "GET",
|
||||
headers: ops?.headers,
|
||||
body: ops?.body ? JSON.stringify(ops.body) : undefined,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch '${fullUrl}' -- ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
const data = (await response.json()) as T;
|
||||
return data;
|
||||
}
|
@@ -1,17 +1,16 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type { AccountWithToken, BookmarkInput, ProgressInput } from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function importProgress(
|
||||
url: string,
|
||||
account: AccountWithToken,
|
||||
progressItems: ProgressInput[],
|
||||
) {
|
||||
return ofetch<void>(`/users/${account.userId}/progress/import`, {
|
||||
return f<void>(`/users/${account.userId}/progress/import`, {
|
||||
method: "PUT",
|
||||
body: progressItems,
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
headers: getAuthHeaders(account.token),
|
||||
});
|
||||
}
|
||||
@@ -21,10 +20,10 @@ export function importBookmarks(
|
||||
account: AccountWithToken,
|
||||
bookmarks: BookmarkInput[],
|
||||
) {
|
||||
return ofetch<void>(`/users/${account.userId}/bookmarks`, {
|
||||
return f<void>(`/users/${account.userId}/bookmarks`, {
|
||||
method: "PUT",
|
||||
body: bookmarks,
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
headers: getAuthHeaders(account.token),
|
||||
});
|
||||
}
|
||||
|
@@ -1,21 +1,20 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
ChallengeTokenResponse,
|
||||
LoginInput,
|
||||
LoginResponse,
|
||||
} from "./types";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export async function getLoginChallengeToken(
|
||||
url: string,
|
||||
publicKey: string,
|
||||
): Promise<ChallengeTokenResponse> {
|
||||
return ofetch<ChallengeTokenResponse>("/auth/login/start", {
|
||||
return f<ChallengeTokenResponse>("/auth/login/start", {
|
||||
method: "POST",
|
||||
body: {
|
||||
publicKey,
|
||||
},
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,12 +22,12 @@ export async function loginAccount(
|
||||
url: string,
|
||||
data: LoginInput,
|
||||
): Promise<LoginResponse> {
|
||||
return ofetch<LoginResponse>("/auth/login/complete", {
|
||||
return f<LoginResponse>("/auth/login/complete", {
|
||||
method: "POST",
|
||||
body: {
|
||||
namespace: "movie-web",
|
||||
...data,
|
||||
},
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type { MetaResponse } from "./types";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export async function getBackendMeta(url: string): Promise<MetaResponse> {
|
||||
return ofetch<MetaResponse>("/meta", {
|
||||
baseURL: url,
|
||||
export function getBackendMeta(url: string): Promise<MetaResponse> {
|
||||
return f<MetaResponse>("/meta", {
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,3 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
AccountWithToken,
|
||||
ProgressInput,
|
||||
@@ -8,6 +6,7 @@ import type {
|
||||
ProgressUpdateItem,
|
||||
} from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function progressUpdateItemToInput(
|
||||
item: ProgressUpdateItem,
|
||||
@@ -72,12 +71,12 @@ export async function setProgress(
|
||||
account: AccountWithToken,
|
||||
input: ProgressInput,
|
||||
) {
|
||||
return ofetch<ProgressResponse>(
|
||||
return f<ProgressResponse>(
|
||||
`/users/${account.userId}/progress/${input.tmdbId}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
body: input,
|
||||
},
|
||||
);
|
||||
@@ -90,10 +89,10 @@ export async function removeProgress(
|
||||
episodeId?: string,
|
||||
seasonId?: string,
|
||||
) {
|
||||
await ofetch(`/users/${account.userId}/progress/${id}`, {
|
||||
await f(`/users/${account.userId}/progress/${id}`, {
|
||||
method: "DELETE",
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
body: {
|
||||
episodeId,
|
||||
seasonId,
|
||||
|
@@ -1,22 +1,21 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
ChallengeTokenResponse,
|
||||
RegisterInput,
|
||||
SessionResponse,
|
||||
UserResponse,
|
||||
} from "./types";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export async function getRegisterChallengeToken(
|
||||
url: string,
|
||||
captchaToken?: string,
|
||||
): Promise<ChallengeTokenResponse> {
|
||||
return ofetch<ChallengeTokenResponse>("/auth/register/start", {
|
||||
return f<ChallengeTokenResponse>("/auth/register/start", {
|
||||
method: "POST",
|
||||
body: {
|
||||
captchaToken,
|
||||
},
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,12 +29,12 @@ export async function registerAccount(
|
||||
url: string,
|
||||
data: RegisterInput,
|
||||
): Promise<RegisterResponse> {
|
||||
return ofetch<RegisterResponse>("/auth/register/complete", {
|
||||
return f<RegisterResponse>("/auth/register/complete", {
|
||||
method: "POST",
|
||||
body: {
|
||||
namespace: "movie-web",
|
||||
...data,
|
||||
},
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -1,12 +1,11 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type { AccountWithToken, SessionResponse, SessionUpdate } from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export async function getSessions(url: string, account: AccountWithToken) {
|
||||
return ofetch<SessionResponse[]>(`/users/${account.userId}/sessions`, {
|
||||
return f<SessionResponse[]>(`/users/${account.userId}/sessions`, {
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,11 +14,11 @@ export async function updateSession(
|
||||
account: AccountWithToken,
|
||||
update: SessionUpdate,
|
||||
) {
|
||||
return ofetch<SessionResponse[]>(`/sessions/${account.sessionId}`, {
|
||||
return f<SessionResponse[]>(`/sessions/${account.sessionId}`, {
|
||||
method: "PATCH",
|
||||
headers: getAuthHeaders(account.token),
|
||||
body: update,
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,9 +27,9 @@ export async function removeSession(
|
||||
token: string,
|
||||
sessionId: string,
|
||||
) {
|
||||
return ofetch<SessionResponse[]>(`/sessions/${sessionId}`, {
|
||||
return f<SessionResponse[]>(`/sessions/${sessionId}`, {
|
||||
method: "DELETE",
|
||||
headers: getAuthHeaders(token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
@@ -1,29 +1,28 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
AccountWithToken,
|
||||
SettingsInput,
|
||||
SettingsResponse,
|
||||
} from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function updateSettings(
|
||||
url: string,
|
||||
account: AccountWithToken,
|
||||
settings: SettingsInput,
|
||||
) {
|
||||
return ofetch<SettingsResponse>(`/users/${account.userId}/settings`, {
|
||||
return f<SettingsResponse>(`/users/${account.userId}/settings`, {
|
||||
method: "PUT",
|
||||
body: settings,
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
headers: getAuthHeaders(account.token),
|
||||
});
|
||||
}
|
||||
|
||||
export function getSettings(url: string, account: AccountWithToken) {
|
||||
return ofetch<SettingsResponse>(`/users/${account.userId}/settings`, {
|
||||
return f<SettingsResponse>(`/users/${account.userId}/settings`, {
|
||||
method: "GET",
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
headers: getAuthHeaders(account.token),
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,3 @@
|
||||
import { ofetch } from "ofetch";
|
||||
|
||||
import type {
|
||||
AccountWithToken,
|
||||
BookmarkMediaItem,
|
||||
@@ -11,6 +9,7 @@ import type {
|
||||
UserResponse,
|
||||
} from "./types";
|
||||
import { getAuthHeaders } from "./auth";
|
||||
import { f } from "./fetch";
|
||||
|
||||
export function bookmarkResponsesToEntries(responses: BookmarkResponse[]) {
|
||||
const entries = responses.map((bookmark) => {
|
||||
@@ -83,13 +82,10 @@ export async function getUser(
|
||||
url: string,
|
||||
token: string,
|
||||
): Promise<{ user: UserResponse; session: SessionResponse }> {
|
||||
return ofetch<{ user: UserResponse; session: SessionResponse }>(
|
||||
"/users/@me",
|
||||
{
|
||||
headers: getAuthHeaders(token),
|
||||
baseURL: url,
|
||||
},
|
||||
);
|
||||
return f<{ user: UserResponse; session: SessionResponse }>("/users/@me", {
|
||||
headers: getAuthHeaders(token),
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
export async function editUser(
|
||||
@@ -97,13 +93,13 @@ export async function editUser(
|
||||
account: AccountWithToken,
|
||||
object: UserEdit,
|
||||
): Promise<{ user: UserResponse; session: SessionResponse }> {
|
||||
return ofetch<{ user: UserResponse; session: SessionResponse }>(
|
||||
return f<{ user: UserResponse; session: SessionResponse }>(
|
||||
`/users/${account.userId}`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: getAuthHeaders(account.token),
|
||||
body: object,
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -112,22 +108,22 @@ export async function deleteUser(
|
||||
url: string,
|
||||
account: AccountWithToken,
|
||||
): Promise<UserResponse> {
|
||||
return ofetch<UserResponse>(`/users/${account.userId}`, {
|
||||
return f<UserResponse>(`/users/${account.userId}`, {
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getBookmarks(url: string, account: AccountWithToken) {
|
||||
return ofetch<BookmarkResponse[]>(`/users/${account.userId}/bookmarks`, {
|
||||
return f<BookmarkResponse[]>(`/users/${account.userId}/bookmarks`, {
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getProgress(url: string, account: AccountWithToken) {
|
||||
return ofetch<ProgressResponse[]>(`/users/${account.userId}/progress`, {
|
||||
return f<ProgressResponse[]>(`/users/${account.userId}/progress`, {
|
||||
headers: getAuthHeaders(account.token),
|
||||
baseURL: url,
|
||||
baseUrl: url,
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user