diff --git a/assets/openapi.json b/assets/openapi.json index d641fe6..230af20 100644 --- a/assets/openapi.json +++ b/assets/openapi.json @@ -2531,6 +2531,9 @@ "$ref": "#/components/schemas/Webhook" } }, + "member_count": { + "type": "integer" + }, "roles": { "type": "array", "items": { @@ -2619,9 +2622,6 @@ "max_video_channel_users": { "type": "integer" }, - "member_count": { - "type": "integer" - }, "presence_count": { "type": "integer" }, @@ -7008,6 +7008,12 @@ "channel": { "$ref": "#/components/schemas/Channel" }, + "thread_id": { + "type": "string" + }, + "thread": { + "$ref": "#/components/schemas/Channel" + }, "guild_id": { "type": "string" }, @@ -7378,6 +7384,18 @@ "type": "integer", "default": 0 }, + "thread_metadata": { + "$ref": "#/components/schemas/threadMetadata" + }, + "member_count": { + "type": "integer" + }, + "message_count": { + "type": "integer" + }, + "total_message_sent": { + "type": "integer" + }, "position": { "description": "Must be calculated Channel.calculatePosition", "type": "integer" @@ -9853,6 +9871,36 @@ "user_id" ] }, + "threadMetadata": { + "type": "object", + "properties": { + "archived": { + "type": "boolean" + }, + "auto_archive_duration": { + "type": "integer" + }, + "archive_timestamp": { + "type": "string" + }, + "locked": { + "type": "boolean" + }, + "invitable": { + "type": "boolean" + }, + "create_timestamp": { + "type": "string" + } + }, + "required": [ + "archive_timestamp", + "archived", + "auto_archive_duration", + "create_timestamp", + "locked" + ] + }, "Attachment": { "type": "object", "properties": { diff --git a/assets/schemas.json b/assets/schemas.json index 46a3693..d1017ec 100644 --- a/assets/schemas.json +++ b/assets/schemas.json @@ -2657,6 +2657,9 @@ "$ref": "#/definitions/Webhook" } }, + "member_count": { + "type": "integer" + }, "roles": { "type": "array", "items": { @@ -2753,9 +2756,6 @@ "max_video_channel_users": { "type": "integer" }, - "member_count": { - "type": "integer" - }, "presence_count": { "type": "integer" }, @@ -7467,6 +7467,12 @@ "channel": { "$ref": "#/definitions/Channel" }, + "thread_id": { + "type": "string" + }, + "thread": { + "$ref": "#/definitions/Channel" + }, "guild_id": { "type": "string" }, @@ -7843,6 +7849,18 @@ "type": "integer", "default": 0 }, + "thread_metadata": { + "$ref": "#/definitions/threadMetadata" + }, + "member_count": { + "type": "integer" + }, + "message_count": { + "type": "integer" + }, + "total_message_sent": { + "type": "integer" + }, "position": { "description": "Must be calculated Channel.calculatePosition", "type": "integer" @@ -10418,6 +10436,38 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "threadMetadata": { + "type": "object", + "properties": { + "archived": { + "type": "boolean" + }, + "auto_archive_duration": { + "type": "integer" + }, + "archive_timestamp": { + "type": "string" + }, + "locked": { + "type": "boolean" + }, + "invitable": { + "type": "boolean" + }, + "create_timestamp": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "archive_timestamp", + "archived", + "auto_archive_duration", + "create_timestamp", + "locked" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, "Attachment": { "type": "object", "properties": { diff --git a/src/schemas/api/channels/Channel.ts b/src/schemas/api/channels/Channel.ts index 1065319..99846e5 100644 --- a/src/schemas/api/channels/Channel.ts +++ b/src/schemas/api/channels/Channel.ts @@ -37,6 +37,14 @@ member = 1, group = 2, } +export interface threadMetadata { + archived: boolean; + auto_archive_duration: number; + archive_timestamp: string; + locked: boolean; + invitable?: boolean; + create_timestamp: string; //Discord docs say this is optional, but it's only for after a certain date so it's not +} export interface DMChannel extends Omit { type: ChannelType.DM | ChannelType.GROUP_DM; diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts index a250758..1d52fa0 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -31,7 +31,7 @@ import { VoiceState } from "./VoiceState"; import { Webhook } from "./Webhook"; import { Member } from "./Member"; -import { ChannelPermissionOverwrite, ChannelPermissionOverwriteType, ChannelType, PublicUserProjection } from "@spacebar/schemas"; +import { ChannelPermissionOverwrite, ChannelPermissionOverwriteType, ChannelType, PublicUserProjection, threadMetadata } from "@spacebar/schemas"; @Entity({ name: "channels", @@ -152,6 +152,18 @@ @Column({ nullable: true }) default_thread_rate_limit_per_user?: number = 0; + @Column({ type: "simple-json", nullable: true }) + thread_metadata?: threadMetadata; + + @Column({ nullable: true }) + member_count?: number; + + @Column({ nullable: true }) + message_count?: number; + + @Column({ nullable: true }) + total_message_sent?: number; + /** Must be calculated Channel.calculatePosition */ position: number; diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts index 508ffd8..c38f60a 100644 --- a/src/util/entities/Message.ts +++ b/src/util/entities/Message.ts @@ -49,6 +49,16 @@ channel: Channel; @Column({ nullable: true }) + @RelationId((message: Message) => message.thread) + thread_id?: string; + + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, { + onDelete: "CASCADE", + }) + thread?: Channel; + + @Column({ nullable: true }) @RelationId((message: Message) => message.guild) guild_id?: string; diff --git a/src/util/migrations/postgres/1764609924756-threads.ts b/src/util/migrations/postgres/1764609924756-threads.ts new file mode 100644 index 0000000..efa2ce7 --- /dev/null +++ b/src/util/migrations/postgres/1764609924756-threads.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Threads1764609924756 implements MigrationInterface { + name = "Threads1764609924756"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "messages" DROP CONSTRAINT "FK_bb3af7f695d50083e6523290d41"`); + await queryRunner.query(`ALTER TABLE "channels" DROP COLUMN "total_message_sent"`); + await queryRunner.query(`ALTER TABLE "channels" ADD "total_messsage_sent" integer`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "thread_metadata" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "member_count" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "message_count" DROP NOT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "message_count" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "member_count" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "thread_metadata" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" DROP COLUMN "total_messsage_sent"`); + await queryRunner.query(`ALTER TABLE "channels" ADD "total_message_sent" integer NOT NULL`); + await queryRunner.query( + `ALTER TABLE "messages" ADD CONSTRAINT "FK_bb3af7f695d50083e6523290d41" FOREIGN KEY ("thread_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } +} diff --git a/src/util/migrations/postgres/1764610059742-threadtypo.ts b/src/util/migrations/postgres/1764610059742-threadtypo.ts new file mode 100644 index 0000000..2fe2a98 --- /dev/null +++ b/src/util/migrations/postgres/1764610059742-threadtypo.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Threadtypo1764610059742 implements MigrationInterface { + name = "Threadtypo1764610059742"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "messages" DROP CONSTRAINT "FK_bb3af7f695d50083e6523290d41"`); + await queryRunner.query(`ALTER TABLE "channels" DROP COLUMN "total_message_sent"`); + await queryRunner.query(`ALTER TABLE "channels" ADD "total_messsage_sent" integer`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "thread_metadata" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "member_count" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "message_count" DROP NOT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "message_count" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "member_count" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" ALTER COLUMN "thread_metadata" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "channels" DROP COLUMN "total_messsage_sent"`); + await queryRunner.query(`ALTER TABLE "channels" ADD "total_message_sent" integer NOT NULL`); + await queryRunner.query( + `ALTER TABLE "messages" ADD CONSTRAINT "FK_bb3af7f695d50083e6523290d41" FOREIGN KEY ("thread_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } +}