From f30fec0ded32900e1b56a8dfd5872a3a769f3c3b Mon Sep 17 00:00:00 2001 From: mkljczk Date: Sun, 22 Dec 2024 20:20:12 +0100 Subject: [PATCH] pl-api: support kmyblue circles Signed-off-by: mkljczk --- packages/pl-api/lib/client.ts | 65 ++++++++++++++++++- packages/pl-api/lib/entities/circle.ts | 16 +++++ packages/pl-api/lib/features.ts | 2 + .../lib/params/{antenna.ts => antennas.ts} | 0 packages/pl-api/lib/params/circles.ts | 10 +++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 packages/pl-api/lib/entities/circle.ts rename packages/pl-api/lib/params/{antenna.ts => antennas.ts} (100%) create mode 100644 packages/pl-api/lib/params/circles.ts diff --git a/packages/pl-api/lib/client.ts b/packages/pl-api/lib/client.ts index 408b5d805..1430f7ef9 100644 --- a/packages/pl-api/lib/client.ts +++ b/packages/pl-api/lib/client.ts @@ -75,6 +75,7 @@ import { trendsLinkSchema, webPushSubscriptionSchema, } from './entities'; +import { circleSchema } from './entities/circle'; import { type GroupedNotificationsResults, groupedNotificationsResultsSchema, type NotificationGroup } from './entities/grouped-notifications-results'; import { filteredArray } from './entities/utils'; import { AKKOMA, type Features, getFeatures, GOTOSOCIAL, MITRA } from './features'; @@ -138,13 +139,14 @@ import type { AdminUpdateRuleParams, AdminUpdateStatusParams, } from './params/admin'; -import type { CreateAntennaParams, UpdateAntennaParams } from './params/antenna'; +import type { CreateAntennaParams, UpdateAntennaParams } from './params/antennas'; import type { CreateApplicationParams } from './params/apps'; import type { CreateChatMessageParams, GetChatMessagesParams, GetChatsParams, } from './params/chats'; +import type { GetCircleStatusesParams } from './params/circles'; import type { CreateEventParams, EditEventParams, @@ -622,6 +624,17 @@ class PlApiClient { * Requires features{@link Features['antennas']}. */ getAccountExcludeAntennas: async (accountId: string) => { + const response = await this.request(`/api/v1/accounts/${accountId}/circles`); + + return v.parse(filteredArray(circleSchema), response.json); + }, + + /** + * Get circles including this account + * User circles that you have added this account to. + * Requires features{@link Features['circles']}. + */ + getAccountCircles: async (accountId: string) => { const response = await this.request(`/api/v1/accounts/${accountId}/exclude_antennas`); return v.parse(filteredArray(antennaSchema), response.json); @@ -4815,6 +4828,56 @@ class PlApiClient { }, }; + public readonly circles = { + /** + * Requires features{@link Features['circles']}. + */ + fetchCircles: async () => { + const response = await this.request('/api/v1/circles'); + + return v.parse(filteredArray(circleSchema), response.json); + }, + + /** + * Requires features{@link Features['circles']}. + */ + getCircles: async (circleId: string) => { + const response = await this.request(`/api/v1/circles/${circleId}`); + + return v.parse(circleSchema, response.json); + }, + + /** + * Requires features{@link Features['circles']}. + */ + createCircle: async (title: string) => { + const response = await this.request('/api/v1/circles', { method: 'POST', body: { title } }); + + return v.parse(circleSchema, response.json); + }, + + /** + * Requires features{@link Features['circles']}. + */ + updateCircle: async (circleId: string, title: string) => { + const response = await this.request(`/api/v1/circles/${circleId}`, { method: 'PUT', body: { title } }); + + return v.parse(circleSchema, response.json); + }, + + /** + * Requires features{@link Features['circles']}. + */ + deleteCircle: async (circleId: string) => { + const response = await this.request<{}>(`/api/v1/circles/${circleId}`, { method: 'DELETE' }); + + return response.json; + }, + + getCircleStatuses: (circleId: string, params: GetCircleStatusesParams) => + this.#paginatedGet(`/api/v1/circles/${circleId}/statuses`, { params }, statusSchema), + }; + /** Routes that are not part of any stable release */ public readonly experimental = { admin: { diff --git a/packages/pl-api/lib/entities/circle.ts b/packages/pl-api/lib/entities/circle.ts new file mode 100644 index 000000000..958e33de1 --- /dev/null +++ b/packages/pl-api/lib/entities/circle.ts @@ -0,0 +1,16 @@ +import * as v from 'valibot'; + +/** + * @category Schemas + */ +const circleSchema = v.object({ + id: v.string(), + title: v.string(), +}); + +/** + * @category Entity types + */ +type Circle = v.InferOutput; + +export { circleSchema, type Circle }; diff --git a/packages/pl-api/lib/features.ts b/packages/pl-api/lib/features.ts index 71b19d73a..cac2e3431 100644 --- a/packages/pl-api/lib/features.ts +++ b/packages/pl-api/lib/features.ts @@ -356,6 +356,8 @@ const getFeatures = (instance: Instance) => { v.software === PLEROMA && v.build === PL, ]), + circles: instance.api_versions['kmyblue_circle_history.fedibird.pl-api'] >= 1, + /** * Mastodon's newer solution for direct messaging. * @see {@link https://docs.joinmastodon.org/methods/conversations/} diff --git a/packages/pl-api/lib/params/antenna.ts b/packages/pl-api/lib/params/antennas.ts similarity index 100% rename from packages/pl-api/lib/params/antenna.ts rename to packages/pl-api/lib/params/antennas.ts diff --git a/packages/pl-api/lib/params/circles.ts b/packages/pl-api/lib/params/circles.ts new file mode 100644 index 000000000..7ec4020a7 --- /dev/null +++ b/packages/pl-api/lib/params/circles.ts @@ -0,0 +1,10 @@ +import { PaginationParams } from './common'; + +/** + * @category Request params + */ +type GetCircleStatusesParams = PaginationParams; + +export type { + GetCircleStatusesParams, +};