pl-api: works on docs
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
14d75be0de
commit
ee0232e2e6
18 changed files with 119 additions and 11 deletions
|
@ -4,6 +4,25 @@ A JavaScript library for interacting with Mastodon API-compatible servers, focus
|
||||||
|
|
||||||
`pl-api` attempts to abstract out the implementation details when supporting different backends, implementing the same features in different ways. It uses [Valibot](https://valibot.dev/) to ensure type safety and normalize API responses.
|
`pl-api` attempts to abstract out the implementation details when supporting different backends, implementing the same features in different ways. It uses [Valibot](https://valibot.dev/) to ensure type safety and normalize API responses.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```ts
|
||||||
|
import { PlApiClient, type CreateApplicationParams } from 'pl-api';
|
||||||
|
|
||||||
|
const { ACCESS_TOKEN } = process.env;
|
||||||
|
|
||||||
|
const client = new PlApiClient('https://mastodon.example/', ACCESS_TOKEN, {
|
||||||
|
fetchInstance: true,
|
||||||
|
onInstanceFetchSuccess: () => console.log('Instance fetched'),
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.statuses.createStatus({
|
||||||
|
status: 'Hello, world!',
|
||||||
|
language: 'en',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Some sort of documentation is available on https://pl.mkljczk.pl/pl-api-docs
|
||||||
|
|
||||||
> This project should be considered unstable before the 1.0.0 release. I will not provide any changelog or information on breaking changes until then.
|
> This project should be considered unstable before the 1.0.0 release. I will not provide any changelog or information on breaking changes until then.
|
||||||
|
|
||||||
## Projects using `pl-api`
|
## Projects using `pl-api`
|
||||||
|
|
|
@ -230,6 +230,9 @@ import type {
|
||||||
} from './params/admin';
|
} from './params/admin';
|
||||||
import type { PaginatedResponse } from './responses';
|
import type { PaginatedResponse } from './responses';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Clients
|
||||||
|
*/
|
||||||
class PlApiClient {
|
class PlApiClient {
|
||||||
|
|
||||||
baseURL: string;
|
baseURL: string;
|
||||||
|
|
|
@ -15,6 +15,9 @@ interface Params {
|
||||||
registrations?: 'instant' | 'manual';
|
registrations?: 'instant' | 'manual';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Clients
|
||||||
|
*/
|
||||||
class PlApiDirectoryClient {
|
class PlApiDirectoryClient {
|
||||||
|
|
||||||
accessToken = undefined;
|
accessToken = undefined;
|
||||||
|
|
|
@ -9,7 +9,10 @@ const appealSchema = v.object({
|
||||||
state: v.picklist(['approved', 'rejected', 'pending']),
|
state: v.picklist(['approved', 'rejected', 'pending']),
|
||||||
});
|
});
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/AccountWarning/} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/AccountWarning/}
|
||||||
|
*/
|
||||||
const accountWarningSchema = v.object({
|
const accountWarningSchema = v.object({
|
||||||
id: v.string(),
|
id: v.string(),
|
||||||
action: v.picklist(['none', 'disable', 'mark_statuses_as_sensitive', 'delete_statuses', 'sensitive', 'silence', 'suspend']),
|
action: v.picklist(['none', 'disable', 'mark_statuses_as_sensitive', 'delete_statuses', 'sensitive', 'silence', 'suspend']),
|
||||||
|
|
|
@ -166,6 +166,9 @@ type WithMoved = {
|
||||||
|
|
||||||
type Account = v.InferOutput<typeof accountWithMovedAccountSchema> & WithMoved;
|
type Account = v.InferOutput<typeof accountWithMovedAccountSchema> & WithMoved;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
*/
|
||||||
const accountSchema: v.BaseSchema<any, Account, v.BaseIssue<unknown>> = untypedAccountSchema as any;
|
const accountSchema: v.BaseSchema<any, Account, v.BaseIssue<unknown>> = untypedAccountSchema as any;
|
||||||
|
|
||||||
const untypedCredentialAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
|
const untypedCredentialAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
|
||||||
|
@ -199,6 +202,9 @@ const untypedCredentialAccountSchema = v.pipe(v.any(), preprocessAccount, v.obje
|
||||||
|
|
||||||
type CredentialAccount = v.InferOutput<typeof untypedCredentialAccountSchema> & WithMoved;
|
type CredentialAccount = v.InferOutput<typeof untypedCredentialAccountSchema> & WithMoved;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
*/
|
||||||
const credentialAccountSchema: v.BaseSchema<any, CredentialAccount, v.BaseIssue<unknown>> = untypedCredentialAccountSchema as any;
|
const credentialAccountSchema: v.BaseSchema<any, CredentialAccount, v.BaseIssue<unknown>> = untypedCredentialAccountSchema as any;
|
||||||
|
|
||||||
const untypedMutedAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
|
const untypedMutedAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
|
||||||
|
@ -208,6 +214,9 @@ const untypedMutedAccountSchema = v.pipe(v.any(), preprocessAccount, v.object({
|
||||||
|
|
||||||
type MutedAccount = v.InferOutput<typeof untypedMutedAccountSchema> & WithMoved;
|
type MutedAccount = v.InferOutput<typeof untypedMutedAccountSchema> & WithMoved;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
*/
|
||||||
const mutedAccountSchema: v.BaseSchema<any, MutedAccount, v.BaseIssue<unknown>> = untypedMutedAccountSchema as any;
|
const mutedAccountSchema: v.BaseSchema<any, MutedAccount, v.BaseIssue<unknown>> = untypedMutedAccountSchema as any;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/announcement/} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/announcement/}
|
||||||
|
*/
|
||||||
const announcementReactionSchema = v.object({
|
const announcementReactionSchema = v.object({
|
||||||
name: v.fallback(v.string(), ''),
|
name: v.fallback(v.string(), ''),
|
||||||
count: v.fallback(v.pipe(v.number(), v.integer(), v.minValue(0)), 0),
|
count: v.fallback(v.pipe(v.number(), v.integer(), v.minValue(0)), 0),
|
||||||
|
|
|
@ -6,7 +6,10 @@ import { mentionSchema } from './mention';
|
||||||
import { tagSchema } from './tag';
|
import { tagSchema } from './tag';
|
||||||
import { datetimeSchema, filteredArray } from './utils';
|
import { datetimeSchema, filteredArray } from './utils';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/announcement/} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/announcement/}
|
||||||
|
*/
|
||||||
const announcementSchema = v.object({
|
const announcementSchema = v.object({
|
||||||
id: v.string(),
|
id: v.string(),
|
||||||
content: v.fallback(v.string(), ''),
|
content: v.fallback(v.string(), ''),
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/Application/} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/Application/}
|
||||||
|
*/
|
||||||
const applicationSchema = v.object({
|
const applicationSchema = v.object({
|
||||||
name: v.fallback(v.string(), ''),
|
name: v.fallback(v.string(), ''),
|
||||||
website: v.fallback(v.optional(v.string()), undefined),
|
website: v.fallback(v.optional(v.string()), undefined),
|
||||||
|
|
|
@ -2,7 +2,10 @@ import * as v from 'valibot';
|
||||||
|
|
||||||
import { datetimeSchema, mimeSchema } from './utils';
|
import { datetimeSchema, mimeSchema } from './utils';
|
||||||
|
|
||||||
/** @see {@link https://docs.pleroma.social/backend/development/API/pleroma_api/#post-apiv1pleromabackups} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.pleroma.social/backend/development/API/pleroma_api/#post-apiv1pleromabackups}
|
||||||
|
*/
|
||||||
const backupSchema = v.object({
|
const backupSchema = v.object({
|
||||||
id: v.pipe(v.unknown(), v.transform(String)),
|
id: v.pipe(v.unknown(), v.transform(String)),
|
||||||
contentType: mimeSchema,
|
contentType: mimeSchema,
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
*/
|
||||||
const bookmarkFolderSchema = v.object({
|
const bookmarkFolderSchema = v.object({
|
||||||
id: v.pipe(v.unknown(), v.transform(String)),
|
id: v.pipe(v.unknown(), v.transform(String)),
|
||||||
name: v.fallback(v.string(), ''),
|
name: v.fallback(v.string(), ''),
|
||||||
|
|
|
@ -5,7 +5,10 @@ import { mediaAttachmentSchema } from './media-attachment';
|
||||||
import { previewCardSchema } from './preview-card';
|
import { previewCardSchema } from './preview-card';
|
||||||
import { datetimeSchema, filteredArray } from './utils';
|
import { datetimeSchema, filteredArray } from './utils';
|
||||||
|
|
||||||
/** @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-the-messages-for-a-chat} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-the-messages-for-a-chat}
|
||||||
|
*/
|
||||||
const chatMessageSchema = v.object({
|
const chatMessageSchema = v.object({
|
||||||
id: v.string(),
|
id: v.string(),
|
||||||
content: v.fallback(v.string(), ''),
|
content: v.fallback(v.string(), ''),
|
||||||
|
|
|
@ -4,7 +4,10 @@ import { accountSchema } from './account';
|
||||||
import { chatMessageSchema } from './chat-message';
|
import { chatMessageSchema } from './chat-message';
|
||||||
import { datetimeSchema } from './utils';
|
import { datetimeSchema } from './utils';
|
||||||
|
|
||||||
/** @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-a-list-of-chats} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.pleroma.social/backend/development/API/chats/#getting-a-list-of-chats}
|
||||||
|
*/
|
||||||
const chatSchema = v.object({
|
const chatSchema = v.object({
|
||||||
id: v.string(),
|
id: v.string(),
|
||||||
account: accountSchema,
|
account: accountSchema,
|
||||||
|
|
|
@ -2,7 +2,10 @@ import * as v from 'valibot';
|
||||||
|
|
||||||
import { statusSchema } from './status';
|
import { statusSchema } from './status';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/Context/} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/Context/}
|
||||||
|
*/
|
||||||
const contextSchema = v.object({
|
const contextSchema = v.object({
|
||||||
ancestors: v.array(statusSchema),
|
ancestors: v.array(statusSchema),
|
||||||
descendants: v.array(statusSchema),
|
descendants: v.array(statusSchema),
|
||||||
|
|
|
@ -4,7 +4,10 @@ import { accountSchema } from './account';
|
||||||
import { statusSchema } from './status';
|
import { statusSchema } from './status';
|
||||||
import { filteredArray } from './utils';
|
import { filteredArray } from './utils';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/Conversation} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/Conversation}
|
||||||
|
*/
|
||||||
const conversationSchema = v.object({
|
const conversationSchema = v.object({
|
||||||
id: v.string(),
|
id: v.string(),
|
||||||
unread: v.fallback(v.boolean(), false),
|
unread: v.fallback(v.boolean(), false),
|
||||||
|
|
|
@ -2,6 +2,8 @@ import * as v from 'valibot';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a custom emoji.
|
* Represents a custom emoji.
|
||||||
|
*
|
||||||
|
* @category Schemas
|
||||||
* @see {@link https://docs.joinmastodon.org/entities/CustomEmoji/}
|
* @see {@link https://docs.joinmastodon.org/entities/CustomEmoji/}
|
||||||
*/
|
*/
|
||||||
const customEmojiSchema = v.object({
|
const customEmojiSchema = v.object({
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
/** @see {@link https://docs.joinmastodon.org/entities/DomainBlock} */
|
/**
|
||||||
|
* @category Schemas
|
||||||
|
* @see {@link https://docs.joinmastodon.org/entities/DomainBlock}
|
||||||
|
*/
|
||||||
const domainBlockSchema = v.object({
|
const domainBlockSchema = v.object({
|
||||||
domain: v.string(),
|
domain: v.string(),
|
||||||
digest: v.string(),
|
digest: v.string(),
|
||||||
|
|
|
@ -9,101 +9,137 @@ const any = (arr: Array<any>): boolean => arr.some(Boolean);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ditto, a Nostr server with Mastodon API.
|
* Ditto, a Nostr server with Mastodon API.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://gitlab.com/soapbox-pub/ditto}
|
* @see {@link https://gitlab.com/soapbox-pub/ditto}
|
||||||
*/
|
*/
|
||||||
const DITTO = 'Ditto';
|
const DITTO = 'Ditto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Firefish, a fork of Misskey. Formerly known as Calckey.
|
* Firefish, a fork of Misskey. Formerly known as Calckey.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://joinfirefish.org/}
|
* @see {@link https://joinfirefish.org/}
|
||||||
*/
|
*/
|
||||||
const FIREFISH = 'Firefish';
|
const FIREFISH = 'Firefish';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Friendica, decentralized social platform implementing multiple federation protocols.
|
* Friendica, decentralized social platform implementing multiple federation protocols.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://friendi.ca/}
|
* @see {@link https://friendi.ca/}
|
||||||
*/
|
*/
|
||||||
const FRIENDICA = 'Friendica';
|
const FRIENDICA = 'Friendica';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GoToSocial, an ActivityPub server written in Golang.
|
* GoToSocial, an ActivityPub server written in Golang.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://gotosocial.org/}
|
* @see {@link https://gotosocial.org/}
|
||||||
*/
|
*/
|
||||||
const GOTOSOCIAL = 'GoToSocial';
|
const GOTOSOCIAL = 'GoToSocial';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iceshrimp, yet another Misskey fork.
|
* Iceshrimp, yet another Misskey fork.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://iceshrimp.dev/}
|
* @see {@link https://iceshrimp.dev/}
|
||||||
*/
|
*/
|
||||||
const ICESHRIMP = 'Iceshrimp';
|
const ICESHRIMP = 'Iceshrimp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mastodon, the software upon which this is all based.
|
* Mastodon, the software upon which this is all based.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://joinmastodon.org/}
|
* @see {@link https://joinmastodon.org/}
|
||||||
*/
|
*/
|
||||||
const MASTODON = 'Mastodon';
|
const MASTODON = 'Mastodon';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mitra, a Rust backend with cryptocurrency integrations.
|
* Mitra, a Rust backend with cryptocurrency integrations.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://codeberg.org/silverpill/mitra}
|
* @see {@link https://codeberg.org/silverpill/mitra}
|
||||||
*/
|
*/
|
||||||
const MITRA = 'Mitra';
|
const MITRA = 'Mitra';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pixelfed, a federated image sharing platform.
|
* Pixelfed, a federated image sharing platform.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://pixelfed.org/}
|
* @see {@link https://pixelfed.org/}
|
||||||
*/
|
*/
|
||||||
const PIXELFED = 'Pixelfed';
|
const PIXELFED = 'Pixelfed';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pleroma, a feature-rich alternative written in Elixir.
|
* Pleroma, a feature-rich alternative written in Elixir.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://pleroma.social/}
|
* @see {@link https://pleroma.social/}
|
||||||
*/
|
*/
|
||||||
const PLEROMA = 'Pleroma';
|
const PLEROMA = 'Pleroma';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takahē, backend with support for serving multiple domains.
|
* Takahē, backend with support for serving multiple domains.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://jointakahe.org/}
|
* @see {@link https://jointakahe.org/}
|
||||||
*/
|
*/
|
||||||
const TAKAHE = 'Takahe';
|
const TAKAHE = 'Takahe';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toki, a C# Fediverse server.
|
* Toki, a C# Fediverse server.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://github.com/purifetchi/Toki}
|
* @see {@link https://github.com/purifetchi/Toki}
|
||||||
*/
|
*/
|
||||||
const TOKI = 'Toki';
|
const TOKI = 'Toki';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Akkoma, a Pleroma fork.
|
* Akkoma, a Pleroma fork.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://akkoma.dev/AkkomaGang/akkoma}
|
* @see {@link https://akkoma.dev/AkkomaGang/akkoma}
|
||||||
*/
|
*/
|
||||||
const AKKOMA = 'akkoma';
|
const AKKOMA = 'akkoma';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glitch-soc, fork of Mastodon with a number of experimental features.
|
* glitch-soc, fork of Mastodon with a number of experimental features.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://glitch-soc.github.io/docs/}
|
* @see {@link https://glitch-soc.github.io/docs/}
|
||||||
*/
|
*/
|
||||||
const GLITCH = 'glitch';
|
const GLITCH = 'glitch';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glitch-soc, fork of Mastodon that provides local posting and a wider range of content types.
|
* glitch-soc, fork of Mastodon that provides local posting and a wider range of content types.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://github.com/hometown-fork/hometown}
|
* @see {@link https://github.com/hometown-fork/hometown}
|
||||||
*/
|
*/
|
||||||
const HOMETOWN = 'hometown';
|
const HOMETOWN = 'hometown';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pl, fork of Pleroma developed by pl-api author.
|
* Pl, fork of Pleroma developed by pl-api author.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://github.com/mkljczk/pl}
|
* @see {@link https://github.com/mkljczk/pl}
|
||||||
*/
|
*/
|
||||||
const PL = 'pl';
|
const PL = 'pl';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebased, fork of Pleroma developed by Soapbox author.
|
* Rebased, fork of Pleroma developed by Soapbox author.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
* @see {@link https://gitlab.com/soapbox-pub/rebased}
|
* @see {@link https://gitlab.com/soapbox-pub/rebased}
|
||||||
*/
|
*/
|
||||||
const REBASED = 'soapbox';
|
const REBASED = 'soapbox';
|
||||||
|
|
||||||
/** Backend name reserved only for tests. */
|
/**
|
||||||
|
* Backend name reserved only for tests.
|
||||||
|
*
|
||||||
|
* @category Software
|
||||||
|
*/
|
||||||
const UNRELEASED = 'unreleased';
|
const UNRELEASED = 'unreleased';
|
||||||
|
|
||||||
/** Parse features for the given instance */
|
/** Parse features for the given instance */
|
||||||
|
|
|
@ -4,6 +4,9 @@ const config = {
|
||||||
entryPoints: ['./lib/main.ts'],
|
entryPoints: ['./lib/main.ts'],
|
||||||
plugin: ['typedoc-material-theme', 'typedoc-plugin-valibot'],
|
plugin: ['typedoc-material-theme', 'typedoc-plugin-valibot'],
|
||||||
themeColor: '#d80482',
|
themeColor: '#d80482',
|
||||||
|
navigation: {
|
||||||
|
includeCategories: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
Loading…
Reference in a new issue