mirror of
https://github.com/stoatchat/javascript-client-api.git
synced 2026-08-26 12:35:48 -04:00
Add channel routes.
This commit is contained in:
+5732
-49
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ export function tag(name: string, description: string) {
|
||||
|
||||
export function resource(path: string, methods: OpenAPIV3.PathItemObject) {
|
||||
console.info(`Generating resource ${path}.`);
|
||||
if (resources[path]) throw `Resource ${path} already exists!`;
|
||||
resources[path] = methods;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,487 @@
|
||||
import { body, parameter, ref, success } from "../openapi/generators.js";
|
||||
import { group, resource, routeAuthenticated, tag } from "../openapi/paths.js";
|
||||
import { schema } from "../typescript.js";
|
||||
|
||||
group("Channels");
|
||||
|
||||
//#region Channel Information
|
||||
tag("Channel Information", "Query and fetch channels on Revolt");
|
||||
|
||||
const channelParams = {
|
||||
parameters: [
|
||||
await parameter('channel', 'Channel ID', ref("Id"))
|
||||
]
|
||||
}
|
||||
|
||||
resource('/channels/:channel', {
|
||||
get: routeAuthenticated(
|
||||
"Fetch Channel",
|
||||
"Retrieve a channel.",
|
||||
{
|
||||
...channelParams,
|
||||
...await success(
|
||||
"Retrieved channel.",
|
||||
ref("Channel")
|
||||
)
|
||||
}
|
||||
),
|
||||
patch: routeAuthenticated(
|
||||
"Edit Channel",
|
||||
"Edit a channel object.",
|
||||
{
|
||||
...channelParams,
|
||||
...await body("Requested changes to channel object.", schema`
|
||||
import type { Status } from './Users';
|
||||
import type { AutumnId } from './_common';
|
||||
|
||||
interface ${'EditChannels'} {
|
||||
/**
|
||||
* Channel name
|
||||
**/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Channel description
|
||||
**/
|
||||
description?: string;
|
||||
|
||||
icon?: AutumnId;
|
||||
|
||||
/**
|
||||
* Field to remove from channel object
|
||||
*/
|
||||
remove?: 'Icon' | 'Description';
|
||||
}
|
||||
`),
|
||||
...await success("Succesfully changed channel object.")
|
||||
}
|
||||
),
|
||||
delete: routeAuthenticated(
|
||||
"Close Channel",
|
||||
"Deletes a server channel, leaves a group or closes a DM.",
|
||||
await success("Deleted Channel")
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Channel Invites
|
||||
tag("Channel Invites", "Create and manage invites for channels");
|
||||
|
||||
resource('/channels/:channel/invites', {
|
||||
post: routeAuthenticated(
|
||||
"Create Invite",
|
||||
"Creates an invite to this channel.\n\nChannel must be a `TextChannel`.",
|
||||
{
|
||||
...channelParams,
|
||||
...await success("Invite", schema`
|
||||
interface ${'InviteCode'} {
|
||||
/**
|
||||
* Invite Code
|
||||
*/
|
||||
code: string;
|
||||
}
|
||||
`)
|
||||
}
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Channel Permissions
|
||||
tag("Channel Permissions", "Manage permissions for channels");
|
||||
|
||||
const roleParams = {
|
||||
parameters: [
|
||||
await parameter('channel', 'Channel ID', ref("Id")),
|
||||
await parameter('role', 'Role ID', ref("Id"))
|
||||
]
|
||||
}
|
||||
|
||||
const channelPermissions = await body("Channel Permissions", schema`
|
||||
interface ${'ChannelPermissions'} {
|
||||
permissions: number
|
||||
}
|
||||
`)
|
||||
|
||||
resource('/channels/:channel/permissions/:role', {
|
||||
put: routeAuthenticated(
|
||||
"Set Role Permission",
|
||||
"Sets permissions for the specified role in this channel.\n\nChannel must be a `TextChannel` or `VoiceChannel`.",
|
||||
{
|
||||
...roleParams,
|
||||
...channelPermissions,
|
||||
...await success("Successfully updated permissions.")
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/permissions/default', {
|
||||
put: routeAuthenticated(
|
||||
"Set Default Permission",
|
||||
"Sets permissions for the default role in this channel.\n\nChannel must be a `Group`, `TextChannel` or `VoiceChannel`.",
|
||||
{
|
||||
...channelParams,
|
||||
...channelPermissions,
|
||||
...await success("Successfully updated permissions.")
|
||||
}
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Messaging
|
||||
tag("Messaging", "Send and manipulate messages");
|
||||
|
||||
const messageParams = {
|
||||
parameters: [
|
||||
await parameter('channel', 'Channel ID', ref("Id")),
|
||||
await parameter('message', 'Message ID', ref("Id"))
|
||||
]
|
||||
}
|
||||
|
||||
const retrievedMessages = await success("Message array or object with requested data.", schema`
|
||||
import { Message } from './Channels';
|
||||
import { User } from './Users';
|
||||
import { Member } from './Servers';
|
||||
|
||||
type ${'RetrievedMessages'} = Message[] | {
|
||||
messages: Message[],
|
||||
users: User[],
|
||||
members?: Member[]
|
||||
}
|
||||
`);
|
||||
|
||||
resource('/channels/:channel/messages', {
|
||||
post: routeAuthenticated(
|
||||
"Send Message",
|
||||
"Sends a message to the given channel.",
|
||||
{
|
||||
...channelParams,
|
||||
...await body("Message to be sent.", schema`
|
||||
import type { Id, Nonce, AutumnId } from './_common';
|
||||
|
||||
interface ${'SendMessage'} {
|
||||
/**
|
||||
* Message content to send.
|
||||
* @minLength 0
|
||||
* @maxLength 2000
|
||||
*/
|
||||
content: string;
|
||||
|
||||
nonce: Nonce;
|
||||
|
||||
/**
|
||||
* Attachments to include in message.
|
||||
*/
|
||||
attachments?: AutumnId[];
|
||||
|
||||
/**
|
||||
* Messages to reply to.
|
||||
*/
|
||||
replies?: {
|
||||
/**
|
||||
* Message Id
|
||||
*/
|
||||
id: Id;
|
||||
|
||||
/**
|
||||
* Whether this reply should mention the message's author.
|
||||
*/
|
||||
mention: boolean;
|
||||
}
|
||||
}
|
||||
`),
|
||||
...await success(
|
||||
"Sent message.",
|
||||
ref("Message")
|
||||
)
|
||||
}
|
||||
),
|
||||
get: routeAuthenticated(
|
||||
"Fetch Messages",
|
||||
"Fetches multiple messages.",
|
||||
{
|
||||
...channelParams,
|
||||
...await body("Fetch Options", schema`
|
||||
import { Id } from './_common';
|
||||
|
||||
interface ${'FetchOptions'} {
|
||||
/**
|
||||
* Maximum number of messages to fetch.
|
||||
*
|
||||
* For fetching nearby messages, this is \`(limit + 1)\`.
|
||||
*
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
limit?: number;
|
||||
|
||||
/**
|
||||
* Message id before which messages should be fetched.
|
||||
*/
|
||||
before?: Id;
|
||||
|
||||
/**
|
||||
* Message id after which messages should be fetched.
|
||||
*/
|
||||
after?: Id;
|
||||
|
||||
/**
|
||||
* Message sort direction
|
||||
*/
|
||||
sort: 'Latest' | 'Oldest';
|
||||
|
||||
/**
|
||||
* Message id to fetch around, this will ignore 'before', 'after' and 'sort' options.
|
||||
* Limits in each direction will be half of the specified limit.
|
||||
* It also fetches the specified message ID.
|
||||
*/
|
||||
nearby?: Id;
|
||||
|
||||
/**
|
||||
* Whether to include user (and member, if server channel) objects.
|
||||
*/
|
||||
include_users?: boolean;
|
||||
}
|
||||
`),
|
||||
...retrievedMessages
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/messages/:message', {
|
||||
get: routeAuthenticated(
|
||||
"Fetch Message",
|
||||
"Retrieves a message by ID.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success(
|
||||
"Message",
|
||||
ref("Message")
|
||||
)
|
||||
}
|
||||
),
|
||||
patch: routeAuthenticated(
|
||||
"Edit Message",
|
||||
"Edits a message that you've previously sent.",
|
||||
{
|
||||
...messageParams,
|
||||
...await body("Message edit data.", schema`
|
||||
interface ${'MessageEdit'} {
|
||||
/**
|
||||
* Message content
|
||||
* @minLength 1
|
||||
* @maxLength 2000
|
||||
*/
|
||||
content: string;
|
||||
}
|
||||
`),
|
||||
...await success("Message was changed.")
|
||||
}
|
||||
),
|
||||
delete: routeAuthenticated(
|
||||
"Delete Message",
|
||||
"Delete a message you've sent or one you have permission to delete.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success("Message was deleted.")
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/messages/stale', {
|
||||
post: routeAuthenticated(
|
||||
"Poll Message Changes",
|
||||
"This route returns any changed message objects and tells you if any have been deleted.\n\nDon't actually poll this route, instead use this to update your local database.",
|
||||
{
|
||||
...channelParams,
|
||||
...await body("Poll Options", schema`
|
||||
import { Id } from './_common';
|
||||
|
||||
interface ${'PollOptions'} {
|
||||
/**
|
||||
* Array of message IDs.
|
||||
*
|
||||
* @maxItems 150
|
||||
*/
|
||||
ids: Id[];
|
||||
}
|
||||
`),
|
||||
...await success("Polled Information", schema`
|
||||
import { Message } from './Channels';
|
||||
|
||||
interface ${'PolledInformation'} {
|
||||
/**
|
||||
* Changed message objects.
|
||||
*/
|
||||
changed: Message[],
|
||||
|
||||
/**
|
||||
* Array of deleted message IDs.
|
||||
*/
|
||||
deleted: string[]
|
||||
}
|
||||
`)
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/messages/search', {
|
||||
post: routeAuthenticated(
|
||||
"Search for Messages",
|
||||
"This route searches for messages within the given parameters.",
|
||||
{
|
||||
...channelParams,
|
||||
...await body("Search Options", schema`
|
||||
import { Id } from './_common';
|
||||
|
||||
interface ${'SearchOptions'} {
|
||||
/**
|
||||
* Full-text search query.
|
||||
*
|
||||
* See [MongoDB documentation](https://docs.mongodb.com/manual/text-search/#-text-operator) for more information.
|
||||
*
|
||||
* @minLength 1
|
||||
* @maxLength 64
|
||||
*/
|
||||
query: string;
|
||||
|
||||
/**
|
||||
* Maximum number of messages to fetch.
|
||||
*
|
||||
* @minimum 1
|
||||
* @maximum 100
|
||||
*/
|
||||
limit?: number;
|
||||
|
||||
/**
|
||||
* Message id before which messages should be fetched.
|
||||
*/
|
||||
before?: Id;
|
||||
|
||||
/**
|
||||
* Message id after which messages should be fetched.
|
||||
*/
|
||||
after?: Id;
|
||||
|
||||
/**
|
||||
* Message sort direction
|
||||
*/
|
||||
sort: 'Relevance' | 'Latest' | 'Oldest';
|
||||
|
||||
/**
|
||||
* Whether to include user (and member, if server channel) objects.
|
||||
*/
|
||||
include_users?: boolean;
|
||||
}
|
||||
`),
|
||||
...retrievedMessages
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/ack/:message', {
|
||||
put: routeAuthenticated(
|
||||
"Acknowledge Message",
|
||||
"Lets the server and all other clients know that we've seen this message id in this channel.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success("Acknowledged message.")
|
||||
}
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Groups
|
||||
tag("Groups", "Create, invite users and manipulate groups");
|
||||
|
||||
resource('/channels/create', {
|
||||
post: routeAuthenticated(
|
||||
"Create Group",
|
||||
"Create a new group with friends.",
|
||||
{
|
||||
...await body("Group Data", schema`
|
||||
import { Id, Nonce } from './_common';
|
||||
|
||||
interface ${'GroupData'} {
|
||||
/**
|
||||
* Group name
|
||||
* @minLength 1
|
||||
* @maxLength 32
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Group description
|
||||
* @minLength 0
|
||||
* @maxLength 1024
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
nonce: Nonce;
|
||||
|
||||
/**
|
||||
* Array of user IDs to add to the group.
|
||||
*
|
||||
* Must be friends with them.
|
||||
*
|
||||
* @maxItems 49
|
||||
*/
|
||||
users?: string[];
|
||||
}
|
||||
`),
|
||||
...await success('Group', ref("GroupChannel"))
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
resource('/channels/:channel/members', {
|
||||
get: routeAuthenticated(
|
||||
"Fetch Group Members",
|
||||
"Retrieves users who are part of this group.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success("Members", schema`
|
||||
import { User } from './Users';
|
||||
type ${'Members'} = User[];
|
||||
`)
|
||||
}
|
||||
),
|
||||
put: routeAuthenticated(
|
||||
"Add Group Member",
|
||||
"Adds another user to the group.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success("User was added to the group.")
|
||||
}
|
||||
),
|
||||
delete: routeAuthenticated(
|
||||
"Remove Group Member",
|
||||
"Removes a user from the group.",
|
||||
{
|
||||
...messageParams,
|
||||
...await success("User was removed from the group.")
|
||||
}
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region Voice
|
||||
tag("Voice", "Join and talk with other users");
|
||||
|
||||
resource('/channels/:channel/join_call', {
|
||||
post: routeAuthenticated(
|
||||
"Join Call",
|
||||
"Asks the voice server for a token to join the call.",
|
||||
{
|
||||
...channelParams,
|
||||
...await success("Join Data", schema`
|
||||
interface ${'JoinData'} {
|
||||
/**
|
||||
* Voso Token
|
||||
*/
|
||||
token: string;
|
||||
}
|
||||
`)
|
||||
}
|
||||
)
|
||||
});
|
||||
//#endregion
|
||||
@@ -1,6 +1,7 @@
|
||||
export async function load() {
|
||||
await import('./core.js');
|
||||
await import('./users.js');
|
||||
await import('./channels.js');
|
||||
}
|
||||
|
||||
await load();
|
||||
|
||||
+29
-37
@@ -7,14 +7,18 @@ group("Users");
|
||||
//#region User Information
|
||||
tag("User Information", "Query and fetch users on Revolt");
|
||||
|
||||
const userParams = {
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref("Id"))
|
||||
]
|
||||
}
|
||||
|
||||
resource('/users/:user', {
|
||||
get: routeAuthenticated(
|
||||
"Fetch User",
|
||||
"Retrieve a user's information.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref("Id"))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"User information.",
|
||||
ref("User")
|
||||
@@ -33,27 +37,27 @@ resource('/users/@me', {
|
||||
import type { AutumnId } from './_common';
|
||||
|
||||
interface ${'EditUser'} {
|
||||
status: Status;
|
||||
status?: Status;
|
||||
|
||||
/**
|
||||
* User profile data
|
||||
**/
|
||||
profile: {
|
||||
profile?: {
|
||||
/**
|
||||
* Text to set as user profile description
|
||||
* @maxLength 2000
|
||||
*/
|
||||
content: string;
|
||||
content?: string;
|
||||
|
||||
background: AutumnId;
|
||||
background?: AutumnId;
|
||||
}
|
||||
|
||||
avatar: AutumnId;
|
||||
avatar?: AutumnId;
|
||||
|
||||
/**
|
||||
* Field to remove from user object
|
||||
*/
|
||||
remove: 'ProfileContent' | 'ProfileBackground' | 'StatusText' | 'Avatar';
|
||||
remove?: 'ProfileContent' | 'ProfileBackground' | 'StatusText' | 'Avatar';
|
||||
}
|
||||
`),
|
||||
...await success("Succesfully changed user object.")
|
||||
@@ -94,9 +98,7 @@ resource('/users/:user/profile', {
|
||||
"Fetch User Profile",
|
||||
"Retrieve a user's profile data.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref("Id"))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"User profile.",
|
||||
ref("Profile")
|
||||
@@ -110,9 +112,7 @@ resource('/users/:user/default_avatar', {
|
||||
"Fetch Default Avatar",
|
||||
"This returns a default avatar based on the given id.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref("Id"))
|
||||
],
|
||||
...userParams,
|
||||
responses: {
|
||||
'200': {
|
||||
description: "Default avatar in PNG format",
|
||||
@@ -135,9 +135,7 @@ resource('/users/:user/mutual', {
|
||||
"Fetch Mutual Friends",
|
||||
"Retrieve a list of mutual friends with another user.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref("Id"))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"Mutual friends.",
|
||||
schema`
|
||||
@@ -179,9 +177,7 @@ resource('/users/:user/dm', {
|
||||
"Open Direct Message",
|
||||
"Open a DM with another user.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"DM channel with user.",
|
||||
ref("DirectMessageChannel")
|
||||
@@ -213,9 +209,7 @@ resource('/users/:user/relationship', {
|
||||
"Fetch Relationship",
|
||||
"Fetch your relationship with another other user.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"Your relationship with the user.",
|
||||
ref("RelationshipOnly")
|
||||
@@ -224,14 +218,18 @@ resource('/users/:user/relationship', {
|
||||
)
|
||||
});
|
||||
|
||||
resource('/users/:user/friend', {
|
||||
const friendParams = {
|
||||
parameters: [
|
||||
await parameter('username', 'Username', ref("Username"))
|
||||
],
|
||||
}
|
||||
|
||||
resource('/users/:username/friend', {
|
||||
put: routeAuthenticated(
|
||||
"Send Friend Request / Accept Request",
|
||||
"Send a friend request to another user or accept another user's friend request.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...friendParams,
|
||||
...await success(
|
||||
"Sent friend request / added user as friend.",
|
||||
ref("RelationshipOnly")
|
||||
@@ -242,9 +240,7 @@ resource('/users/:user/friend', {
|
||||
"Deny Friend Request / Remove Friend",
|
||||
"Denies another user's friend request or removes an existing friend.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...friendParams,
|
||||
...await success(
|
||||
"Deleted friend request / removed user from friends.",
|
||||
ref("RelationshipOnly")
|
||||
@@ -258,9 +254,7 @@ resource('/users/:user/block', {
|
||||
"Block User",
|
||||
"Block another user.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"Blocked user.",
|
||||
ref("RelationshipOnly")
|
||||
@@ -271,9 +265,7 @@ resource('/users/:user/block', {
|
||||
"Unblock User",
|
||||
"Unblock another user.",
|
||||
{
|
||||
parameters: [
|
||||
await parameter('user', 'User ID', ref('Id'))
|
||||
],
|
||||
...userParams,
|
||||
...await success(
|
||||
"Unblocked user.",
|
||||
ref("RelationshipOnly")
|
||||
|
||||
File diff suppressed because one or more lines are too long
+9
-7
@@ -1,6 +1,14 @@
|
||||
import type { Attachment } from './Autumn';
|
||||
import type { Id } from './_common';
|
||||
|
||||
/**
|
||||
* Username
|
||||
* @minLength 2
|
||||
* @maxLength 32
|
||||
* @pattern ^[a-zA-Z0-9_.]+$
|
||||
*/
|
||||
export type Username = string;
|
||||
|
||||
/**
|
||||
* Your relationship with the user
|
||||
*/
|
||||
@@ -64,13 +72,7 @@ export interface User {
|
||||
*/
|
||||
_id: Id
|
||||
|
||||
/**
|
||||
* Username
|
||||
* @minLength 2
|
||||
* @maxLength 32
|
||||
* @pattern ^[a-zA-Z0-9_.]+$
|
||||
*/
|
||||
username: string
|
||||
username: Username
|
||||
|
||||
/**
|
||||
* User avatar
|
||||
|
||||
+6
-2
@@ -1,4 +1,8 @@
|
||||
|
||||
import type { Relationship } from "./Users";
|
||||
type FetchRelationships = Relationship[];
|
||||
interface JoinData {
|
||||
/**
|
||||
* Voso Token
|
||||
*/
|
||||
token: string;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ export type Id = string;
|
||||
|
||||
/**
|
||||
* Nonce value, prefer to use ULIDs here for better feature support.
|
||||
*
|
||||
* Used to prevent double requests to create objects.
|
||||
*
|
||||
* @minLength 1
|
||||
* @maxLength 36
|
||||
*/
|
||||
@@ -13,5 +16,7 @@ export type Nonce = string;
|
||||
|
||||
/**
|
||||
* Autumn file ID, [learn more](https://example.com/TODO).
|
||||
* @minLength 1
|
||||
* @maxLength 128
|
||||
*/
|
||||
export type AutumnId = string;
|
||||
|
||||
Reference in New Issue
Block a user