summaryrefslogtreecommitdiff
path: root/packages/misskey-js/src/api.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/misskey-js/src/api.ts')
-rw-r--r--packages/misskey-js/src/api.ts54
1 files changed, 46 insertions, 8 deletions
diff --git a/packages/misskey-js/src/api.ts b/packages/misskey-js/src/api.ts
index 959a634a74..ea1df57f3d 100644
--- a/packages/misskey-js/src/api.ts
+++ b/packages/misskey-js/src/api.ts
@@ -1,7 +1,7 @@
import './autogen/apiClientJSDoc.js';
-import { SwitchCaseResponseType } from './api.types.js';
-import type { Endpoints } from './api.types.js';
+import { endpointReqTypes } from './autogen/endpoint.js';
+import type { SwitchCaseResponseType, Endpoints } from './api.types.js';
export type {
SwitchCaseResponseType,
@@ -14,6 +14,7 @@ export type APIError = {
code: string;
message: string;
kind: 'client' | 'server';
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
info: Record<string, any>;
};
@@ -23,12 +24,13 @@ export function isAPIError(reason: Record<PropertyKey, unknown>): reason is APIE
export type FetchLike = (input: string, init?: {
method?: string;
- body?: string;
+ body?: Blob | FormData | string;
credentials?: RequestCredentials;
cache?: RequestCache;
headers: { [key in string]: string }
}) => Promise<{
status: number;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
json(): Promise<any>;
}>;
@@ -49,20 +51,56 @@ export class APIClient {
this.fetch = opts.fetch ?? ((...args) => fetch(...args));
}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ private assertIsRecord<T>(obj: T): obj is T & Record<string, any> {
+ return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
+ }
+
public request<E extends keyof Endpoints, P extends Endpoints[E]['req']>(
endpoint: E,
params: P = {} as P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>> {
return new Promise((resolve, reject) => {
- this.fetch(`${this.origin}/api/${endpoint}`, {
- method: 'POST',
- body: JSON.stringify({
+ let mediaType = 'application/json';
+ if (endpoint in endpointReqTypes) {
+ mediaType = endpointReqTypes[endpoint];
+ }
+ let payload: FormData | string = '{}';
+
+ if (mediaType === 'application/json') {
+ payload = JSON.stringify({
...params,
i: credential !== undefined ? credential : this.credential,
- }),
+ });
+ } else if (mediaType === 'multipart/form-data') {
+ payload = new FormData();
+ const i = credential !== undefined ? credential : this.credential;
+ if (i != null) {
+ payload.append('i', i);
+ }
+ if (this.assertIsRecord(params)) {
+ for (const key in params) {
+ const value = params[key];
+
+ if (value == null) continue;
+
+ if (value instanceof File || value instanceof Blob) {
+ payload.append(key, value);
+ } else if (typeof value === 'object') {
+ payload.append(key, JSON.stringify(value));
+ } else {
+ payload.append(key, value);
+ }
+ }
+ }
+ }
+
+ this.fetch(`${this.origin}/api/${endpoint}`, {
+ method: 'POST',
+ body: payload,
headers: {
- 'Content-Type': 'application/json',
+ 'Content-Type': endpointReqTypes[endpoint],
},
credentials: 'omit',
cache: 'no-cache',