diff --git a/package.json b/package.json index c06a6f1b5..c3f4bedb9 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,7 @@ "_moduleAliases": { "@spacebar/api": "dist/api", "@spacebar/cdn": "dist/cdn", + "@spacebar/database": "dist/database", "@spacebar/extensions": "dist/extensions", "@spacebar/gateway": "dist/gateway", "@spacebar/util": "dist/util", diff --git a/src/api/Server.ts b/src/api/Server.ts index f48f72200..adc2429be 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -21,13 +21,14 @@ import { Request, Response, Router } from "express"; import morgan from "morgan"; import { Server, ServerOptions } from "lambert-server/Server"; import { red } from "picocolors"; -import { Config, ConnectionConfig, ConnectionLoader, Email, JSONReplacer, WebAuthn, initDatabase, initEvent, registerRoutes, getDatabase, getRevInfoOrFail } from "@spacebar/util"; -import { Authentication, CORS, ImageProxy, BodyParser, ErrorHandler, initRateLimits, initTranslation } from "./middlewares"; -import { initInstance } from "./util/handlers/Instance"; -import { route } from "./util"; +import { getDatabase, initDatabase } from "@spacebar/database"; +import { Config, ConnectionConfig, ConnectionLoader, Email, JSONReplacer, WebAuthn, initEvent, registerRoutes, getRevInfoOrFail } from "@spacebar/util"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; import { BcryptWorkerPool } from "../util/util/workers/bcrypt/BcryptWorkerPool"; +import { Authentication, CORS, ImageProxy, BodyParser, ErrorHandler, initRateLimits, initTranslation } from "./middlewares"; +import { initInstance } from "./util/handlers/Instance"; +import { route } from "./util"; const ASSETS_FOLDER = path.join(__dirname, "..", "..", "assets"); const PUBLIC_ASSETS_FOLDER = path.join(ASSETS_FOLDER, "public"); diff --git a/src/api/routes/-/healthz.ts b/src/api/routes/-/healthz.ts index 90f6054d5..b98eb9456 100644 --- a/src/api/routes/-/healthz.ts +++ b/src/api/routes/-/healthz.ts @@ -18,7 +18,7 @@ import { Router, Response, Request } from "express"; import { route } from "@spacebar/api"; -import { getDatabase } from "@spacebar/util"; +import { getDatabase } from "@spacebar/database"; const router = Router({ mergeParams: true }); diff --git a/src/api/routes/-/readyz.ts b/src/api/routes/-/readyz.ts index 90f6054d5..b98eb9456 100644 --- a/src/api/routes/-/readyz.ts +++ b/src/api/routes/-/readyz.ts @@ -18,7 +18,7 @@ import { Router, Response, Request } from "express"; import { route } from "@spacebar/api"; -import { getDatabase } from "@spacebar/util"; +import { getDatabase } from "@spacebar/database"; const router = Router({ mergeParams: true }); diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index 674b74c61..4e6d7316b 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -16,7 +16,10 @@ along with this program. If not, see . */ +import { HTTPError } from "lambert-server/HTTPError"; +import { Equal, In, Or } from "typeorm"; import { fillMessageUrlEmbeds, randomString } from "@spacebar/api"; +import { getDatabase } from "@spacebar/database"; import { mathLogBase, arrayDistributeSequentially } from "@spacebar/extensions"; import { Application, @@ -28,7 +31,6 @@ import { emitEvent, EVERYONE_MENTION, FieldErrors, - getDatabase, getPermission, getRights, Guild, @@ -53,8 +55,6 @@ import { USER_MENTION, Webhook, } from "@spacebar/util"; -import { HTTPError } from "lambert-server/HTTPError"; -import { Equal, In, Or } from "typeorm"; import { ActionRowComponent, BaseMessageComponents, diff --git a/src/apply-migrations.ts b/src/apply-migrations.ts index 0a540e732..3ae453cac 100644 --- a/src/apply-migrations.ts +++ b/src/apply-migrations.ts @@ -26,7 +26,7 @@ config({ quiet: true }); process.env.DB_LOGGING = "true"; -import { closeDatabase, initDatabase } from "@spacebar/util"; +import { closeDatabase, initDatabase } from "@spacebar/database"; async function main() { let success = false; diff --git a/src/bundle/Server.ts b/src/bundle/Server.ts index c396d1000..8c2b07879 100644 --- a/src/bundle/Server.ts +++ b/src/bundle/Server.ts @@ -23,10 +23,11 @@ import morgan from "morgan"; import express from "express"; import { green, bold } from "picocolors"; import * as Api from "@spacebar/api"; -import * as Gateway from "@spacebar/gateway"; -import * as Webrtc from "@spacebar/webrtc"; import { CDNServer } from "@spacebar/cdn"; -import { Config, initDatabase } from "@spacebar/util"; +import { initDatabase } from "@spacebar/database"; +import * as Gateway from "@spacebar/gateway"; +import { Config } from "@spacebar/util"; +import * as Webrtc from "@spacebar/webrtc"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; diff --git a/src/cdn/Server.ts b/src/cdn/Server.ts index 0bd6a8f47..1c0f7802b 100644 --- a/src/cdn/Server.ts +++ b/src/cdn/Server.ts @@ -19,12 +19,13 @@ import path from "node:path"; import morgan from "morgan"; import { Server, ServerOptions } from "lambert-server/Server"; -import { Attachment, Config, initDatabase, registerRoutes } from "@spacebar/util"; import { CORS, BodyParser } from "@spacebar/api"; -import guildProfilesRoute from "./routes/guild-profiles"; -import { storage } from "./util"; +import { initDatabase } from "@spacebar/database"; +import { Attachment, Config, registerRoutes } from "@spacebar/util"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; +import guildProfilesRoute from "./routes/guild-profiles"; +import { storage } from "./util"; export type CDNServerOptions = ServerOptions; diff --git a/src/util/util/Database.ts b/src/database/Database.ts similarity index 97% rename from src/util/util/Database.ts rename to src/database/Database.ts index ecbb7110c..adafeac03 100644 --- a/src/util/util/Database.ts +++ b/src/database/Database.ts @@ -21,9 +21,9 @@ import path from "node:path"; import { green, red, yellow } from "picocolors"; import { DataSource } from "typeorm"; // noinspection ES6PreferShortImport -import { ConfigEntity } from "../entities/Config"; +import { ConfigEntity } from "../util/entities/Config"; import fs from "node:fs"; -import { ProcessLifecycle } from "./ProcessLifecycle"; +import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; // UUID extension option is only supported with postgres // We want to generate all id's with Snowflakes that's why we have our own BaseEntity class diff --git a/src/database/index.ts b/src/database/index.ts new file mode 100644 index 000000000..0ceebea87 --- /dev/null +++ b/src/database/index.ts @@ -0,0 +1,19 @@ +/* + 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 . +*/ + +export * from "./Database"; diff --git a/src/gateway/Server.ts b/src/gateway/Server.ts index 430419752..f01976113 100644 --- a/src/gateway/Server.ts +++ b/src/gateway/Server.ts @@ -19,12 +19,13 @@ import http from "node:http"; import { setInterval } from "node:timers"; import ws from "ws"; -import { checkToken, Config, initDatabase, initEvent, Rights } from "@spacebar/util"; import { randomString } from "@spacebar/api"; // TODO: move to util -import { Connection, openConnections } from "./events/Connection"; -import { cleanupOnStartup } from "./util"; +import { initDatabase } from "@spacebar/database"; +import { checkToken, Config, initEvent, Rights } from "@spacebar/util"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; +import { Connection, openConnections } from "./events/Connection"; +import { cleanupOnStartup } from "./util"; export class Server { public ws: ws.Server; diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index 74907f451..b4b127e50 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -16,8 +16,11 @@ along with this program. If not, see . */ +import { In, Not } from "typeorm"; +import { PreloadedUserSettings } from "discord-protos"; import { Capabilities, CLOSECODES, OPCODES, Payload, Send, setupListener, WebSocket } from "@spacebar/gateway"; import { arrayGroupBy } from "@spacebar/extensions"; +import { getDatabase } from "@spacebar/database"; import { Application, Channel, @@ -29,7 +32,6 @@ import { Emoji, EVENTEnum, generateToken, - getDatabase, Guild, GuildOrUnavailable, Intents, @@ -57,11 +59,9 @@ import { UserSettingsProtos, VoiceState, } from "@spacebar/util"; -import { check } from "./instanceOf"; -import { In, Not } from "typeorm"; -import { PreloadedUserSettings } from "discord-protos"; import { ChannelType, DefaultUserGuildSettings, DMChannel, IdentifySchema, PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType } from "@spacebar/schemas"; import { randomString } from "@spacebar/api"; +import { check } from "./instanceOf"; // TODO: user sharding // TODO: check privileged intents, if defined in the config diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts index 0080e589c..d8900d9e7 100644 --- a/src/gateway/opcodes/LazyRequest.ts +++ b/src/gateway/opcodes/LazyRequest.ts @@ -16,12 +16,13 @@ along with this program. If not, see . */ -import { arrayPartition } from "@spacebar/extensions"; -import { getDatabase, getPermission, listenEvent, Member, Role, Session, User, Presence, Channel, Permissions, getMostRelevantSession } from "@spacebar/util"; -import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send } from "@spacebar/gateway"; import murmur from "murmurhash-js/murmurhash3_gc"; -import { check } from "./instanceOf"; +import { getDatabase } from "@spacebar/database"; +import { arrayPartition } from "@spacebar/extensions"; +import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send } from "@spacebar/gateway"; import { LazyRequestSchema } from "@spacebar/schemas"; +import { getPermission, listenEvent, Member, Role, Session, User, Presence, Channel, Permissions, getMostRelevantSession } from "@spacebar/util"; +import { check } from "./instanceOf"; // TODO: only show roles/members that have access to this channel // TODO: config: to list all members (even those who are offline) sorted by role, or just those who are online diff --git a/src/gateway/opcodes/RequestGuildMembers.ts b/src/gateway/opcodes/RequestGuildMembers.ts index fbb249d30..88b24d6c2 100644 --- a/src/gateway/opcodes/RequestGuildMembers.ts +++ b/src/gateway/opcodes/RequestGuildMembers.ts @@ -16,11 +16,12 @@ along with this program. If not, see . */ -import { Config, DateBuilder, getDatabase, getPermission, GuildMembersChunkEvent, Member, Presence, Session } from "@spacebar/util"; -import { WebSocket, Payload, OPCODES, Send, handleOffloadedGatewayRequest } from "@spacebar/gateway"; -import { check } from "./instanceOf"; import { FindManyOptions, ILike, In, MoreThan } from "typeorm"; +import { getDatabase } from "@spacebar/database"; +import { WebSocket, Payload, OPCODES, Send, handleOffloadedGatewayRequest } from "@spacebar/gateway"; import { RequestGuildMembersSchema } from "@spacebar/schemas"; +import { Config, DateBuilder, getPermission, GuildMembersChunkEvent, Member, Presence, Session } from "@spacebar/util"; +import { check } from "./instanceOf"; export async function onRequestGuildMembers(this: WebSocket, { d }: Payload) { const startTime = Date.now(); diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts index bcebca0f3..a64138adb 100644 --- a/src/util/entities/BaseClass.ts +++ b/src/util/entities/BaseClass.ts @@ -16,8 +16,9 @@ along with this program. If not, see . */ -import { BaseEntity, BeforeInsert, BeforeUpdate, Column, ColumnOptions, FindOptionsWhere, PrimaryColumn } from "typeorm"; -import { Snowflake, getDatabase } from "../util"; +import { BaseEntity, BeforeInsert, BeforeUpdate, FindOptionsWhere, PrimaryColumn } from "typeorm"; +import { getDatabase } from "@spacebar/database"; +import { Snowflake } from "../util"; import { OrmUtils } from "../imports"; import { annotationsKey } from "../util/Decorators"; diff --git a/src/util/util/index.ts b/src/util/util/index.ts index b6f72d9bd..d4f21d618 100644 --- a/src/util/util/index.ts +++ b/src/util/util/index.ts @@ -22,7 +22,6 @@ export * from "./BitField"; export * from "./cdn"; export * from "./Config"; export * from "./Constants"; -export * from "./Database"; export * from "./DateBuilder"; export * from "./email"; export * from "./ElapsedTime"; diff --git a/src/webrtc/Server.ts b/src/webrtc/Server.ts index f3e8e2c26..d58c249fc 100644 --- a/src/webrtc/Server.ts +++ b/src/webrtc/Server.ts @@ -19,11 +19,12 @@ import http from "node:http"; import ws from "ws"; import { green, yellow } from "picocolors"; -import { Config, initDatabase, initEvent } from "@spacebar/util"; -import { Connection } from "./events/Connection"; -import { loadWebRtcLibrary, mediaServer, WRTC_PORT_MAX, WRTC_PORT_MIN, WRTC_PUBLIC_IP } from "./util"; +import { initDatabase } from "@spacebar/database"; +import { Config, initEvent } from "@spacebar/util"; import { ProcessLifecycle } from "../util/util/ProcessLifecycle"; import { Monitoring } from "../util/monitoring/Monitoring"; +import { Connection } from "./events/Connection"; +import { loadWebRtcLibrary, mediaServer, WRTC_PORT_MAX, WRTC_PORT_MIN, WRTC_PUBLIC_IP } from "./util"; export class Server { public ws: ws.Server; diff --git a/tsconfig.json b/tsconfig.json index 19e71deb6..6f96802f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,6 +34,8 @@ //"*": ["./src/*"], "@spacebar/api": ["./src/api"], // Required for stable tsc, typescript-go doesn't need this "@spacebar/api*": ["./src/api*"], + "@spacebar/database": ["./src/database"], // Required for stable tsc, typescript-go doesn't need this + "@spacebar/database*": ["./src/database*"], "@spacebar/extensions": ["./src/extensions"], // Required for stable tsc, typescript-go doesn't need this "@spacebar/extensions*": ["./src/extensions*"], "@spacebar/gateway": ["./src/gateway"], // Required for stable tsc, typescript-go doesn't need this