Skip to content
Snippets Groups Projects
Commit bdb59253 authored by syuilo's avatar syuilo
Browse files

update api api

parent 3557741f
No related branches found
No related tags found
No related merge requests found
......@@ -18,21 +18,13 @@ coming soon
todo
## API request
都度インスタンスやトークンを指定する場合
``` ts
import * as Misskey from 'misskey-js';
const meta = await Misskey.api.request('https://misskey.test', 'meta', { detail: true }, 'TOKEN');
```
最初にインスタンスやトークンを指定し、以後のリクエストでその情報を使いまわす場合
``` ts
import * as Misskey from 'misskey-js';
const cli = new Misskey.api.APIClient({
origin: 'https://misskey.test'
origin: 'https://misskey.test',
credential: 'TOKEN',
});
cli.i = { token: 'TOKEN' };
const meta = await cli.request('meta', { detail: true });
```
......
......@@ -14,54 +14,51 @@ export function isAPIError(reason: any): reason is APIError {
return reason[MK_API_ERROR] === true;
}
export function request<E extends keyof Endpoints>(
origin: string,
endpoint: E,
data: Endpoints[E]['req'] = {},
credential: string | null | undefined,
): Promise<Endpoints[E]['res']> {
const promise = new Promise<Endpoints[E]['res']>((resolve, reject) => {
// Append a credential
if (credential !== undefined) (data as Record<string, any>).i = credential;
// Send request
fetch(`${origin}/api/${endpoint}`, {
method: 'POST',
body: JSON.stringify(data),
credentials: 'omit',
cache: 'no-cache'
}).then(async (res) => {
const body = res.status === 204 ? null : await res.json();
if (res.status === 200) {
resolve(body);
} else if (res.status === 204) {
resolve(null);
} else {
reject({
[MK_API_ERROR]: true,
...body.error
});
}
}).catch(reject);
});
return promise;
}
export class APIClient {
public i: { token: string; } | null = null;
private origin: string;
public origin: string;
public credential: string | null | undefined;
public fetch: (typeof fetch);
constructor(opts: {
origin: APIClient['origin'];
credential?: APIClient['credential'];
fetch?: APIClient['fetch'] | null | undefined;
}) {
this.origin = opts.origin;
this.credential = opts.credential;
this.fetch = opts.fetch || fetch;
}
public request<E extends keyof Endpoints>(
endpoint: E, data: Endpoints[E]['req'] = {}, credential?: string | null | undefined,
): Promise<Endpoints[E]['res']> {
return request(this.origin, endpoint, data, credential === undefined ? this.i?.token : credential);
const promise = new Promise<Endpoints[E]['res']>((resolve, reject) => {
// Append a credential
if (this.credential) (data as Record<string, any>).i = this.credential;
if (credential) (data as Record<string, any>).i = credential;
// Send request
this.fetch(`${this.origin}/api/${endpoint}`, {
method: 'POST',
body: JSON.stringify(data),
credentials: 'omit',
cache: 'no-cache'
}).then(async (res) => {
const body = res.status === 204 ? null : await res.json();
if (res.status === 200) {
resolve(body);
} else if (res.status === 204) {
resolve(null);
} else {
reject({
[MK_API_ERROR]: true,
...body.error
});
}
}).catch(reject);
});
return promise;
}
}
import { request } from '../src/api';
import { APIClient } from '../src/api';
import { enableFetchMocks } from 'jest-fetch-mock';
enableFetchMocks();
......@@ -21,16 +21,22 @@ describe('API', () => {
fetchMock.mockResponse(async (req) => {
const body = await req.json();
if (req.method == 'POST' && req.url == 'https://misskey.test/api/i') {
if (typeof body.i != 'string') {
if (body.i === 'TOKEN') {
return JSON.stringify({ id: 'foo' });
} else {
return { status: 400 };
}
return JSON.stringify({ id: 'foo' });
} else {
return { status: 404 };
}
});
const res = await request('https://misskey.test', 'i', {}, 'TOKEN');
const cli = new APIClient({
origin: 'https://misskey.test',
credential: 'TOKEN',
});
const res = await cli.request('i');
// validate response
expect(res).toEqual({
......@@ -60,11 +66,18 @@ describe('API', () => {
});
try {
await request('https://misskey.test', 'i', {}, 'TOKEN');
const cli = new APIClient({
origin: 'https://misskey.test',
credential: 'TOKEN',
});
await cli.request('i');
} catch (e) {
expect(e.id).toEqual('5d37dbcb-891e-41ca-a3d6-e690c97775ac');
}
});
// TODO: ネットワークエラーのテスト
// TODO: JSON以外が返ってきた場合のハンドリング
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment