summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-06-13 20:24:12 +0200
committerRory& <root@rory.gay>2026-06-13 20:37:26 +0200
commit42406c18383902bbef5f3d78e5c04511eff9f519 (patch)
tree881a08adcf965677d5cafdd09d609558f4817dd5
parentSplit config/response voice regions, remove APIVoiceRegion alias (diff)
downloadserver-ts-42406c18383902bbef5f3d78e5c04511eff9f519.tar.xz
Replace APIRole with schema
-rw-r--r--assets/openapi.json106
-rw-r--r--assets/schemas.json122
-rw-r--r--src/api/routes/guilds/#guild_id/roles/index.ts2
-rw-r--r--src/schemas/api/guilds/Role.ts61
-rw-r--r--src/schemas/responses/TypedResponses.ts4
5 files changed, 277 insertions, 18 deletions
diff --git a/assets/openapi.json b/assets/openapi.json

index 95a8807f..45a151ba 100644 --- a/assets/openapi.json +++ b/assets/openapi.json
@@ -3670,6 +3670,75 @@ "id" ] }, + "RoleResponse": { + "type": "object", + "properties": { + "id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "color": { + "type": "integer" + }, + "colors": { + "$ref": "#/components/schemas/RoleColors" + }, + "hoist": { + "type": "boolean" + }, + "icon": { + "type": "string", + "nullable": true + }, + "unicode_emoji": { + "type": "string", + "nullable": true + }, + "position": { + "type": "integer" + }, + "permissions": { + "type": "string" + }, + "managed": { + "type": "boolean" + }, + "mentionable": { + "type": "boolean" + }, + "flags": { + "type": "integer" + }, + "tags": { + "$ref": "#/components/schemas/RoleTags" + } + }, + "required": [ + "color", + "colors", + "description", + "hoist", + "id", + "managed", + "mentionable", + "name", + "permissions", + "position" + ] + }, + "RoleListResponse": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoleResponse" + } + }, "StickersResponse": { "type": "array", "items": { @@ -5097,12 +5166,6 @@ "widget_enabled" ] }, - "APIRoleArray": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Role" - } - }, "APITemplateArray": { "type": "array", "items": { @@ -14061,6 +14124,35 @@ 3 ] }, + "RoleTags": { + "type": "object", + "properties": { + "bot_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "integration_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "subscription_listing_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "premium_subscriber": { + "type": "boolean", + "nullable": true + }, + "available_for_purchase": { + "type": "boolean", + "nullable": true + }, + "guild_connections": { + "type": "boolean", + "nullable": true + } + } + }, "DmChannelDTO": { "type": "object", "properties": { @@ -20826,7 +20918,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/APIRoleArray" + "$ref": "#/components/schemas/RoleListResponse" } } } diff --git a/assets/schemas.json b/assets/schemas.json
index 9506fab1..b82fe518 100644 --- a/assets/schemas.json +++ b/assets/schemas.json
@@ -3893,6 +3893,84 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "RoleResponse": { + "type": "object", + "properties": { + "id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": [ + "null", + "string" + ] + }, + "color": { + "type": "integer" + }, + "colors": { + "$ref": "#/definitions/RoleColors" + }, + "hoist": { + "type": "boolean" + }, + "icon": { + "type": [ + "null", + "string" + ] + }, + "unicode_emoji": { + "type": [ + "null", + "string" + ] + }, + "position": { + "type": "integer" + }, + "permissions": { + "type": "string" + }, + "managed": { + "type": "boolean" + }, + "mentionable": { + "type": "boolean" + }, + "flags": { + "type": "integer" + }, + "tags": { + "$ref": "#/definitions/RoleTags" + } + }, + "additionalProperties": false, + "required": [ + "color", + "colors", + "description", + "hoist", + "id", + "managed", + "mentionable", + "name", + "permissions", + "position" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "RoleListResponse": { + "type": "array", + "items": { + "$ref": "#/definitions/RoleResponse" + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, "StickersResponse": { "type": "array", "items": { @@ -5399,13 +5477,6 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, - "APIRoleArray": { - "type": "array", - "items": { - "$ref": "#/definitions/Role" - }, - "$schema": "http://json-schema.org/draft-07/schema#" - }, "APITemplateArray": { "type": "array", "items": { @@ -15024,6 +15095,43 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "RoleTags": { + "type": "object", + "properties": { + "bot_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "integration_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "subscription_listing_id": { + "description": "A Twitter-like snowflake, except the epoch is 2015-01-01T00:00:00.000Z\n```\nIf we have a snowflake '266241948824764416' we can represent it as binary:\n\n64 22 17 12 0\n 000000111011000111100001101001000101000000 00001 00000 000000000000\n number of ms since Discord epoch worker pid increment\n```", + "type": "string" + }, + "premium_subscriber": { + "type": [ + "null", + "boolean" + ] + }, + "available_for_purchase": { + "type": [ + "null", + "boolean" + ] + }, + "guild_connections": { + "type": [ + "null", + "boolean" + ] + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" + }, "DmChannelDTO": { "type": "object", "properties": { diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts
index 4cb82663..5f792222 100644 --- a/src/api/routes/guilds/#guild_id/roles/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/index.ts
@@ -119,7 +119,7 @@ router.patch( permission: "MANAGE_ROLES", responses: { 200: { - body: "APIRoleArray", + body: "RoleListResponse", }, 400: { body: "APIErrorResponse", diff --git a/src/schemas/api/guilds/Role.ts b/src/schemas/api/guilds/Role.ts
index 2f32e5d7..fd3440e6 100644 --- a/src/schemas/api/guilds/Role.ts +++ b/src/schemas/api/guilds/Role.ts
@@ -1,3 +1,44 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2026 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +import { Snowflake } from "../../Identifiers"; + +export interface RoleResponse { + id: Snowflake; + name: string; + description: string | null; + // @deprecated + color: number; + colors: RoleColors; + hoist: boolean; + icon?: string | null; + unicode_emoji?: string | null; + position: number; + // @format number + permissions: string; + managed: boolean; + mentionable: boolean; + flags?: number; + tags?: RoleTags; // unused currently +} + +export type RoleListResponse = RoleResponse[]; + export class RoleColors { primary_color: number; secondary_color: number | undefined; // only used for "holographic" and "gradient" styles @@ -11,3 +52,23 @@ export class RoleColors { }; } } + +export class RoleTags { + bot_id?: Snowflake; + integration_id?: Snowflake; + subscription_listing_id?: Snowflake; + // ??? https://github.com/discord-userdoccers/discord-userdoccers/issues/576 - in other words, types are currently unknown + premium_subscriber?: boolean | null; + available_for_purchase?: boolean | null; + guild_connections?: boolean | null; + + toJSON(): RoleTags { + return { + ...this, + // "forward compatibility" + premium_subscriber: this.premium_subscriber ? null : undefined, + available_for_purchase: this.available_for_purchase ? null : undefined, + guild_connections: this.subscription_listing_id ? null : undefined, + }; + } +} diff --git a/src/schemas/responses/TypedResponses.ts b/src/schemas/responses/TypedResponses.ts
index 692487b0..e0413a72 100644 --- a/src/schemas/responses/TypedResponses.ts +++ b/src/schemas/responses/TypedResponses.ts
@@ -20,8 +20,7 @@ import { GeneralConfiguration, LimitsConfiguration } from "../../util/config/types"; import { DmChannelDTO } from "../../util/dtos"; // TODO: remove entity imports -import { Application, BackupCode, Categories, Channel, Guild, Invite, Member, Message, Role, Template, Webhook } from "@spacebar/database"; -import { GuildVoiceRegion } from "./GuildVoiceRegionsResponse"; +import { Application, BackupCode, Categories, Channel, Guild, Invite, Member, Message, Template, Webhook } from "@spacebar/database"; import { GuildCreateResponse, PrivateUser, PublicMember, PublicUser } from "@spacebar/schemas"; // TODO: remove this entire file! @@ -54,7 +53,6 @@ export interface APIGuildWithJoinedAt extends GuildCreateResponse { joined_at: string; } -export type APIRoleArray = Role[]; export type APITemplateArray = Template[]; export type APILimitsConfiguration = LimitsConfiguration;