diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-01 23:33:14 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-01 23:33:14 +0200 |
commit | 1a76c663d285167aa1b8c748f60c04cff5ae0dce (patch) | |
tree | 547efb9dd2ab175530d54e197405fb8a12d6310e /api | |
parent | Merge pull request #302 from sudenoh/master (diff) | |
download | server-1a76c663d285167aa1b8c748f60c04cff5ae0dce.tar.xz |
:sparkles: generate open api schema based on body and db entities
Diffstat (limited to 'api')
-rw-r--r-- | api/assets/openapi.json | 1625 | ||||
-rw-r--r-- | api/assets/openapi.yaml | 136 | ||||
-rw-r--r-- | api/assets/openapi.yml | 526 | ||||
-rw-r--r-- | api/patches/typescript-json-schema+0.50.1.patch | 14 | ||||
-rw-r--r-- | api/scripts/config_generator.js | 93 | ||||
-rw-r--r-- | api/scripts/generate_openapi_schema.ts | 191 | ||||
-rw-r--r-- | api/src/schema/Emoji.ts | 5 | ||||
-rw-r--r-- | api/src/schema/Guild.ts | 2 | ||||
-rw-r--r-- | api/src/schema/Invite.ts | 18 | ||||
-rw-r--r-- | api/src/schema/index.ts | 11 |
10 files changed, 1853 insertions, 768 deletions
diff --git a/api/assets/openapi.json b/api/assets/openapi.json new file mode 100644 index 00000000..60a40c8a --- /dev/null +++ b/api/assets/openapi.json @@ -0,0 +1,1625 @@ +{ + "openapi": "3.0.0", + "servers": [ + { + "url": "https://api.fosscord.com/v{version}", + "description": "Official fosscord instance", + "variables": { "version": { "description": "", "default": "9", "enum": ["8", "9"] } } + } + ], + "info": { + "description": "Fosscord is a free open source selfhostable chat, voice and video discord compatible platform", + "version": "1.0.0", + "title": "Swagger Petstore", + "termsOfService": "", + "contact": { "name": "Fosscord" }, + "license": { "name": "AGPLV3", "url": "https://www.gnu.org/licenses/agpl-3.0.en.html" } + }, + "tags": [], + "paths": { + "/users/{id}": { + "get": { + "summary": "", + "description": "", + "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "user id" }], + "operationId": "", + "responses": { + "200": { + "description": "user found", + "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserPublic" } } } + }, + "401": { + "description": "Unauthorized", + "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } + }, + "429": { + "description": "Rate limit exceeded", + "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }, + "headers": { + "X-RateLimit-Bucket": { + "description": "A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)", + "schema": { "type": "string" } + }, + "X-Rate-Limit-Limit": { + "description": "The number of allowed requests in the current period", + "schema": { "type": "integer" } + }, + "X-Rate-Limit-Remaining": { + "description": "The number of remaining requests in the current period", + "schema": { "type": "integer" } + }, + "X-Rate-Limit-Reset": { + "description": "Date when current period is over in seconds since the Unix epoch", + "schema": { "type": "integer" } + }, + "X-Rate-Limit-Reset-After": { + "description": "Number of seconds when current period will reset (can have decimal)", + "schema": { "type": "number" } + }, + "Retry-After": { + "description": "Same as X-Rate-Limit-Reset-After but an integer", + "schema": { "type": "integer" } + }, + "X-RateLimit-Global": { + "description": "Indicates whether or not all requests from your ip are rate limited", + "schema": { "type": "boolean" } + } + } + } + } + } + } + }, + "externalDocs": { "description": "", "url": "http://docs.fosscord.com/" }, + "components": { + "schemas": { + "Error": { + "type": "object", + "properties": { "code": { "type": "integer" }, "message": { "type": "string" } }, + "required": ["code", "message"] + }, + "RateLimit": { + "type": "object", + "properties": { "retry_after": { "type": "integer" }, "message": { "type": "string" }, "global": { "type": "boolean" } }, + "required": ["code", "message", "globa"] + }, + "User": { + "type": "object", + "properties": { + "username": { "type": "string" }, + "discriminator": { "type": "string" }, + "avatar": { "type": "string" }, + "accent_color": { "type": "integer" }, + "banner": { "type": "string" }, + "phone": { "type": "string" }, + "desktop": { "type": "boolean" }, + "mobile": { "type": "boolean" }, + "premium": { "type": "boolean" }, + "premium_type": { "type": "integer" }, + "bot": { "type": "boolean" }, + "bio": { "type": "string" }, + "system": { "type": "boolean" }, + "nsfw_allowed": { "type": "boolean" }, + "mfa_enabled": { "type": "boolean" }, + "created_at": { "type": "string", "format": "date-time" }, + "verified": { "type": "boolean" }, + "disabled": { "type": "boolean" }, + "deleted": { "type": "boolean" }, + "email": { "type": "string" }, + "flags": { "type": "string" }, + "public_flags": { "type": "string" }, + "relationships": { "type": "array", "items": { "$ref": "#/components/schemas/Relationship" } }, + "connected_accounts": { "type": "array", "items": { "$ref": "#/components/schemas/ConnectedAccount" } }, + "data": { + "type": "object", + "properties": { "valid_tokens_since": { "type": "string", "format": "date-time" }, "hash": { "type": "string" } }, + "additionalProperties": false, + "required": ["valid_tokens_since"] + }, + "fingerprints": { "type": "array", "items": { "type": "string" } }, + "settings": { "$ref": "#/components/schemas/UserSettings" }, + "id": { "type": "string" } + }, + "required": [ + "bio", + "bot", + "connected_accounts", + "created_at", + "data", + "deleted", + "desktop", + "disabled", + "discriminator", + "fingerprints", + "flags", + "id", + "mfa_enabled", + "mobile", + "nsfw_allowed", + "premium", + "premium_type", + "public_flags", + "relationships", + "settings", + "system", + "username", + "verified" + ] + }, + "Relationship": { + "type": "object", + "properties": { + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "nickname": { "type": "string" }, + "type": { "$ref": "#/components/schemas/RelationshipType" }, + "id": { "type": "string" } + }, + "required": ["id", "type", "user", "user_id"] + }, + "RelationshipType": { "enum": [1, 2, 3, 4], "type": "number" }, + "ConnectedAccount": { + "type": "object", + "properties": { + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "access_token": { "type": "string" }, + "friend_sync": { "type": "boolean" }, + "name": { "type": "string" }, + "revoked": { "type": "boolean" }, + "show_activity": { "type": "boolean" }, + "type": { "type": "string" }, + "verifie": { "type": "boolean" }, + "visibility": { "type": "integer" }, + "id": { "type": "string" } + }, + "required": [ + "access_token", + "friend_sync", + "id", + "name", + "revoked", + "show_activity", + "type", + "user", + "user_id", + "verifie", + "visibility" + ] + }, + "UserSettings": { + "type": "object", + "properties": { + "afk_timeout": { "type": "integer" }, + "allow_accessibility_detection": { "type": "boolean" }, + "animate_emoji": { "type": "boolean" }, + "animate_stickers": { "type": "integer" }, + "contact_sync_enabled": { "type": "boolean" }, + "convert_emoticons": { "type": "boolean" }, + "custom_status": { + "type": "object", + "properties": { + "emoji_id": { "type": "string" }, + "emoji_name": { "type": "string" }, + "expires_at": { "type": "integer" }, + "text": { "type": "string" } + }, + "additionalProperties": false + }, + "default_guilds_restricted": { "type": "boolean" }, + "detect_platform_accounts": { "type": "boolean" }, + "developer_mode": { "type": "boolean" }, + "disable_games_tab": { "type": "boolean" }, + "enable_tts_command": { "type": "boolean" }, + "explicit_content_filter": { "type": "integer" }, + "friend_source_flags": { + "type": "object", + "properties": { "all": { "type": "boolean" } }, + "additionalProperties": false, + "required": ["all"] + }, + "gateway_connected": { "type": "boolean" }, + "gif_auto_play": { "type": "boolean" }, + "guild_folders": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { "type": "integer" }, + "guild_ids": { "type": "array", "items": { "type": "string" } }, + "id": { "type": "integer" }, + "name": { "type": "string" } + }, + "additionalProperties": false, + "required": ["color", "guild_ids", "id", "name"] + } + }, + "guild_positions": { "type": "array", "items": { "type": "string" } }, + "inline_attachment_media": { "type": "boolean" }, + "inline_embed_media": { "type": "boolean" }, + "locale": { "type": "string" }, + "message_display_compact": { "type": "boolean" }, + "native_phone_integration_enabled": { "type": "boolean" }, + "render_embeds": { "type": "boolean" }, + "render_reactions": { "type": "boolean" }, + "restricted_guilds": { "type": "array", "items": { "type": "string" } }, + "show_current_game": { "type": "boolean" }, + "status": { "enum": ["dnd", "idle", "offline", "online"], "type": "string" }, + "stream_notifications_enabled": { "type": "boolean" }, + "theme": { "enum": ["dark", "white"], "type": "string" }, + "timezone_offset": { "type": "integer" } + }, + "required": [ + "afk_timeout", + "allow_accessibility_detection", + "animate_emoji", + "animate_stickers", + "contact_sync_enabled", + "convert_emoticons", + "custom_status", + "default_guilds_restricted", + "detect_platform_accounts", + "developer_mode", + "disable_games_tab", + "enable_tts_command", + "explicit_content_filter", + "friend_source_flags", + "gateway_connected", + "gif_auto_play", + "guild_folders", + "guild_positions", + "inline_attachment_media", + "inline_embed_media", + "locale", + "message_display_compact", + "native_phone_integration_enabled", + "render_embeds", + "render_reactions", + "restricted_guilds", + "show_current_game", + "status", + "stream_notifications_enabled", + "theme", + "timezone_offset" + ] + }, + "Team": { + "type": "object", + "properties": { + "icon": { "type": "string" }, + "members": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMember" } }, + "name": { "type": "string" }, + "owner_user_id": { "type": "string" }, + "owner_user": { "$ref": "#/components/schemas/User" }, + "id": { "type": "string" } + }, + "required": ["id", "members", "name", "owner_user", "owner_user_id"] + }, + "TeamMember": { + "type": "object", + "properties": { + "membership_state": { "$ref": "#/components/schemas/TeamMemberState" }, + "permissions": { "type": "array", "items": { "type": "string" } }, + "team_id": { "type": "string" }, + "team": { "$ref": "#/components/schemas/Team" }, + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "id": { "type": "string" } + }, + "required": ["id", "membership_state", "permissions", "team", "team_id", "user", "user_id"] + }, + "TeamMemberState": { "enum": [1, 2], "type": "number" }, + "Guild": { + "type": "object", + "properties": { + "afk_channel_id": { "type": "string" }, + "afk_channel": { "$ref": "#/components/schemas/Channel" }, + "afk_timeout": { "type": "integer" }, + "bans": { "type": "array", "items": { "$ref": "#/components/schemas/Ban" } }, + "banner": { "type": "string" }, + "default_message_notifications": { "type": "integer" }, + "description": { "type": "string" }, + "discovery_splash": { "type": "string" }, + "explicit_content_filter": { "type": "integer" }, + "features": { "type": "array", "items": { "type": "string" } }, + "icon": { "type": "string" }, + "large": { "type": "boolean" }, + "max_members": { "type": "integer" }, + "max_presences": { "type": "integer" }, + "max_video_channel_users": { "type": "integer" }, + "member_count": { "type": "integer" }, + "presence_count": { "type": "integer" }, + "members": { "type": "array", "items": { "$ref": "#/components/schemas/Member" } }, + "roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } }, + "channels": { "type": "array", "items": { "$ref": "#/components/schemas/Channel" } }, + "template_id": { "type": "string" }, + "template": { "$ref": "#/components/schemas/Template" }, + "emojis": { "type": "array", "items": { "$ref": "#/components/schemas/Emoji" } }, + "stickers": { "type": "array", "items": { "$ref": "#/components/schemas/Sticker" } }, + "invites": { "type": "array", "items": { "$ref": "#/components/schemas/Invite" } }, + "voice_states": { "type": "array", "items": { "$ref": "#/components/schemas/VoiceState" } }, + "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } }, + "mfa_level": { "type": "integer" }, + "name": { "type": "string" }, + "owner_id": { "type": "string" }, + "owner": { "$ref": "#/components/schemas/User" }, + "preferred_locale": { "type": "string" }, + "premium_subscription_count": { "type": "integer" }, + "premium_tier": { "type": "integer" }, + "public_updates_channel_id": { "type": "string" }, + "public_updates_channel": { "$ref": "#/components/schemas/Channel" }, + "rules_channel_id": { "type": "string" }, + "rules_channel": { "type": "string" }, + "region": { "type": "string" }, + "splash": { "type": "string" }, + "system_channel_id": { "type": "string" }, + "system_channel": { "$ref": "#/components/schemas/Channel" }, + "system_channel_flags": { "type": "integer" }, + "unavailable": { "type": "boolean" }, + "vanity_url_code": { "type": "string" }, + "vanity_url": { "$ref": "#/components/schemas/Invite" }, + "verification_level": { "type": "integer" }, + "welcome_screen": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "description": { "type": "string" }, + "welcome_channels": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { "type": "string" }, + "emoji_id": { "type": "string" }, + "emoji_name": { "type": "string" }, + "channel_id": { "type": "string" } + }, + "additionalProperties": false, + "required": ["channel_id", "description", "emoji_name"] + } + } + }, + "additionalProperties": false, + "required": ["description", "enabled", "welcome_channels"] + }, + "widget_channel_id": { "type": "string" }, + "widget_channel": { "$ref": "#/components/schemas/Channel" }, + "widget_enabled": { "type": "boolean" }, + "id": { "type": "string" } + }, + "required": [ + "bans", + "channels", + "emojis", + "features", + "id", + "invites", + "members", + "name", + "owner", + "owner_id", + "public_updates_channel_id", + "roles", + "stickers", + "template", + "template_id", + "voice_states", + "webhooks", + "welcome_screen" + ] + }, + "Channel": { + "type": "object", + "properties": { + "created_at": { "type": "string", "format": "date-time" }, + "name": { "type": "string" }, + "type": { "$ref": "#/components/schemas/ChannelType" }, + "recipients": { "type": "array", "items": { "$ref": "#/components/schemas/Recipient" } }, + "last_message_id": { "type": "string" }, + "last_message": { "$ref": "#/components/schemas/Message" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "parent_id": { "type": "string" }, + "parent": { "$ref": "#/components/schemas/Channel" }, + "owner_id": { "type": "string" }, + "owner": { "$ref": "#/components/schemas/User" }, + "last_pin_timestamp": { "type": "integer" }, + "default_auto_archive_duration": { "type": "integer" }, + "position": { "type": "integer" }, + "permission_overwrites": { "type": "array", "items": { "$ref": "#/components/schemas/ChannelPermissionOverwrite" } }, + "video_quality_mode": { "type": "integer" }, + "bitrate": { "type": "integer" }, + "user_limit": { "type": "integer" }, + "nsfw": { "type": "boolean" }, + "rate_limit_per_user": { "type": "integer" }, + "topic": { "type": "string" }, + "id": { "type": "string" } + }, + "required": [ + "created_at", + "guild", + "id", + "last_message_id", + "name", + "owner", + "owner_id", + "parent_id", + "permission_overwrites", + "position", + "type" + ] + }, + "ChannelType": { "enum": [0, 1, 2, 3, 4, 5, 6], "type": "number" }, + "Recipient": { + "type": "object", + "properties": { + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "user": { "$ref": "#/components/schemas/User" }, + "id": { "type": "string" } + }, + "required": ["channel", "channel_id", "id", "user"] + }, + "Message": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "author_id": { "type": "string" }, + "author": { "$ref": "#/components/schemas/User" }, + "member_id": { "type": "string" }, + "member": { "$ref": "#/components/schemas/Member" }, + "webhook_id": { "type": "string" }, + "webhook": { "$ref": "#/components/schemas/Webhook" }, + "application_id": { "type": "string" }, + "application": { "$ref": "#/components/schemas/Application" }, + "content": { "type": "string" }, + "timestamp": { "type": "string", "format": "date-time" }, + "edited_timestamp": { "type": "string", "format": "date-time" }, + "tts": { "type": "boolean" }, + "mention_everyone": { "type": "boolean" }, + "mentions": { "type": "array", "items": { "$ref": "#/components/schemas/User" } }, + "mention_roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } }, + "mention_channels": { "type": "array", "items": { "$ref": "#/components/schemas/Channel" } }, + "sticker_items": { "type": "array", "items": { "$ref": "#/components/schemas/Sticker" } }, + "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/Attachment" } }, + "embeds": { "type": "array", "items": { "$ref": "#/components/schemas/Embed" } }, + "reactions": { "type": "array", "items": { "$ref": "#/components/schemas/Reaction" } }, + "nonce": { "type": "string" }, + "pinned": { "type": "boolean" }, + "type": { "$ref": "#/components/schemas/MessageType" }, + "activity": { + "type": "object", + "properties": { "type": { "type": "integer" }, "party_id": { "type": "string" } }, + "additionalProperties": false, + "required": ["party_id", "type"] + }, + "flags": { "type": "string" }, + "message_reference": { + "type": "object", + "properties": { + "message_id": { "type": "string" }, + "channel_id": { "type": "string" }, + "guild_id": { "type": "string" } + }, + "additionalProperties": false, + "required": ["message_id"] + }, + "referenced_message": { "$ref": "#/components/schemas/Message" }, + "interaction": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "type": { "$ref": "#/components/schemas/InteractionType" }, + "name": { "type": "string" }, + "user_id": { "type": "string" } + }, + "additionalProperties": false, + "required": ["id", "name", "type", "user_id"] + }, + "components": { "type": "array", "items": { "$ref": "#/components/schemas/MessageComponent" } } + }, + "required": [ + "application_id", + "author_id", + "channel", + "channel_id", + "embeds", + "id", + "member_id", + "mention_channels", + "mention_roles", + "mentions", + "reactions", + "timestamp", + "type", + "webhook_id" + ] + }, + "Member": { + "type": "object", + "properties": { + "user": { "$ref": "#/components/schemas/User" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "nick": { "type": "string" }, + "roles": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } }, + "joined_at": { "type": "string", "format": "date-time" }, + "premium_since": { "type": "integer" }, + "deaf": { "type": "boolean" }, + "mute": { "type": "boolean" }, + "pending": { "type": "boolean" }, + "settings": { "$ref": "#/components/schemas/UserGuildSettings" }, + "id": { "type": "string" } + }, + "required": ["deaf", "guild", "guild_id", "id", "joined_at", "mute", "pending", "roles", "settings", "user"] + }, + "Role": { + "type": "object", + "properties": { + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "color": { "type": "integer" }, + "hoist": { "type": "boolean" }, + "managed": { "type": "boolean" }, + "mentionable": { "type": "boolean" }, + "name": { "type": "string" }, + "permissions": { "type": "string" }, + "position": { "type": "integer" }, + "tags": { + "type": "object", + "properties": { + "bot_id": { "type": "string" }, + "integration_id": { "type": "string" }, + "premium_subscriber": { "type": "boolean" } + }, + "additionalProperties": false + }, + "id": { "type": "string" } + }, + "required": ["color", "guild", "guild_id", "hoist", "id", "managed", "mentionable", "name", "permissions", "position"] + }, + "UserGuildSettings": { + "type": "object", + "properties": { + "channel_overrides": { + "type": "array", + "items": { + "type": "object", + "properties": { + "channel_id": { "type": "string" }, + "message_notifications": { "type": "integer" }, + "mute_config": { "$ref": "#/components/schemas/MuteConfig" }, + "muted": { "type": "boolean" } + }, + "additionalProperties": false, + "required": ["channel_id", "message_notifications", "mute_config", "muted"] + } + }, + "message_notifications": { "type": "integer" }, + "mobile_push": { "type": "boolean" }, + "mute_config": { "$ref": "#/components/schemas/MuteConfig" }, + "muted": { "type": "boolean" }, + "suppress_everyone": { "type": "boolean" }, + "suppress_roles": { "type": "boolean" }, + "version": { "type": "integer" } + }, + "required": [ + "channel_overrides", + "message_notifications", + "mobile_push", + "mute_config", + "muted", + "suppress_everyone", + "suppress_roles", + "version" + ] + }, + "MuteConfig": { + "type": "object", + "properties": { "end_time": { "type": "integer" }, "selected_time_window": { "type": "integer" } }, + "required": ["end_time", "selected_time_window"] + }, + "Webhook": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "type": { "$ref": "#/components/schemas/WebhookType" }, + "name": { "type": "string" }, + "avatar": { "type": "string" }, + "token": { "type": "string" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "application_id": { "type": "string" }, + "application": { "$ref": "#/components/schemas/Application" }, + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "source_guild_id": { "type": "string" }, + "source_guild": { "$ref": "#/components/schemas/Guild" } + }, + "required": [ + "application", + "application_id", + "channel", + "channel_id", + "guild", + "guild_id", + "id", + "source_guild", + "source_guild_id", + "type", + "user", + "user_id" + ] + }, + "WebhookType": { "enum": [1, 2], "type": "number" }, + "Application": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "icon": { "type": "string" }, + "description": { "type": "string" }, + "rpc_origins": { "type": "array", "items": { "type": "string" } }, + "bot_public": { "type": "boolean" }, + "bot_require_code_grant": { "type": "boolean" }, + "terms_of_service_url": { "type": "string" }, + "privacy_policy_url": { "type": "string" }, + "owner": { "$ref": "#/components/schemas/User" }, + "summary": { "type": "string" }, + "verify_key": { "type": "string" }, + "team": { "$ref": "#/components/schemas/Team" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "primary_sku_id": { "type": "string" }, + "slug": { "type": "string" }, + "cover_image": { "type": "string" }, + "flags": { "type": "string" }, + "id": { "type": "string" } + }, + "required": ["bot_public", "bot_require_code_grant", "description", "flags", "guild", "id", "name", "verify_key"] + }, + "Sticker": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "description": { "type": "string" }, + "tags": { "type": "string" }, + "pack_id": { "type": "string" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "type": { "$ref": "#/components/schemas/StickerType" }, + "format_type": { "$ref": "#/components/schemas/StickerFormatType" }, + "id": { "type": "string" } + }, + "required": ["format_type", "id", "name", "pack_id", "tags", "type"] + }, + "StickerType": { "enum": [1, 2], "type": "number" }, + "StickerFormatType": { "enum": [1, 2, 3], "type": "number" }, + "Attachment": { + "type": "object", + "properties": { + "filename": { "type": "string" }, + "size": { "type": "integer" }, + "url": { "type": "string" }, + "proxy_url": { "type": "string" }, + "height": { "type": "integer" }, + "width": { "type": "integer" }, + "content_type": { "type": "string" }, + "message_id": { "type": "string" }, + "message": { "$ref": "#/components/schemas/Message" }, + "id": { "type": "string" } + }, + "required": ["filename", "id", "message", "message_id", "proxy_url", "size", "url"] + }, + "Embed": { + "type": "object", + "properties": { + "title": { "type": "string" }, + "type": { "$ref": "#/components/schemas/EmbedType" }, + "description": { "type": "string" }, + "url": { "type": "string" }, + "timestamp": { "type": "string", "format": "date-time" }, + "color": { "type": "integer" }, + "footer": { + "type": "object", + "properties": { + "text": { "type": "string" }, + "icon_url": { "type": "string" }, + "proxy_icon_url": { "type": "string" } + }, + "additionalProperties": false, + "required": ["text"] + }, + "image": { "$ref": "#/components/schemas/EmbedImage" }, + "thumbnail": { "$ref": "#/components/schemas/EmbedImage" }, + "video": { "$ref": "#/components/schemas/EmbedImage" }, + "provider": { + "type": "object", + "properties": { "name": { "type": "string" }, "url": { "type": "string" } }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "url": { "type": "string" }, + "icon_url": { "type": "string" }, + "proxy_icon_url": { "type": "string" } + }, + "additionalProperties": false + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { "name": { "type": "string" }, "value": { "type": "string" }, "inline": { "type": "boolean" } }, + "additionalProperties": false, + "required": ["name", "value"] + } + } + } + }, + "EmbedType": { "enum": ["article", "gifv", "image", "link", "rich", "video"], "type": "string" }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { "type": "string" }, + "proxy_url": { "type": "string" }, + "height": { "type": "integer" }, + "width": { "type": "integer" } + } + }, + "Reaction": { + "type": "object", + "properties": { + "count": { "type": "integer" }, + "emoji": { "$ref": "#/components/schemas/PartialEmoji" }, + "user_ids": { "type": "array", "items": { "type": "string" } } + }, + "required": ["count", "emoji", "user_ids"] + }, + "PartialEmoji": { + "type": "object", + "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "animated": { "type": "boolean" } }, + "required": ["name"] + }, + "MessageType": { "enum": [0, 1, 10, 11, 12, 14, 15, 19, 2, 20, 3, 4, 5, 6, 7, 8, 9], "type": "number" }, + "InteractionType": { "enum": [1, 2], "type": "number" }, + "MessageComponent": { + "type": "object", + "properties": { + "type": { "type": "integer" }, + "style": { "type": "integer" }, + "label": { "type": "string" }, + "emoji": { "$ref": "#/components/schemas/PartialEmoji" }, + "custom_id": { "type": "string" }, + "url": { "type": "string" }, + "disabled": { "type": "boolean" }, + "components": { "type": "array", "items": { "$ref": "#/components/schemas/MessageComponent" } } + }, + "required": ["components", "type"] + }, + "ChannelPermissionOverwrite": { + "type": "object", + "properties": { + "allow": { "type": "number" }, + "deny": { "type": "number" }, + "id": { "type": "string" }, + "type": { "$ref": "#/components/schemas/ChannelPermissionOverwriteType" } + }, + "required": ["allow", "deny", "id", "type"] + }, + "ChannelPermissionOverwriteType": { "enum": [0, 1], "type": "number" }, + "Ban": { + "type": "object", + "properties": { + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "executor_id": { "type": "string" }, + "executor": { "$ref": "#/components/schemas/User" }, + "ip": { "type": "string" }, + "reason": { "type": "string" }, + "id": { "type": "string" } + }, + "required": ["executor", "executor_id", "guild", "guild_id", "id", "ip", "user", "user_id"] + }, + "Template": { + "type": "object", + "properties": { + "code": { "type": "string" }, + "name": { "type": "string" }, + "description": { "type": "string" }, + "usage_count": { "type": "integer" }, + "creator_id": { "type": "string" }, + "creator": { "$ref": "#/components/schemas/User" }, + "created_at": { "type": "string", "format": "date-time" }, + "updated_at": { "type": "string", "format": "date-time" }, + "source_guild_id": { "type": "string" }, + "source_guild": { "$ref": "#/components/schemas/Guild" }, + "serialized_source_guild": { "$ref": "#/components/schemas/Guild" }, + "id": { "type": "string" } + }, + "required": [ + "code", + "created_at", + "creator", + "creator_id", + "id", + "name", + "serialized_source_guild", + "source_guild", + "source_guild_id", + "updated_at" + ] + }, + "Emoji": { + "type": "object", + "properties": { + "animated": { "type": "boolean" }, + "available": { "type": "boolean" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "managed": { "type": "boolean" }, + "name": { "type": "string" }, + "require_colons": { "type": "boolean" }, + "id": { "type": "string" } + }, + "required": ["animated", "available", "guild", "guild_id", "id", "managed", "name", "require_colons"] + }, + "Invite": { + "type": "object", + "properties": { + "code": { "type": "string" }, + "temporary": { "type": "boolean" }, + "uses": { "type": "integer" }, + "max_uses": { "type": "integer" }, + "max_age": { "type": "integer" }, + "created_at": { "type": "string", "format": "date-time" }, + "expires_at": { "type": "string", "format": "date-time" }, + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "inviter_id": { "type": "string" }, + "inviter": { "$ref": "#/components/schemas/User" }, + "target_user_id": { "type": "string" }, + "target_user": { "type": "string" }, + "target_user_type": { "type": "integer" }, + "id": { "type": "string" } + }, + "required": [ + "channel", + "channel_id", + "code", + "created_at", + "expires_at", + "guild", + "guild_id", + "id", + "inviter", + "inviter_id", + "max_age", + "max_uses", + "target_user_id", + "temporary", + "uses" + ] + }, + "VoiceState": { + "type": "object", + "properties": { + "guild_id": { "type": "string" }, + "guild": { "$ref": "#/components/schemas/Guild" }, + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "session_id": { "type": "string" }, + "deaf": { "type": "boolean" }, + "mute": { "type": "boolean" }, + "self_deaf": { "type": "boolean" }, + "self_mute": { "type": "boolean" }, + "self_stream": { "type": "boolean" }, + "self_video": { "type": "boolean" }, + "suppress": { "type": "boolean" }, + "id": { "type": "string" } + }, + "required": [ + "channel", + "channel_id", + "deaf", + "guild_id", + "id", + "mute", + "self_deaf", + "self_mute", + "self_video", + "session_id", + "suppress", + "user", + "user_id" + ] + }, + "AuditLogEvents": { + "enum": [ + 1, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 40, 41, 42, 50, 51, 52, 60, 61, 62, 72, 73, + 74, 75, 80, 81, 82 + ], + "type": "number" + }, + "AuditLogChange": { + "type": "object", + "properties": { + "new_value": { "$ref": "#/components/schemas/AuditLogChangeValue" }, + "old_value": { "$ref": "#/components/schemas/AuditLogChangeValue" }, + "key": { "type": "string" } + }, + "required": ["key"] + }, + "AuditLogChangeValue": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "description": { "type": "string" }, + "icon_hash": { "type": "string" }, + "splash_hash": { "type": "string" }, + "discovery_splash_hash": { "type": "string" }, + "banner_hash": { "type": "string" }, + "owner_id": { "type": "string" }, + "region": { "type": "string" }, + "preferred_locale": { "type": "string" }, + "afk_channel_id": { "type": "string" }, + "afk_timeout": { "type": "integer" }, + "rules_channel_id": { "type": "string" }, + "public_updates_channel_id": { "type": "string" }, + "mfa_level": { "type": "integer" }, + "verification_level": { "type": "integer" }, + "explicit_content_filter": { "type": "integer" }, + "default_message_notifications": { "type": "integer" }, + "vanity_url_code": { "type": "string" }, + "$add": { "type": "array", "items": { "type": "object", "properties": {} } }, + "$remove": { "type": "array", "items": { "type": "object", "properties": {} } }, + "prune_delete_days": { "type": "integer" }, + "widget_enabled": { "type": "boolean" }, + "widget_channel_id": { "type": "string" }, + "system_channel_id": { "type": "string" }, + "position": { "type": "integer" }, + "topic": { "type": "string" }, + "bitrate": { "type": "integer" }, + "permission_overwrites": { "type": "array", "items": { "$ref": "#/components/schemas/ChannelPermissionOverwrite" } }, + "nsfw": { "type": "boolean" }, + "application_id": { "type": "string" }, + "rate_limit_per_user": { "type": "integer" }, + "permissions": { "type": "string" }, + "color": { "type": "integer" }, + "hoist": { "type": "boolean" }, + "mentionable": { "type": "boolean" }, + "allow": { "type": "string" }, + "deny": { "type": "string" }, + "code": { "type": "string" }, + "channel_id": { "type": "string" }, + "inviter_id": { "type": "string" }, + "max_uses": { "type": "integer" }, + "uses": { "type": "integer" }, + "max_age": { "type": "integer" }, + "temporary": { "type": "boolean" }, + "deaf": { "type": "boolean" }, + "mute": { "type": "boolean" }, + "nick": { "type": "string" }, + "avatar_hash": { "type": "string" }, + "id": { "type": "string" }, + "type": { "type": "integer" }, + "enable_emoticons": { "type": "boolean" }, + "expire_behavior": { "type": "integer" }, + "expire_grace_period": { "type": "integer" }, + "user_limit": { "type": "integer" } + } + }, + "AuditLog": { + "type": "object", + "properties": { + "target": { "$ref": "#/components/schemas/User" }, + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "action_type": { "$ref": "#/components/schemas/AuditLogEvents" }, + "options": { + "type": "object", + "properties": { + "delete_member_days": { "type": "string" }, + "members_removed": { "type": "string" }, + "channel_id": { "type": "string" }, + "messaged_id": { "type": "string" }, + "count": { "type": "string" }, + "id": { "type": "string" }, + "type": { "type": "string" }, + "role_name": { "type": "string" } + }, + "additionalProperties": false + }, + "changes": { "type": "array", "items": { "$ref": "#/components/schemas/AuditLogChange" } }, + "reason": { "type": "string" }, + "id": { "type": "string" } + }, + "required": ["action_type", "changes", "id", "user", "user_id"] + }, + "ReadState": { + "type": "object", + "properties": { + "channel_id": { "type": "string" }, + "channel": { "$ref": "#/components/schemas/Channel" }, + "user_id": { "type": "string" }, + "user": { "$ref": "#/components/schemas/User" }, + "last_message_id": { "type": "string" }, + "last_message": { "$ref": "#/components/schemas/Message" }, + "last_pin_timestamp": { "type": "string", "format": "date-time" }, + "mention_count": { "type": "integer" }, + "manual": { "type": "boolean" }, + "id": { "type": "string" } + }, + "required": ["channel", "channel_id", "id", "last_message_id", "manual", "mention_count", "user", "user_id"] + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { "type": "string" }, + "discriminator": { "type": "string" }, + "id": { "type": "string" }, + "public_flags": { "type": "string" }, + "avatar": { "type": "string" }, + "accent_color": { "type": "integer" }, + "banner": { "type": "string" }, + "bio": { "type": "string" }, + "bot": { "type": "boolean" } + }, + "required": ["bio", "bot", "discriminator", "id", "public_flags", "username"] + } + }, + "requestBodies": { + "BanCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "delete_message_days": { "type": "string" }, "reason": { "type": "string" } } + } + } + }, + "description": "" + }, + "DmChannelCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "recipients": { "type": "array", "items": { "type": "string" } } + }, + "required": ["recipients"] + } + } + }, + "description": "" + }, + "ChannelModifySchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "type": { "type": "integer" }, + "topic": { "type": "string" }, + "bitrate": { "type": "integer" }, + "user_limit": { "type": "integer" }, + "rate_limit_per_user": { "type": "integer" }, + "position": { "type": "integer" }, + "permission_overwrites": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "type": { "type": "integer" }, + "allow": { "type": "number" }, + "deny": { "type": "number" } + }, + "additionalProperties": false, + "required": ["allow", "deny", "id", "type"] + } + }, + "parent_id": { "type": "string" }, + "id": { "type": "string" }, + "nsfw": { "type": "boolean" }, + "rtc_region": { "type": "string" }, + "default_auto_archive_duration": { "type": "integer" } + }, + "required": ["name", "type"] + } + } + }, + "description": "" + }, + "ChannelGuildPositionUpdateSchema": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { "id": { "type": "string" }, "position": { "type": "integer" } }, + "additionalProperties": false, + "required": ["id"] + } + } + } + }, + "description": "" + }, + "EmojiCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "image": { "type": "string" }, + "roles": { "type": "array", "items": { "type": "string" } } + }, + "required": ["image", "name"] + } + } + }, + "description": "" + }, + "GuildCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "region": { "type": "string" }, + "icon": { "type": "string" }, + "channels": { "type": "array", "items": { "$ref": "#/components/requestBodies/ChannelModifySchema" } }, + "guild_template_code": { "type": "string" }, + "system_channel_id": { "type": "string" }, + "rules_channel_id": { "type": "string" } + }, + "required": ["name"] + } + } + }, + "description": "" + }, + "GuildUpdateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "banner": { "type": "string" }, + "splash": { "type": "string" }, + "description": { "type": "string" }, + "features": { "type": "array", "items": { "type": "string" } }, + "verification_level": { "type": "integer" }, + "default_message_notifications": { "type": "integer" }, + "system_channel_flags": { "type": "integer" }, + "explicit_content_filter": { "type": "integer" }, + "public_updates_channel_id": { "type": "string" }, + "afk_timeout": { "type": "integer" }, + "afk_channel_id": { "type": "string" }, + "preferred_locale": { "type": "string" }, + "name": { "type": "string" }, + "region": { "type": "string" }, + "icon": { "type": "string" }, + "guild_template_code": { "type": "string" }, + "system_channel_id": { "type": "string" }, + "rules_channel_id": { "type": "string" } + }, + "required": ["name"] + } + } + }, + "description": "" + }, + "GuildTemplateCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "name": { "type": "string" }, "avatar": { "type": "string" } }, + "required": ["name"] + } + } + }, + "description": "" + }, + "GuildUpdateWelcomeScreenSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "welcome_channels": { + "type": "array", + "items": { + "type": "object", + "properties": { + "channel_id": { "type": "string" }, + "description": { "type": "string" }, + "emoji_id": { "type": "string" }, + "emoji_name": { "type": "string" } + }, + "additionalProperties": false, + "required": ["channel_id", "description", "emoji_name"] + } + }, + "enabled": { "type": "boolean" }, + "description": { "type": "string" } + } + } + } + }, + "description": "" + }, + "Number": { "content": { "application/json": { "schema": { "type": "object" } } }, "description": "" }, + "Boolean": { "content": { "application/json": { "schema": { "type": "object" } } }, "description": "" }, + "InviteCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "target_user_id": { "type": "string" }, + "target_type": { "type": "string" }, + "validate": { "type": "string" }, + "max_age": { "type": "integer" }, + "max_uses": { "type": "integer" }, + "temporary": { "type": "boolean" }, + "unique": { "type": "boolean" }, + "target_user": { "type": "string" }, + "target_user_type": { "type": "integer" } + } + } + } + }, + "description": "" + }, + "MemberCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "nick": { "type": "string" }, + "guild_id": { "type": "string" }, + "joined_at": { "type": "string", "format": "date-time" } + }, + "required": ["guild_id", "id", "joined_at", "nick"] + } + } + }, + "description": "" + }, + "MemberNickChangeSchema": { + "content": { + "application/json": { + "schema": { "type": "object", "properties": { "nick": { "type": "string" } }, "required": ["nick"] } + } + }, + "description": "" + }, + "MemberChangeSchema": { + "content": { + "application/json": { + "schema": { "type": "object", "properties": { "roles": { "type": "array", "items": { "type": "string" } } } } + } + }, + "description": "" + }, + "EmbedType": { + "content": { + "application/json": { "schema": { "enum": ["article", "gifv", "image", "link", "rich", "video"], "type": "string" } } + }, + "description": "" + }, + "EmbedImage": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "url": { "type": "string" }, + "proxy_url": { "type": "string" }, + "height": { "type": "integer" }, + "width": { "type": "integer" } + } + } + } + }, + "description": "" + }, + "MessageCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "content": { "type": "string" }, + "nonce": { "type": "string" }, + "tts": { "type": "boolean" }, + "flags": { "type": "string" }, + "embed": { + "additionalProperties": false, + "type": "object", + "properties": { + "title": { "type": "string" }, + "type": { "$ref": "#/components/requestBodies/EmbedType" }, + "description": { "type": "string" }, + "url": { "type": "string" }, + "timestamp": { "type": "string" }, + "color": { "type": "integer" }, + "footer": { + "type": "object", + "properties": { + "text": { "type": "string" }, + "icon_url": { "type": "string" }, + "proxy_icon_url": { "type": "string" } + }, + "additionalProperties": false, + "required": ["text"] + }, + "image": { "$ref": "#/components/requestBodies/EmbedImage" }, + "thumbnail": { "$ref": "#/components/requestBodies/EmbedImage" }, + "video": { "$ref": "#/components/requestBodies/EmbedImage" }, + "provider": { + "type": "object", + "properties": { "name": { "type": "string" }, "url": { "type": "string" } }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "url": { "type": "string" }, + "icon_url": { "type": "string" }, + "proxy_icon_url": { "type": "string" } + }, + "additionalProperties": false + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "value": { "type": "string" }, + "inline": { "type": "boolean" } + }, + "additionalProperties": false, + "required": ["name", "value"] + } + } + } + }, + "allowed_mentions": { + "type": "object", + "properties": { + "parse": { "type": "array", "items": { "type": "string" } }, + "roles": { "type": "array", "items": { "type": "string" } }, + "users": { "type": "array", "items": { "type": "string" } }, + "replied_user": { "type": "boolean" } + }, + "additionalProperties": false + }, + "message_reference": { + "type": "object", + "properties": { + "message_id": { "type": "string" }, + "channel_id": { "type": "string" }, + "guild_id": { "type": "string" }, + "fail_if_not_exists": { "type": "boolean" } + }, + "additionalProperties": false, + "required": ["channel_id", "message_id"] + }, + "payload_json": { "type": "string" }, + "file": {} + } + } + } + }, + "description": "" + }, + "RoleModifySchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "permissions": { "type": "number" }, + "color": { "type": "integer" }, + "hoist": { "type": "boolean" }, + "mentionable": { "type": "boolean" }, + "position": { "type": "integer" } + } + } + } + }, + "description": "" + }, + "TemplateCreateSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, + "required": ["name"] + } + } + }, + "description": "" + }, + "TemplateModifySchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, + "required": ["name"] + } + } + }, + "description": "" + }, + "UserModifySchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { "type": "string" }, + "avatar": { "type": "string" }, + "bio": { "type": "string" }, + "accent_color": { "type": "integer" }, + "banner": { "type": "string" }, + "password": { "type": "string" }, + "new_password": { "type": "string" }, + "code": { "type": "string" } + } + } + } + }, + "description": "" + }, + "UserSettingsSchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "afk_timeout": { "type": "integer" }, + "allow_accessibility_detection": { "type": "boolean" }, + "animate_emoji": { "type": "boolean" }, + "animate_stickers": { "type": "integer" }, + "contact_sync_enabled": { "type": "boolean" }, + "convert_emoticons": { "type": "boolean" }, + "custom_status": { + "type": "object", + "properties": { + "emoji_id": { "type": "string" }, + "emoji_name": { "type": "string" }, + "expires_at": { "type": "integer" }, + "text": { "type": "string" } + }, + "additionalProperties": false + }, + "default_guilds_restricted": { "type": "boolean" }, + "detect_platform_accounts": { "type": "boolean" }, + "developer_mode": { "type": "boolean" }, + "disable_games_tab": { "type": "boolean" }, + "enable_tts_command": { "type": "boolean" }, + "explicit_content_filter": { "type": "integer" }, + "friend_source_flags": { + "type": "object", + "properties": { "all": { "type": "boolean" } }, + "additionalProperties": false, + "required": ["all"] + }, + "gateway_connected": { "type": "boolean" }, + "gif_auto_play": { "type": "boolean" }, + "guild_folders": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { "type": "integer" }, + "guild_ids": { "type": "array", "items": { "type": "string" } }, + "id": { "type": "integer" }, + "name": { "type": "string" } + }, + "additionalProperties": false, + "required": ["color", "guild_ids", "id", "name"] + } + }, + "guild_positions": { "type": "array", "items": { "type": "string" } }, + "inline_attachment_media": { "type": "boolean" }, + "inline_embed_media": { "type": "boolean" }, + "locale": { "type": "string" }, + "message_display_compact": { "type": "boolean" }, + "native_phone_integration_enabled": { "type": "boolean" }, + "render_embeds": { "type": "boolean" }, + "render_reactions": { "type": "boolean" }, + "restricted_guilds": { "type": "array", "items": { "type": "string" } }, + "show_current_game": { "type": "boolean" }, + "status": { "enum": ["dnd", "idle", "offline", "online"], "type": "string" }, + "stream_notifications_enabled": { "type": "boolean" }, + "theme": { "enum": ["dark", "white"], "type": "string" }, + "timezone_offset": { "type": "integer" } + }, + "required": [ + "afk_timeout", + "allow_accessibility_detection", + "animate_emoji", + "animate_stickers", + "contact_sync_enabled", + "convert_emoticons", + "custom_status", + "default_guilds_restricted", + "detect_platform_accounts", + "developer_mode", + "disable_games_tab", + "enable_tts_command", + "explicit_content_filter", + "friend_source_flags", + "gateway_connected", + "gif_auto_play", + "guild_folders", + "guild_positions", + "inline_attachment_media", + "inline_embed_media", + "locale", + "message_display_compact", + "native_phone_integration_enabled", + "render_embeds", + "render_reactions", + "restricted_guilds", + "show_current_game", + "status", + "stream_notifications_enabled", + "theme", + "timezone_offset" + ] + } + } + }, + "description": "" + }, + "WidgetModifySchema": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "enabled": { "type": "boolean" }, "channel_id": { "type": "string" } }, + "required": ["channel_id", "enabled"] + } + } + }, + "description": "" + } + }, + "securitySchemes": { "authorization": { "type": "oauth2" } }, + "links": {}, + "callbacks": {} + }, + "security": [{ "authorization": [] }] +} diff --git a/api/assets/openapi.yaml b/api/assets/openapi.yaml deleted file mode 100644 index 06a0b72d..00000000 --- a/api/assets/openapi.yaml +++ /dev/null @@ -1,136 +0,0 @@ -openapi: 3.0.3 -info: - title: Fosscord - version: '9' - license: - name: GNU AGPLv3 - url: https://www.gnu.org/licenses/agpl.txt - x-last-modified: 1625409195984 - x-logo: - url: '' -servers: - - url: https://api.fosscord.com - description: '' - x-last-modified: 1625407844365 -paths: - /users/:id: - summary: get user - description: test - get: - tags: [] - responses: - '200': - $ref: '#/components/responses/User' - x-last-modified: 1625409722629 - parameters: - - name: id - in: path - required: true - deprecated: false - x-last-modified: 1625409813480 - x-last-modified: 1625409704895 -components: - schemas: - User: - type: object - properties: - avatar: - type: string - example: - - d83f330fc30367f859bc6ee358b14319 - bot: - type: boolean - example: - - false - desktop: - type: boolean - example: - - false - discriminator: - type: string - example: - - '0001' - email: - type: string - example: - - example@example.org - flags: - type: string - example: - - '0' - id: - type: string - example: - - '732645009894277321' - mfa_enabled: - type: boolean - example: - - false - mobile: - type: boolean - example: - - false - nsfw_allowed: - type: boolean - example: - - true - premium: - type: boolean - example: - - false - premium_type: - type: number - example: - - 0 - public_flags: - type: string - example: - - '0' - username: - type: string - example: - - Example - verified: - type: boolean - example: - - true - example: - avatar: d83f330fc30367f859bc6ee358b14319 - bot: false - desktop: false - discriminator: '0001' - email: example@example.org - flags: '0' - id: '732645009894277321' - mfa_enabled: false - mobile: false - nsfw_allowed: true - premium: false - premium_type: 0 - public_flags: '0' - username: Example - verified: true - x-last-modified: 1625409630283 - required: [] - description: test - securitySchemes: - JWTAuth: - scheme: bearer - bearerFormat: JWT - type: http - description: |- - Example: - > Authorization: Bot <token> - x-last-modified: 1625407825787 - headers: {} - responses: - User: - content: - application/json: - schema: - $ref: '#/components/schemas/User' - x-last-modified: 1625409578903 - parameters: {} -security: - - JWTAuth: [] -tags: [] diff --git a/api/assets/openapi.yml b/api/assets/openapi.yml deleted file mode 100644 index 957b6d16..00000000 --- a/api/assets/openapi.yml +++ /dev/null @@ -1,526 +0,0 @@ -swagger: "2.0" -info: - description: "Fosscord backend api docs" - version: "1.0.0" - title: "Fosscord Backend API" - termsOfService: "https://github.com/fosscord/fosscord/blob/master/LICENSE" - license: - name: "AGPL 3.0" - url: "https://www.gnu.org/licenses/agpl-3.0.html" -host: "dev.fosscord.com" -basePath: "/api/v9" -tags: - - name: "Audit Log" - description: "Guild Audit Log resource" - externalDocs: - description: "Find out more" - url: "https://discord.com/developers/docs/resources/audit-log" - - name: "Channel" - description: "Channel resource" - externalDocs: - description: "Find out more" - url: "https://discord.com/developers/docs/resources/channel" -schemes: - - "https" - - "http" -paths: - /guilds/{guildId}/audit-logs: - get: - summary: "Returns an audit log object for the guild. Requires the 'VIEW_AUDIT_LOG' permission." - tags: - - Audit Log - parameters: - - $ref: "#/definitionsParam/guildId" - - name: user_id - in: query - type: string - description: "Type of snowflake - Filter the log for actions made by a user" - - name: action_type - in: query - type: integer - description: "The type of audit log event" - - name: before - in: query - type: string - description: "Type of snowflake - Filter the log before a certain entry id" - - name: limit - in: query - type: integer - description: "How many entries are returned (default 50, minimum 1, maximum 100)" - responses: - '200': - description: "Audit Log Object" - schema: - $ref: "#/definitions/Audit%20Log" - /channels/{channelId}: - get: - summary: "Get a channel by ID. Returns a channel object. If the channel is a thread, a thread member object is included in the returned result." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - responses: - '200': - description: "Channel Object" - schema: - $ref: "#/definitions/Channel" - patch: - summary: "Update a channel's settings. Returns a channel on success, and a 400 BAD REQUEST on invalid parameters. All JSON parameters are optional." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - name: body (Group DM) - in: body - description: "The request body when modifying Group DM channels - Fires a Channel Update Gateway event." - schema: - type: object - properties: - name: - type: string - description: "1-100 character channel name" - icon: - type: string - format: byte - description: "base64 encoded icon" - - name: body (Guild channel) - in: body - description: "Requires the MANAGE_CHANNELS permission for the guild. Fires a Channel Update Gateway event. If modifying a category, individual Channel Update events will fire for each child channel that also changes. If modifying permission overwrites, the MANAGE_ROLES permission is required. Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel)." - schema: - type: object - properties: - name: - type: string - description: "1-100 character channel name" - type: - type: integer - description: "The type of channel; only conversion between text and news is supported and only in guilds with the \"NEWS\" feature" - position: - type: integer - default: null - description: "The position of the channel in the left-hand listing" - topic: - type: string - default: null - description: "0-1024 character channel topic" - nsfw: - type: boolean - default: null - description: "Whether the channel is nsfw" - rate_limit_per_user: - type: integer - default: null - description: "Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages or manage_channel, are unaffected" - bitrate: - type: integer - default: null - description: "The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)" - user_limit: - type: integer - default: null - description: "The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit" - permission_overwrites: - type: array - items: - $ref: "#/definitions/Overwrite" - default: null - description: "Channel or category-specific permissions" - parent_id: - $ref: "#/definitions/Snowflake" - default: null - description: "Id of the new parent category for a channel" - rtc_region: - type: string - default: null - description: "Channel voice region id, automatic when set to null" - video_quality_mode: - type: integer - default: null - description: "The camera video quality mode of the voice channel" - default_auto_archive_duration: - type: integer - default: null - description: "The default duration for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity" - - name: body (Thread) - in: body - description: "When setting archived to false, when locked is also false, only the SEND_MESSAGES permission is required.Otherwise, requires the MANAGE_THREADS permission. Fires a Thread Update Gateway event. Requires the thread to have archived set to false or be set to false in the request." - schema: - type: object - properties: - name: - type: string - description: "1-100 character channel name" - archived: - type: boolean - description: "Whether the channel is archived" - auto_archive_duration: - type: integer - description: "Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080 (The 3 day and 7 day archive durations require the server to be boosted. The guild features will indicate if a server is able to use those settings)" - locked: - type: boolean - description: "When a thread is locked, only users with MANAGE_THREADS can unarchive it" - rate_limit_per_user: - type: integer - default: null - description: "Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected" - responses: - '200': - description: "Channel Object" - schema: - $ref: "#/definitions/Channel" - '400': - description: "Bad Request due to invalid parameters" - delete: - summary: "Delete a channel, or close a private message. Requires the MANAGE_CHANNELS permission for the guild, or MANAGE_THREADS if the channel is a thread. Deleting a category does not delete its child channels; they will have their parent_id removed and a Channel Update Gateway event will fire for each of them. Returns a channel object on success. Fires a Channel Delete Gateway event (or Thread Delete if the channel was a thread)." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - responses: - '200': - description: "Channel deleted sucessfully" - /channels/{channelId}/messages: - get: - summary: "Returns the messages for a channel. If operating on a guild channel, this endpoint requires the VIEW_CHANNEL permission to be present on the current user. If the current user is missing the 'READ_MESSAGE_HISTORY' permission in the channel then this will return no messages (since they cannot read the message history). Returns an array of message objects on success." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - name: around - in: query - type: string - description: "Type of snowflake - Get messages around this message ID" - - name: before - in: query - type: string - description: "Type of snowflake - Get messages before this message ID" - - name: after - in: query - type: string - description: "Type of snowflake - Get messages after this message ID" - - name: limit - in: query - type: integer - description: "Max number of messages to return (1-100)" - default: 50 - responses: - '200': - description: "Returns an array of message objects on success" - schema: - type: array - items: - $ref: "#/definitions/Message" - /channels/{channelId}/messages/{messageId}: - get: - summary: "Returns a specific message in the channel. If operating on a guild channel, this endpoint requires the 'READ_MESSAGE_HISTORY' permission to be present on the current user. Returns a message object on success." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - responses: - '200': - description: "Returns a message object on success" - schema: - $ref: "#/definitions/Message" - post: - summary: "Post a message to a guild text or DM channel. Returns a message object. Fires a Message Create Gateway event. See message formatting for more information on how to properly format messages." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - name: body - in: body - required: true - description: "Request body that contains the necessary data for creating messages" - schema: - type: object - properties: - content: - type: string - description: "The message contents (up to 2000 characters)" - tts: - type: boolean - description: "True if this is a TTS message" - default: null - file: - type: string - format: binary - description: "The contents of the file being sent" - embeds: - type: array - items: - $ref: "#/definitions/Embed" - description: "Embedded rich content (up to 6000 characters)" - payload_json: - type: string - description: "JSON encoded body of non-file params" - default: null - allowed_mentions: - $ref: "#/definitions/Allowed%20Mention" - description: "Allowed mentions for the message" - default: null - message_refrence: - $ref: "#/definitions/Message%20Refrence" - description: "Include to make your message a reply" - default: null - components: - type: array - items: - $ref: "#/definitions/Message%20Component" - default: null - responses: - '200': - description: "Returns a message object on success" - schema: - $ref: "#/definitions/Message" - patch: - summary: "Edit a previously sent message. The fields content, embeds, and flags can be edited by the original message author. Other users can only edit flags and only if they have the MANAGE_MESSAGES permission in the corresponding channel. When specifying flags, ensure to include all previously set flags/bits in addition to ones that you are modifying. Only flags documented in the table below may be modified by users (unsupported flag changes are currently ignored without error)." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - name: body - in: body - required: true - description: "Request body that contains the necessary data for editing messages" - schema: - type: object - properties: - content: - type: string - description: "The message contents (up to 2000 characters)" - embeds: - type: array - items: - $ref: "#/definitions/Embed" - description: "Embedded rich content (up to 6000 characters)" - flags: - type: integer - description: "Edit the flags of a message (only SUPPRESS_EMBEDS can currently be set/unset)" - file: - type: string - format: binary - description: "The contents of the file being sent/edited" - payload_json: - type: string - description: "JSON encoded body of non-file params (multipart/form-data only)" - default: null - allowed_mentions: - $ref: "#/definitions/Allowed%20Mention" - description: "Allowed mentions for the message" - default: null - message_refrence: - $ref: "#/definitions/Message%20Refrence" - description: "Include to make your message a reply" - default: null - components: - type: array - items: - $ref: "#/definitions/Message%20Component" - default: null - responses: - '200': - description: "Message edited" - delete: - summary: "Delete a message. If operating on a guild channel and trying to delete a message that was not sent by the current user, this endpoint requires the MANAGE_MESSAGES permission. Returns a 204 empty response on success. Fires a Message Delete Gateway event." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - responses: - '204': - description: "Returns a 204 empty response on success." - /channels/{channelId}/messages/{messageId}/crosspost: - post: - summary: "Crosspost a message in a News Channel to following channels. This endpoint requires the 'SEND_MESSAGES' permission, if the current user sent the message, or additionally the 'MANAGE_MESSAGES' permission, for all other messages, to be present for the current user." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - responses: - '200': - description: "Returns a message object on success" - schema: - $ref: "#/definitions/Message" - /channels/{channelId}/messages/{messageId}/reactions/{emoji}/@me: - put: - summary: "Create a reaction for the message. This endpoint requires the 'READ_MESSAGE_HISTORY' permission to be present on the current user. Additionally, if nobody else has reacted to the message using this emoji, this endpoint requires the 'ADD_REACTIONS' permission to be present on the current user. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - $ref: "#/definitionsParam/emoji" - responses: - '204': - description: "Returns a 204 empty response on success." - delete: - summary: "Delete a reaction the current user has made for the message. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - $ref: "#/definitionsParam/emoji" - responses: - '204': - description: "Returns a 204 empty response on success." - /channels/{channelId}/messages/{messageId}/reactions/{emoji}/{userId}: - delete: - summary: "Deletes another user's reaction. This endpoint requires the 'MANAGE_MESSAGES' permission to be present on the current user. Returns a 204 empty response on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - $ref: "#/definitionsParam/emoji" - - $ref: "#/definitionsParam/userId" - responses: - '204': - description: "Returns a 204 empty response on success." - /channels/{channelId}/messages/{messageId}/reactions/{emoji}: - get: - summary: "Get a list of users that reacted with this emoji. Returns an array of user objects on success. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - $ref: "#/definitionsParam/emoji" - - name: after - in: query - type: string - description: "Type of snowflake - Get users after this user ID" - - name: limit - in: query - type: integer - description: "Max number of users to return (1-100)" - default: 25 - responses: - '200': - description: "Returns an array of user objects on success" - schema: - type: array - items: - $ref: "#/definitions/User" - delete: - summary: "Deletes all the reactions for a given emoji on a message. This endpoint requires the MANAGE_MESSAGES permission to be present on the current user. Fires a Message Reaction Remove Emoji Gateway event. The emoji must be URL Encoded or the request will fail with 10014: Unknown Emoji. To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - - $ref: "#/definitionsParam/emoji" - responses: - '204': - description: "Returns a 204 empty response on success." - /channels/{channelId}/messages/{messageId}/reactions: - delete: - summary: "Deletes all reactions on a message. This endpoint requires the 'MANAGE_MESSAGES' permission to be present on the current user. Fires a Message Reaction Remove All Gateway event." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - - $ref: "#/definitionsParam/messageId" - responses: - '204': - description: "Returns a 204 empty response on success." - /channels/{channelId}/messages/bulk-delete: - post: - summary: "Delete multiple messages in a single request. This endpoint can only be used on guild channels and requires the MANAGE_MESSAGES permission. Returns a 204 empty response on success. Fires a Message Delete Bulk Gateway event." - tags: - - Channel - parameters: - - $ref: "#/definitionsParam/channelId" - responses: - '204': - description: "Returns a 204 empty response on success." -definitions: - Snowflake: - type: string - pattern: "^\\d+$" - Audit Log: - type: object - properties: - webhooks: - type: array - items: - $ref: "#/definitions/Webhook" - description: "List of webhooks found in the audit log" - users: - type: array - items: - $ref: "#/definitions/User" - description: "List of users found in the audit log" - audit_log_entries: - type: array - items: - $ref: "#/definitions/Audit%20Log%20Entry" - description: "List of audit log entries" - integrations: - type: array - items: - $ref: "#/definitions/Integration" - description: "List of partial integration objects" - Audit Log Entry: - type: object - Webhook: - type: object - User: - type: object - Integration: - type: object - Channel: - type: object - Overwrite: - type: object - Message: - type: object - Embed: - type: object - Allowed Mention: - type: object - Message Refrence: - type: object - Message Component: - type: object -definitionsParam: - channelId: - name: channelId - in: path - required: true - type: string - description: "Type of snowflake - A channel Id" - messageId: - name: messageId - in: path - required: true - type: string - description: "Type of snowflake - A message ID" - guildId: - name: guildId - in: path - required: true - type: string - description: "Type of snowflake - A guild ID" - emoji: - name: emoji - in: path - required: true - type: string - format: url - description: "The emoji ID to use" - userId: - name: userId - in: path - required: true - type: string - description: "Type of snowflake - A user ID" -externalDocs: - description: "Discord API" - url: "https://discord.com/developers/docs/" diff --git a/api/patches/typescript-json-schema+0.50.1.patch b/api/patches/typescript-json-schema+0.50.1.patch new file mode 100644 index 00000000..a0d479de --- /dev/null +++ b/api/patches/typescript-json-schema+0.50.1.patch @@ -0,0 +1,14 @@ +diff --git a/node_modules/typescript-json-schema/dist/typescript-json-schema.js b/node_modules/typescript-json-schema/dist/typescript-json-schema.js +index 47e1598..8397b9d 100644 +--- a/node_modules/typescript-json-schema/dist/typescript-json-schema.js ++++ b/node_modules/typescript-json-schema/dist/typescript-json-schema.js +@@ -432,6 +432,9 @@ var JsonSchemaGenerator = (function () { + else if (flags & ts.TypeFlags.Boolean) { + definition.type = "boolean"; + } ++ else if (flags & ts.TypeFlags.BigInt) { ++ definition.type = "bigint"; ++ } + else if (flags & ts.TypeFlags.Null) { + definition.type = "null"; + } diff --git a/api/scripts/config_generator.js b/api/scripts/config_generator.js deleted file mode 100644 index 5b5c52d4..00000000 --- a/api/scripts/config_generator.js +++ /dev/null @@ -1,93 +0,0 @@ -const { Snowflake } = require("@fosscord/server-util"); -const crypto = require('crypto'); -const fs = require('fs'); - - -const defaultConfig = { - // TODO: Get the network interfaces dinamically - gateway: "ws://localhost", - general: { - instance_id: Snowflake.generate(), - }, - permissions: { - user: { - createGuilds: true, - } - }, - limits: { - user: { - maxGuilds: 100, - maxUsername: 32, - maxFriends: 1000, - }, - guild: { - maxRoles: 250, - maxMembers: 250000, - maxChannels: 500, - maxChannelsInCategory: 50, - hideOfflineMember: 1000, - }, - message: { - characters: 2000, - ttsCharacters: 200, - maxReactions: 20, - maxAttachmentSize: 8388608, - maxBulkDelete: 100, - }, - channel: { - maxPins: 50, - maxTopic: 1024, - }, - rate: { - ip: { - enabled: true, - count: 1000, - timespan: 1000 * 60 * 10, - }, - routes: {}, - }, - }, - security: { - jwtSecret: crypto.randomBytes(256).toString("base64"), - forwadedFor: null, - // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy - // forwadedFor: "CF-Connecting-IP" // cloudflare: - captcha: { - enabled: false, - service: null, - sitekey: null, - secret: null, - }, - }, - login: { - requireCaptcha: false, - }, - register: { - email: { - necessary: true, - allowlist: false, - blocklist: true, - domains: [], // TODO: efficiently save domain blocklist in database - // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), - }, - dateOfBirth: { - necessary: true, - minimum: 13, - }, - requireInvite: false, - requireCaptcha: true, - allowNewRegistration: true, - allowMultipleAccounts: true, - password: { - minLength: 8, - minNumbers: 2, - minUpperCase: 2, - minSymbols: 0, - blockInsecureCommonPasswords: false, - }, - }, -} - -let data = JSON.stringify(defaultConfig); -fs.writeFileSync('./.docker/config/api.json', data); - diff --git a/api/scripts/generate_openapi_schema.ts b/api/scripts/generate_openapi_schema.ts new file mode 100644 index 00000000..c45a43eb --- /dev/null +++ b/api/scripts/generate_openapi_schema.ts @@ -0,0 +1,191 @@ +// https://mermade.github.io/openapi-gui/# +// https://editor.swagger.io/ +import path from "path"; +import fs from "fs"; +import * as TJS from "typescript-json-schema"; +import "missing-native-js-functions"; + +const settings: TJS.PartialArgs = { + required: true, + ignoreErrors: true, + excludePrivate: true, + defaultNumberType: "integer", + noExtraProps: true, + defaultProps: false +}; +const compilerOptions: TJS.CompilerOptions = { + strictNullChecks: false +}; +const openapiPath = path.join(__dirname, "..", "assets", "openapi.json"); +var specification = JSON.parse(fs.readFileSync(openapiPath, { encoding: "utf8" })); + +async function generateSchemas() { + const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "..", "util", "src", "index.ts")], compilerOptions); + const generator = TJS.buildGenerator(program, settings); + + const schemas = [ + "Application", + "Attachment", + "Message", + "AuditLog", + "Ban", + "Channel", + "Emoji", + "Guild", + "Invite", + "ReadState", + "Recipient", + "Relationship", + "Role", + "Sticker", + "Team", + "TeamMember", + "Template", + "VoiceState", + "Webhook", + "User", + "UserPublic" + ]; + + // @ts-ignore + const definitions = combineSchemas({ schemas, generator, program }); + + for (const key in definitions) { + specification.components.schemas[key] = definitions[key]; + delete definitions[key].additionalProperties; + } +} + +function combineSchemas(opts: { program: TJS.Program; generator: TJS.JsonSchemaGenerator; schemas: string[] }) { + var definitions: any = {}; + + for (const name of opts.schemas) { + const part = TJS.generateSchema(opts.program, name, settings, [], opts.generator as TJS.JsonSchemaGenerator); + if (!part) continue; + + definitions = { ...definitions, ...part.definitions, [name]: { ...part, definitions: undefined, $schema: undefined } }; + } + + return definitions; +} + +function generateBodies() { + const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "src", "schema", "index.ts")], compilerOptions); + const generator = TJS.buildGenerator(program, settings); + + const schemas = [ + "BanCreateSchema", + "DmChannelCreateSchema", + "ChannelModifySchema", + "ChannelGuildPositionUpdateSchema", + "ChannelGuildPositionUpdateSchema", + "EmojiCreateSchema", + "GuildCreateSchema", + "GuildUpdateSchema", + "GuildTemplateCreateSchema", + "GuildUpdateWelcomeScreenSchema", + "InviteCreateSchema", + "MemberCreateSchema", + "MemberNickChangeSchema", + "MemberChangeSchema", + "MessageCreateSchema", + "RoleModifySchema", + "TemplateCreateSchema", + "TemplateModifySchema", + "UserModifySchema", + "UserSettingsSchema", + "WidgetModifySchema" + ]; + + // @ts-ignore + const definitions = combineSchemas({ schemas, generator, program }); + + for (const key in definitions) { + specification.components.requestBodies[key] = { + content: { + "application/json": { schema: definitions[key] } + }, + description: "" + }; + + delete definitions[key].additionalProperties; + delete definitions[key].$schema; + } +} + +function addDefaultResponses() { + Object.values(specification.paths).forEach((path: any) => + Object.values(path).forEach((request: any) => { + if (!request.responses?.["401"]) { + request.responses["401"] = { + description: "Unauthorized", + content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } + }; + } + if (!request.responses?.["429"]) { + request.responses["429"] = { + description: "Rate limit exceeded", + content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } }, + headers: { + "X-RateLimit-Bucket": { + description: + "A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)", + schema: { type: "string" } + }, + "X-Rate-Limit-Limit": { + description: "The number of allowed requests in the current period", + schema: { + type: "integer" + } + }, + "X-Rate-Limit-Remaining": { + description: "The number of remaining requests in the current period", + schema: { + type: "integer" + } + }, + "X-Rate-Limit-Reset": { + description: "Date when current period is over in seconds since the Unix epoch", + schema: { + type: "integer" + } + }, + "X-Rate-Limit-Reset-After": { + description: "Number of seconds when current period will reset (can have decimal)", + schema: { + type: "number" + } + }, + "Retry-After": { + description: "Same as X-Rate-Limit-Reset-After but an integer", + schema: { + type: "integer" + } + }, + "X-RateLimit-Global": { + description: "Indicates whether or not all requests from your ip are rate limited", + schema: { + type: "boolean" + } + } + } + }; + } + }) + ); +} + +function main() { + addDefaultResponses(); + generateSchemas(); + specification = JSON.parse(JSON.stringify(specification).replaceAll("#/definitions", "#/components/schemas")); + + generateBodies(); + + fs.writeFileSync( + openapiPath, + JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/requestBodies").replaceAll("bigint", "number") + ); +} + +main(); diff --git a/api/src/schema/Emoji.ts b/api/src/schema/Emoji.ts index deaccf5c..0406919c 100644 --- a/api/src/schema/Emoji.ts +++ b/api/src/schema/Emoji.ts @@ -1,14 +1,13 @@ // https://discord.com/developers/docs/resources/emoji - export const EmojiCreateSchema = { name: String, //name of the emoji image: String, // image data the 128x128 emoji image uri - roles: Array //roles allowed to use this emoji + $roles: Array //roles allowed to use this emoji }; export interface EmojiCreateSchema { name: string; // name of the emoji image: string; // image data the 128x128 emoji image uri - roles: []; //roles allowed to use this emoji + roles?: string[]; //roles allowed to use this emoji } diff --git a/api/src/schema/Guild.ts b/api/src/schema/Guild.ts index 3e98fe76..0f9fd884 100644 --- a/api/src/schema/Guild.ts +++ b/api/src/schema/Guild.ts @@ -48,7 +48,7 @@ export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels"> { banner?: string; splash?: string; description?: string; - features?: [string]; + features?: string[]; verification_level?: number; default_message_notifications?: number; system_channel_flags?: number; diff --git a/api/src/schema/Invite.ts b/api/src/schema/Invite.ts index a22449ba..da6192bc 100644 --- a/api/src/schema/Invite.ts +++ b/api/src/schema/Invite.ts @@ -10,13 +10,13 @@ export const InviteCreateSchema = { $target_user_type: Number }; export interface InviteCreateSchema { - target_user_id?: String; - target_type?: String; - validate?: String; //? wtf is this - max_age?: Number; - max_uses?: Number; - temporary?: Boolean; - unique?: Boolean; - target_user?: String; - target_user_type?: Number; + target_user_id?: string; + target_type?: string; + validate?: string; //? wtf is this + max_age?: number; + max_uses?: number; + temporary?: boolean; + unique?: boolean; + target_user?: string; + target_user_type?: number; } diff --git a/api/src/schema/index.ts b/api/src/schema/index.ts new file mode 100644 index 00000000..b5f38a2f --- /dev/null +++ b/api/src/schema/index.ts @@ -0,0 +1,11 @@ +export * from "./Ban"; +export * from "./Channel"; +export * from "./Emoji"; +export * from "./Guild"; +export * from "./Invite"; +export * from "./Member"; +export * from "./Message"; +export * from "./Roles"; +export * from "./Template"; +export * from "./User"; +export * from "./Widget"; |