refactor: 🚚 Organize code into sub-packages, instead of a single large package

This commit is contained in:
Jesse Wierzbinski 2025-06-15 04:38:20 +02:00
parent 79742f47dc
commit a6d3ebbeef
No known key found for this signature in database
366 changed files with 942 additions and 833 deletions

View file

@ -99,7 +99,15 @@
"noCommonJs": "warn", "noCommonJs": "warn",
"noExportedImports": "warn", "noExportedImports": "warn",
"noSubstr": "warn", "noSubstr": "warn",
"useTrimStartEnd": "warn" "useTrimStartEnd": "warn",
"noRestrictedImports": {
"options": {
"paths": {
"~/packages/": "Use the appropriate package instead of importing from the packages directory directly."
}
},
"level": "error"
}
}, },
"performance": { "performance": {
"noDynamicNamespaceImportAccess": "warn" "noDynamicNamespaceImportAccess": "warn"

333
bun.lock
View file

@ -4,84 +4,111 @@
"": { "": {
"name": "versia-server", "name": "versia-server",
"dependencies": { "dependencies": {
"@bull-board/api": "^6.10.1", "@bull-board/api": "catalog:",
"@bull-board/hono": "^6.10.1", "@bull-board/hono": "catalog:",
"@clerc/plugin-completions": "^0.44.0", "@clerc/plugin-completions": "catalog:",
"@clerc/plugin-friendly-error": "^0.44.0", "@clerc/plugin-friendly-error": "catalog:",
"@clerc/plugin-help": "^0.44.0", "@clerc/plugin-help": "catalog:",
"@clerc/plugin-not-found": "^0.44.0", "@clerc/plugin-not-found": "catalog:",
"@clerc/plugin-version": "^0.44.0", "@clerc/plugin-version": "catalog:",
"@hackmd/markdown-it-task-lists": "^2.1.4", "@hackmd/markdown-it-task-lists": "catalog:",
"@hono/zod-validator": "^0.7.0", "@hono/zod-validator": "catalog:",
"@inquirer/confirm": "^5.1.12", "@inquirer/confirm": "catalog:",
"@logtape/file": "^0.12.0", "@logtape/file": "catalog:",
"@logtape/logtape": "^0.12.0", "@logtape/logtape": "catalog:",
"@scalar/hono-api-reference": "^0.9.4", "@scalar/hono-api-reference": "catalog:",
"@sentry/bun": "^9.29.0", "@sentry/bun": "catalog:",
"@versia-server/config": "workspace:*",
"@versia/client": "workspace:*", "@versia/client": "workspace:*",
"@versia/kit": "workspace:*", "@versia/kit": "workspace:*",
"@versia/sdk": "workspace:*", "@versia/sdk": "workspace:*",
"altcha-lib": "^1.3.0", "altcha-lib": "catalog:",
"blurhash": "^2.0.5", "blurhash": "catalog:",
"bullmq": "^5.53.3", "bullmq": "catalog:",
"chalk": "^5.4.1", "chalk": "catalog:",
"clerc": "^0.44.0", "clerc": "catalog:",
"confbox": "^0.2.2", "confbox": "catalog:",
"drizzle-orm": "^0.44.2", "drizzle-orm": "catalog:",
"feed": "^5.1.0", "feed": "catalog:",
"hono": "^4.7.11", "hono": "catalog:",
"hono-openapi": "^0.4.8", "hono-openapi": "catalog:",
"hono-rate-limiter": "^0.4.2", "hono-rate-limiter": "catalog:",
"html-to-text": "^9.0.5", "html-to-text": "catalog:",
"ioredis": "^5.6.1", "ioredis": "catalog:",
"ip-matching": "^2.1.2", "ip-matching": "catalog:",
"iso-639-1": "^3.1.5", "iso-639-1": "^3.1.5",
"jose": "^6.0.11", "jose": "catalog:",
"linkify-html": "^4.3.1", "linkify-html": "catalog:",
"linkify-string": "^4.3.1", "linkify-string": "catalog:",
"linkifyjs": "^4.3.1", "linkifyjs": "catalog:",
"magic-regexp": "^0.10.0", "magic-regexp": "catalog:",
"markdown-it": "^14.1.0", "markdown-it": "catalog:",
"markdown-it-anchor": "^9.2.0", "markdown-it-anchor": "catalog:",
"markdown-it-container": "^4.0.0", "markdown-it-container": "catalog:",
"markdown-it-mathjax3": "^4.3.2", "markdown-it-mathjax3": "catalog:",
"markdown-it-toc-done-right": "^4.2.0", "markdown-it-toc-done-right": "catalog:",
"mime-types": "^3.0.1", "mime-types": "catalog:",
"mitata": "^1.0.34", "mitata": "catalog:",
"oauth4webapi": "^3.5.2", "oauth4webapi": "catalog:",
"ora": "^8.2.0", "ora": "catalog:",
"qs": "^6.14.0", "qs": "catalog:",
"sharp": "^0.34.2", "sharp": "catalog:",
"sonic-channel": "^1.3.1", "sonic-channel": "catalog:",
"string-comparison": "^1.3.0", "string-comparison": "catalog:",
"stringify-entities": "^4.0.4", "stringify-entities": "catalog:",
"unicode-emoji-json": "^0.8.0", "unicode-emoji-json": "catalog:",
"uqr": "^0.1.2", "uqr": "catalog:",
"web-push": "^3.6.7", "web-push": "catalog:",
"xss": "^1.0.15", "xss": "catalog:",
"youch": "^4.1.0-beta.7", "youch": "catalog:",
"zod": "^3.25.64", "zod": "catalog:",
"zod-openapi": "^4.2.4", "zod-openapi": "catalog:",
"zod-validation-error": "^3.5.0", "zod-validation-error": "catalog:",
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.0.0-beta.5", "@types/bun": "catalog:",
"@types/bun": "^1.2.16", "@types/html-to-text": "catalog:",
"@types/html-to-text": "^9.0.4", "@types/markdown-it-container": "catalog:",
"@types/markdown-it-container": "^2.0.10", "@types/mime-types": "catalog:",
"@types/mime-types": "^3.0.1", "@types/qs": "catalog:",
"@types/qs": "^6.14.0", "@types/web-push": "catalog:",
"@types/web-push": "^3.6.4", "bun-bagel": "catalog:",
"bun-bagel": "^1.2.0", "drizzle-kit": "catalog:",
"drizzle-kit": "^0.31.1", "markdown-it-image-figures": "catalog:",
"markdown-it-image-figures": "^2.1.1", "ts-prune": "catalog:",
"ts-prune": "^0.10.3", "typescript": "catalog:",
"typescript": "^5.8.3", "vitepress": "catalog:",
"vitepress": "^1.6.3", "vitepress-plugin-tabs": "catalog:",
"vitepress-plugin-tabs": "^0.7.1", "vitepress-sidebar": "catalog:",
"vitepress-sidebar": "^1.31.1", "vue": "catalog:",
"vue": "^3.5.16", "zod-to-json-schema": "catalog:",
"zod-to-json-schema": "^3.24.5", },
},
"packages/api": {
"name": "@versia-server/api",
"version": "0.9.0-alpha.0",
"dependencies": {
"@logtape/logtape": "catalog:",
"@scalar/hono-api-reference": "catalog:",
"@versia-server/config": "workspace:*",
"@versia/client": "workspace:*",
"@versia/kit": "workspace:*",
"@versia/sdk": "workspace:*",
"bun-bagel": "catalog:",
"chalk": "catalog:",
"drizzle-orm": "catalog:",
"hono": "catalog:",
"hono-openapi": "catalog:",
"hono-rate-limiter": "catalog:",
"ip-matching": "catalog:",
"iso-639-1": "catalog:",
"jose": "catalog:",
"sharp": "catalog:",
"string-comparison": "catalog:",
"unicode-emoji-json": "catalog:",
"youch": "catalog:",
"zod": "catalog:",
"zod-openapi": "catalog:",
}, },
}, },
"packages/client": { "packages/client": {
@ -89,40 +116,150 @@
"version": "0.2.0-alpha.4", "version": "0.2.0-alpha.4",
"dependencies": { "dependencies": {
"@badgateway/oauth2-client": "^3.0.0", "@badgateway/oauth2-client": "^3.0.0",
"iso-639-1": "^3.1.5", "iso-639-1": "catalog:",
"magic-regexp": "^0.10.0", "magic-regexp": "catalog:",
"zod": "^3.24.2", "zod": "catalog:",
"zod-openapi": "^4.2.4", "zod-openapi": "catalog:",
},
},
"packages/config": {
"name": "@versia-server/config",
"version": "0.0.1",
"dependencies": {
"@versia/client": "workspace:*",
"chalk": "catalog:",
"confbox": "catalog:",
"iso-639-1": "catalog:",
"mime-types": "catalog:",
"web-push": "catalog:",
"zod": "catalog:",
"zod-to-json-schema": "catalog:",
"zod-validation-error": "catalog:",
}, },
}, },
"packages/plugin-kit": { "packages/plugin-kit": {
"name": "@versia/kit", "name": "@versia/kit",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"drizzle-orm": "^0.44.2", "@logtape/logtape": "catalog:",
"hono": "^4.7.7", "@versia-server/config": "workspace:*",
"mitt": "^3.0.1", "@versia/client": "workspace:*",
"zod": "^3.24.2", "@versia/sdk": "workspace:*",
"zod-to-json-schema": "^3.24.5", "altcha-lib": "catalog:",
"zod-validation-error": "^3.4.0", "chalk": "catalog:",
"drizzle-orm": "catalog:",
"hono": "catalog:",
"hono-openapi": "catalog:",
"html-to-text": "catalog:",
"magic-regexp": "catalog:",
"mitt": "catalog:",
"sharp": "catalog:",
"zod": "catalog:",
"zod-to-json-schema": "catalog:",
"zod-validation-error": "catalog:",
}, },
}, },
"packages/sdk": { "packages/sdk": {
"name": "@versia/sdk", "name": "@versia/sdk",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"magic-regexp": "^0.10.0", "magic-regexp": "catalog:",
"mime-types": "^3.0.1", "mime-types": "catalog:",
"zod": "^3.24.2", "zod": "catalog:",
},
},
"packages/worker": {
"name": "@versia-server/worker",
"version": "0.9.0-alpha.0",
"dependencies": {
"@logtape/logtape": "catalog:",
"@versia-server/config": "workspace:*",
"@versia/kit": "workspace:*",
"chalk": "catalog:",
}, },
}, },
}, },
"trustedDependencies": [ "trustedDependencies": [
"sharp", "sharp",
"esbuild", "esbuild",
"@biomejs/biome",
"msgpackr-extract", "msgpackr-extract",
], ],
"catalog": {
"@biomejs/biome": "2.0.0-beta.5",
"@bull-board/api": "^6.10.1",
"@bull-board/hono": "^6.10.1",
"@clerc/plugin-completions": "^0.44.0",
"@clerc/plugin-friendly-error": "^0.44.0",
"@clerc/plugin-help": "^0.44.0",
"@clerc/plugin-not-found": "^0.44.0",
"@clerc/plugin-version": "^0.44.0",
"@hackmd/markdown-it-task-lists": "^2.1.4",
"@hono/zod-validator": "^0.7.0",
"@inquirer/confirm": "^5.1.12",
"@logtape/file": "^0.12.0",
"@logtape/logtape": "^0.12.0",
"@scalar/hono-api-reference": "^0.9.4",
"@sentry/bun": "^9.29.0",
"@types/bun": "^1.2.16",
"@types/html-to-text": "^9.0.4",
"@types/markdown-it-container": "^2.0.10",
"@types/mime-types": "^3.0.1",
"@types/qs": "^6.14.0",
"@types/web-push": "^3.6.4",
"altcha-lib": "^1.3.0",
"blurhash": "^2.0.5",
"bullmq": "^5.53.3",
"bun-bagel": "^1.2.0",
"chalk": "^5.4.1",
"clerc": "^0.44.0",
"confbox": "^0.2.2",
"drizzle-kit": "^0.31.1",
"drizzle-orm": "^0.44.2",
"feed": "^5.1.0",
"hono": "^4.7.11",
"hono-openapi": "^0.4.8",
"hono-rate-limiter": "^0.4.2",
"html-to-text": "^9.0.5",
"ioredis": "^5.6.1",
"ip-matching": "^2.1.2",
"iso-639-1": "^3.1.5",
"jose": "^6.0.11",
"linkify-html": "^4.3.1",
"linkify-string": "^4.3.1",
"linkifyjs": "^4.3.1",
"magic-regexp": "^0.10.0",
"markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.2.0",
"markdown-it-container": "^4.0.0",
"markdown-it-image-figures": "^2.1.1",
"markdown-it-mathjax3": "^4.3.2",
"markdown-it-toc-done-right": "^4.2.0",
"mime-types": "^3.0.1",
"mitata": "^1.0.34",
"mitt": "^3.0.1",
"oauth4webapi": "^3.5.2",
"ora": "^8.2.0",
"qs": "^6.14.0",
"sharp": "^0.34.2",
"sonic-channel": "^1.3.1",
"string-comparison": "^1.3.0",
"stringify-entities": "^4.0.4",
"ts-prune": "^0.10.3",
"typescript": "^5.8.3",
"unicode-emoji-json": "^0.8.0",
"uqr": "^0.1.2",
"vitepress": "^1.6.3",
"vitepress-plugin-tabs": "^0.7.1",
"vitepress-sidebar": "^1.31.1",
"vue": "^3.5.16",
"web-push": "^3.6.7",
"xss": "^1.0.15",
"youch": "^4.1.0-beta.7",
"zod": "^3.25.64",
"zod-openapi": "^4.2.4",
"zod-to-json-schema": "^3.24.5",
"zod-validation-error": "^3.5.0",
},
"packages": { "packages": {
"@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="],
@ -174,24 +311,6 @@
"@badgateway/oauth2-client": ["@badgateway/oauth2-client@3.2.0", "", {}, "sha512-EHsoV6oLHot7HeYkIoSxCZApNgBjwNo1OTV9kXIDnmijGAshlVkJreVAAtexFn+sfDKPE0JW5SCPYJV1y4IoMg=="], "@badgateway/oauth2-client": ["@badgateway/oauth2-client@3.2.0", "", {}, "sha512-EHsoV6oLHot7HeYkIoSxCZApNgBjwNo1OTV9kXIDnmijGAshlVkJreVAAtexFn+sfDKPE0JW5SCPYJV1y4IoMg=="],
"@biomejs/biome": ["@biomejs/biome@2.0.0-beta.5", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.0.0-beta.5", "@biomejs/cli-darwin-x64": "2.0.0-beta.5", "@biomejs/cli-linux-arm64": "2.0.0-beta.5", "@biomejs/cli-linux-arm64-musl": "2.0.0-beta.5", "@biomejs/cli-linux-x64": "2.0.0-beta.5", "@biomejs/cli-linux-x64-musl": "2.0.0-beta.5", "@biomejs/cli-win32-arm64": "2.0.0-beta.5", "@biomejs/cli-win32-x64": "2.0.0-beta.5" }, "bin": { "biome": "bin/biome" } }, "sha512-1ldO4AepieVvg4aLi1ubZkA7NsefQT2UTNssbJbDiQTGem8kCHx/PZCwLxIR6UzFpGIjh0xsDzivyVvhnmqmuA=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.0.0-beta.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pnJiaoDpwGo+ctGkMu4POcO8jgOgCErBdYbhutr+K9rxxJS+TlHLr0LR91GCEWbGV2O1oyZRFQcW21rYFoak4w=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.0.0-beta.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-WwEZpqcmsNoFpZkUFNQcbZo52WK4hLGQ0vZk3PQ8JlZ55gJsHiyhtv6aem6fVlyVCvZgpsC0sYPLE3VvFVKNAQ=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.0.0-beta.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAF1de+Ki0vnq14NwDXouKkAR/iviyMNrUngSHjTGFC4z8XGVEfIw0ZMSm7fAdJZ5fAWodt9HiYmEAVs5EtHQg=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.0.0-beta.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-4vxNkYx1uEt211W8hLdXddc7icRHQgYENb72g6uTd/tLVPSBvIwqUAxAOkU+9Ai1E/8R4sWy7HIxREgpuFgbNA=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.0.0-beta.5", "", { "os": "linux", "cpu": "x64" }, "sha512-I0Pt1VHeL1mN8G7ZwV2u9AfzBd5ZKfbvHUI4x2wETUZbwcQlAu/nEzEa2LUe5HqSmnctTR36ig7RkkM9qbmIrA=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.0.0-beta.5", "", { "os": "linux", "cpu": "x64" }, "sha512-nUeKGO517GtRCxziVD9les1HiCs2s2/WIVITMN9+9RRuLOko8r+T77E8ZXEmlfLOfOIOeE6z62WITqei3oNccA=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.0.0-beta.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-YXW6hgbrgBcWQ1SLO69ypWlluPchgQV5C1lTG4xOcBUWdCsfYuQirM64S6Dov7SFPqsMIoFC6LlQRW+n8qAyiA=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.0.0-beta.5", "", { "os": "win32", "cpu": "x64" }, "sha512-N7Yby52BJmvEdst1iMbclE5hxxefboaXKRJLm1tLfBYr4FeuoCe6j8HdiQSwhCRdIUGFFqBLaDXh//LLF6EReA=="],
"@bull-board/api": ["@bull-board/api@6.10.1", "", { "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { "@bull-board/ui": "6.10.1" } }, "sha512-VPkZa2XZI2Wk2MqK1XyiiS+tOhNan54mnm2fpv2KA0fdZ92mQqNjhKkOpsykhQv9XUEc8cCRlZqGxf67YCMJbQ=="], "@bull-board/api": ["@bull-board/api@6.10.1", "", { "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { "@bull-board/ui": "6.10.1" } }, "sha512-VPkZa2XZI2Wk2MqK1XyiiS+tOhNan54mnm2fpv2KA0fdZ92mQqNjhKkOpsykhQv9XUEc8cCRlZqGxf67YCMJbQ=="],
"@bull-board/hono": ["@bull-board/hono@6.10.1", "", { "dependencies": { "@bull-board/api": "6.10.1", "@bull-board/ui": "6.10.1", "ejs": "^3.1.10" }, "peerDependencies": { "hono": "^4" } }, "sha512-2I9BUS7jbtQ4tCKOJdVKQn6uW8MXJKUGIhHLK2r4X8kiXZvk2I7jjt0KZ4VNyF9nfoBblgX5WemxE4sU61kGGg=="], "@bull-board/hono": ["@bull-board/hono@6.10.1", "", { "dependencies": { "@bull-board/api": "6.10.1", "@bull-board/ui": "6.10.1", "ejs": "^3.1.10" }, "peerDependencies": { "hono": "^4" } }, "sha512-2I9BUS7jbtQ4tCKOJdVKQn6uW8MXJKUGIhHLK2r4X8kiXZvk2I7jjt0KZ4VNyF9nfoBblgX5WemxE4sU61kGGg=="],
@ -570,6 +689,12 @@
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"@versia-server/api": ["@versia-server/api@workspace:packages/api"],
"@versia-server/config": ["@versia-server/config@workspace:packages/config"],
"@versia-server/worker": ["@versia-server/worker@workspace:packages/worker"],
"@versia/client": ["@versia/client@workspace:packages/client"], "@versia/client": ["@versia/client@workspace:packages/client"],
"@versia/kit": ["@versia/kit@workspace:packages/plugin-kit"], "@versia/kit": ["@versia/kit@workspace:packages/plugin-kit"],

View file

@ -1,12 +0,0 @@
import { zodToJsonSchema } from "zod-to-json-schema";
await import("~/config.ts");
// This is an awkward way to avoid import cycles for some reason
await (async () => {
const { ConfigSchema } = await import("./schema.ts");
const jsonSchema = zodToJsonSchema(ConfigSchema, {});
console.write(`${JSON.stringify(jsonSchema, null, 4)}\n`);
})();

View file

@ -1,7 +1,9 @@
import markdownItTaskLists from "@hackmd/markdown-it-task-lists"; import markdownItTaskLists from "@hackmd/markdown-it-task-lists";
import { db, type Note, User } from "@versia/kit/db"; import { db, type Note, User } from "@versia/kit/db";
import { Instances, Users } from "@versia/kit/tables"; import { Instances, Users } from "@versia/kit/tables";
import type * as VersiaEntities from "@versia/sdk/entities";
import { FederationRequester } from "@versia/sdk/http"; import { FederationRequester } from "@versia/sdk/http";
import { config } from "@versia-server/config";
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm"; import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
import linkifyHtml from "linkify-html"; import linkifyHtml from "linkify-html";
import { import {
@ -18,8 +20,6 @@ import markdownItContainer from "markdown-it-container";
import markdownItTocDoneRight from "markdown-it-toc-done-right"; import markdownItTocDoneRight from "markdown-it-toc-done-right";
import { mentionValidator } from "@/api"; import { mentionValidator } from "@/api";
import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization"; import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization";
import { config } from "~/config.ts";
import type * as VersiaEntities from "~/packages/sdk/entities/index.ts";
import { transformOutputToUserWithRelations, userRelations } from "./user.ts"; import { transformOutputToUserWithRelations, userRelations } from "./user.ts";
/** /**

View file

@ -1,4 +1,5 @@
import { getLogger, type Logger } from "@logtape/logtape"; import { getLogger, type Logger } from "@logtape/logtape";
import { ApiError } from "@versia/kit";
import { import {
type Instance, type Instance,
Like, Like,
@ -8,6 +9,10 @@ import {
User, User,
} from "@versia/kit/db"; } from "@versia/kit/db";
import { Likes, Notes } from "@versia/kit/tables"; import { Likes, Notes } from "@versia/kit/tables";
import { EntitySorter, type JSONObject } from "@versia/sdk";
import { verify } from "@versia/sdk/crypto";
import * as VersiaEntities from "@versia/sdk/entities";
import { config } from "@versia-server/config";
import type { SocketAddress } from "bun"; import type { SocketAddress } from "bun";
import { Glob } from "bun"; import { Glob } from "bun";
import chalk from "chalk"; import chalk from "chalk";
@ -15,12 +20,6 @@ import { and, eq } from "drizzle-orm";
import { matches } from "ip-matching"; import { matches } from "ip-matching";
import { isValidationError } from "zod-validation-error"; import { isValidationError } from "zod-validation-error";
import { sentry } from "@/sentry"; import { sentry } from "@/sentry";
import { config } from "~/config.ts";
import { verify } from "~/packages/sdk/crypto.ts";
import * as VersiaEntities from "~/packages/sdk/entities/index.ts";
import { EntitySorter } from "~/packages/sdk/inbox-processor.ts";
import type { JSONObject } from "~/packages/sdk/types.ts";
import { ApiError } from "../errors/api-error.ts";
/** /**
* Checks if the hostname is defederated using glob matching. * Checks if the hostname is defederated using glob matching.

View file

@ -1,221 +0,0 @@
/* import {
afterEach,
beforeEach,
describe,
expect,
jest,
mock,
test,
} from "bun:test";
import { ZodError, type ZodTypeAny, z } from "zod";
import { Plugin } from "~/packages/plugin-kit";
import { type Manifest, manifestSchema } from "~/packages/plugin-kit/schema";
import { PluginLoader } from "./loader.ts";
const mockReaddir = jest.fn();
const mockGetLogger = jest.fn(() => ({
fatal: jest.fn(),
}));
const mockParseJSON5 = jest.fn();
const mockParseJSONC = jest.fn();
const mockFromZodError = jest.fn();
mock.module("node:fs/promises", () => ({
readdir: mockReaddir,
}));
mock.module("@logtape/logtape", () => ({
getLogger: mockGetLogger,
}));
mock.module("confbox", () => ({
parseJSON5: mockParseJSON5,
parseJSONC: mockParseJSONC,
}));
mock.module("zod-validation-error", () => ({
fromZodError: mockFromZodError,
}));
describe("PluginLoader", () => {
let pluginLoader: PluginLoader;
beforeEach(() => {
pluginLoader = new PluginLoader();
});
afterEach(() => {
jest.clearAllMocks();
});
test("getDirectories should return directories", async () => {
mockReaddir.mockResolvedValue([
{ name: "dir1", isDirectory: (): true => true },
{ name: "file1", isDirectory: (): false => false },
{ name: "dir2", isDirectory: (): true => true },
]);
// biome-ignore lint/complexity/useLiteralKeys: Private method
const directories = await PluginLoader["getDirectories"]("/some/path");
expect(directories).toEqual(["dir1", "dir2"]);
});
test("findManifestFile should return manifest file if found", async () => {
mockReaddir.mockResolvedValue(["manifest.json", "otherfile.txt"]);
const manifestFile =
// biome-ignore lint/complexity/useLiteralKeys: Private method
await PluginLoader["findManifestFile"]("/some/path");
expect(manifestFile).toBe("manifest.json");
});
test("hasEntrypoint should return true if entrypoint file is found", async () => {
mockReaddir.mockResolvedValue(["index.ts", "otherfile.txt"]);
// biome-ignore lint/complexity/useLiteralKeys: Private method
const hasEntrypoint = await PluginLoader["hasEntrypoint"]("/some/path");
expect(hasEntrypoint).toBe(true);
});
test("parseManifestFile should parse JSON manifest", async () => {
const manifestContent = { name: "test-plugin" };
Bun.file = jest.fn().mockReturnValue({
text: (): Promise<string> =>
Promise.resolve(JSON.stringify(manifestContent)),
});
// biome-ignore lint/complexity/useLiteralKeys: Private method
const manifest = await pluginLoader["parseManifestFile"](
"/some/path/manifest.json",
"manifest.json",
);
expect(manifest).toEqual(manifestContent);
});
test("findPlugins should return plugin directories with valid manifest and entrypoint", async () => {
mockReaddir
.mockResolvedValueOnce([
{ name: "plugin1", isDirectory: (): true => true },
{ name: "plugin2", isDirectory: (): true => true },
])
.mockResolvedValue(["manifest.json", "index.ts"]);
const plugins = await PluginLoader.findPlugins("/some/path");
expect(plugins).toEqual(["plugin1", "plugin2"]);
});
test("parseManifest should parse and validate manifest", async () => {
const manifestContent: Manifest = {
name: "test-plugin",
version: "1.1.0",
description: "Doobaee",
};
mockReaddir.mockResolvedValue(["manifest.json"]);
Bun.file = jest.fn().mockReturnValue({
text: (): Promise<string> =>
Promise.resolve(JSON.stringify(manifestContent)),
});
manifestSchema.safeParseAsync = jest.fn().mockResolvedValue({
success: true,
data: manifestContent,
});
const manifest = await pluginLoader.parseManifest(
"/some/path",
"plugin1",
);
expect(manifest).toEqual(manifestContent);
});
test("parseManifest should throw error if manifest is missing", async () => {
mockReaddir.mockResolvedValue([]);
await expect(
pluginLoader.parseManifest("/some/path", "plugin1"),
).rejects.toThrow("Plugin plugin1 is missing a manifest file");
});
test("parseManifest should throw error if manifest is invalid", async () => {
// @ts-expect-error trying to cause a type error here
const manifestContent: Manifest = {
name: "test-plugin",
version: "1.1.0",
};
mockReaddir.mockResolvedValue(["manifest.json"]);
Bun.file = jest.fn().mockReturnValue({
text: (): Promise<string> =>
Promise.resolve(JSON.stringify(manifestContent)),
});
manifestSchema.safeParseAsync = jest.fn().mockResolvedValue({
success: false,
error: new ZodError([]),
});
await expect(
pluginLoader.parseManifest("/some/path", "plugin1"),
).rejects.toThrow();
});
test("loadPlugin should load and return a Plugin instance", async () => {
const mockPlugin = new Plugin(z.object({}));
mock.module("/some/path/index.ts", () => ({
default: mockPlugin,
}));
const plugin = await pluginLoader.loadPlugin("/some/path", "index.ts");
expect(plugin).toBeInstanceOf(Plugin);
});
test("loadPlugin should throw error if default export is not a Plugin", async () => {
mock.module("/some/path/index.ts", () => ({
default: "cheese",
}));
await expect(
pluginLoader.loadPlugin("/some/path", "index.ts"),
).rejects.toThrow("Entrypoint is not a Plugin");
});
test("loadPlugins should load all plugins in a directory", async () => {
const manifestContent: Manifest = {
name: "test-plugin",
version: "1.1.0",
description: "Doobaee",
};
const mockPlugin = new Plugin(z.object({}));
mockReaddir
.mockResolvedValueOnce([
{ name: "plugin1", isDirectory: (): true => true },
{ name: "plugin2", isDirectory: (): true => true },
])
.mockResolvedValue(["manifest.json", "index.ts"]);
Bun.file = jest.fn().mockReturnValue({
text: (): Promise<string> =>
Promise.resolve(JSON.stringify(manifestContent)),
});
manifestSchema.safeParseAsync = jest.fn().mockResolvedValue({
success: true,
data: manifestContent,
});
mock.module("/some/path/plugin1/index", () => ({
default: mockPlugin,
}));
mock.module("/some/path/plugin2/index", () => ({
default: mockPlugin,
}));
const plugins = await pluginLoader.loadPlugins("/some/path", true);
expect(plugins).toEqual([
{
manifest: manifestContent,
plugin: mockPlugin as unknown as Plugin<ZodTypeAny>,
},
{
manifest: manifestContent,
plugin: mockPlugin as unknown as Plugin<ZodTypeAny>,
},
]);
});
});
*/

View file

@ -1,14 +1,13 @@
import { readdir } from "node:fs/promises"; import { readdir } from "node:fs/promises";
import { getLogger, type Logger } from "@logtape/logtape"; import { getLogger, type Logger } from "@logtape/logtape";
import { type Manifest, manifestSchema, Plugin } from "@versia/kit";
import { config } from "@versia-server/config";
import { file, sleep } from "bun"; import { file, sleep } from "bun";
import chalk from "chalk"; import chalk from "chalk";
import { parseJSON5, parseJSONC } from "confbox"; import { parseJSON5, parseJSONC } from "confbox";
import type { Hono } from "hono"; import type { Hono } from "hono";
import type { ZodTypeAny } from "zod"; import type { ZodTypeAny } from "zod";
import { fromZodError, type ValidationError } from "zod-validation-error"; import { fromZodError, type ValidationError } from "zod-validation-error";
import { config } from "~/config.ts";
import { Plugin } from "~/packages/plugin-kit/plugin";
import { type Manifest, manifestSchema } from "~/packages/plugin-kit/schema";
import type { HonoEnv } from "~/types/api"; import type { HonoEnv } from "~/types/api";
/** /**

View file

@ -1,9 +1,9 @@
import { User } from "@versia/kit/db"; import { User } from "@versia/kit/db";
import type { JSONObject } from "@versia/sdk";
import * as VersiaEntities from "@versia/sdk/entities";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import chalk from "chalk"; import chalk from "chalk";
import { config } from "~/config.ts";
import * as VersiaEntities from "~/packages/sdk/entities";
import type { JSONObject } from "~/packages/sdk/types";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
export enum DeliveryJobType { export enum DeliveryJobType {

View file

@ -1,8 +1,8 @@
import { Instance } from "@versia/kit/db"; import { Instance } from "@versia/kit/db";
import { Instances } from "@versia/kit/tables"; import { Instances } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { config } from "~/config.ts";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
export enum FetchJobType { export enum FetchJobType {

View file

@ -1,11 +1,11 @@
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import { ApiError } from "@versia/kit";
import { Instance, User } from "@versia/kit/db"; import { Instance, User } from "@versia/kit/db";
import type { JSONObject } from "@versia/sdk";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import type { SocketAddress } from "bun"; import type { SocketAddress } from "bun";
import { config } from "~/config.ts";
import type { JSONObject } from "~/packages/sdk/types.ts";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
import { ApiError } from "../errors/api-error.ts";
import { InboxProcessor } from "../inbox/processor.ts"; import { InboxProcessor } from "../inbox/processor.ts";
export enum InboxJobType { export enum InboxJobType {

View file

@ -1,6 +1,6 @@
import { Media } from "@versia/kit/db"; import { Media } from "@versia/kit/db";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import { config } from "~/config.ts";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
import { calculateBlurhash } from "../media/preprocessors/blurhash.ts"; import { calculateBlurhash } from "../media/preprocessors/blurhash.ts";
import { convertImage } from "../media/preprocessors/image-conversion.ts"; import { convertImage } from "../media/preprocessors/image-conversion.ts";

View file

@ -1,8 +1,8 @@
import { Note, PushSubscription, Token, User } from "@versia/kit/db"; import { Note, PushSubscription, Token, User } from "@versia/kit/db";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import { sendNotification } from "web-push"; import { sendNotification } from "web-push";
import { htmlToText } from "@/content_types.ts"; import { htmlToText } from "@/content_types.ts";
import { config } from "~/config.ts";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
export enum PushJobType { export enum PushJobType {

View file

@ -1,6 +1,6 @@
import { Relationship, User } from "@versia/kit/db"; import { Relationship, User } from "@versia/kit/db";
import { config } from "@versia-server/config";
import { Queue, Worker } from "bullmq"; import { Queue, Worker } from "bullmq";
import { config } from "~/config.ts";
import { connection } from "~/utils/redis.ts"; import { connection } from "~/utils/redis.ts";
export enum RelationshipJobType { export enum RelationshipJobType {

View file

@ -5,12 +5,12 @@
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import { db, Note, User } from "@versia/kit/db"; import { db, Note, User } from "@versia/kit/db";
import { config } from "@versia-server/config";
import type { SQL, ValueOrArray } from "drizzle-orm"; import type { SQL, ValueOrArray } from "drizzle-orm";
import { import {
Ingest as SonicChannelIngest, Ingest as SonicChannelIngest,
Search as SonicChannelSearch, Search as SonicChannelSearch,
} from "sonic-channel"; } from "sonic-channel";
import { config } from "~/config.ts";
/** /**
* Enum for Sonic index types * Enum for Sonic index types

View file

@ -3,9 +3,9 @@ import { friendlyErrorPlugin } from "@clerc/plugin-friendly-error";
import { helpPlugin } from "@clerc/plugin-help"; import { helpPlugin } from "@clerc/plugin-help";
import { notFoundPlugin } from "@clerc/plugin-not-found"; import { notFoundPlugin } from "@clerc/plugin-not-found";
import { versionPlugin } from "@clerc/plugin-version"; import { versionPlugin } from "@clerc/plugin-version";
import { setupDatabase } from "@versia/kit/db";
import { Clerc } from "clerc"; import { Clerc } from "clerc";
import { searchManager } from "~/classes/search/search-manager.ts"; import { searchManager } from "~/classes/search/search-manager.ts";
import { setupDatabase } from "~/drizzle/db.ts";
import pkg from "~/package.json" with { type: "json" }; import pkg from "~/package.json" with { type: "json" };
import { rebuildIndexCommand } from "./index/rebuild.ts"; import { rebuildIndexCommand } from "./index/rebuild.ts";
import { refetchInstanceCommand } from "./instance/refetch.ts"; import { refetchInstanceCommand } from "./instance/refetch.ts";

View file

@ -1,3 +1,4 @@
import { config } from "@versia-server/config";
// @ts-expect-error - Root import is required or the Clec type definitions won't work // @ts-expect-error - Root import is required or the Clec type definitions won't work
// biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work // biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work
import { defineCommand, type Root } from "clerc"; import { defineCommand, type Root } from "clerc";
@ -6,7 +7,6 @@ import {
SonicIndexType, SonicIndexType,
searchManager, searchManager,
} from "~/classes/search/search-manager.ts"; } from "~/classes/search/search-manager.ts";
import { config } from "~/config.ts";
export const rebuildIndexCommand = defineCommand( export const rebuildIndexCommand = defineCommand(
{ {

View file

@ -1,11 +1,11 @@
import { Instance } from "@versia/kit/db";
import { Instances } from "@versia/kit/tables";
import chalk from "chalk"; import chalk from "chalk";
// @ts-expect-error - Root import is required or the Clec type definitions won't work // @ts-expect-error - Root import is required or the Clec type definitions won't work
// biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work // biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work
import { defineCommand, type Root } from "clerc"; import { defineCommand, type Root } from "clerc";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { Instance } from "~/classes/database/instance.ts";
import { FetchJobType, fetchQueue } from "~/classes/queues/fetch.ts"; import { FetchJobType, fetchQueue } from "~/classes/queues/fetch.ts";
import { Instances } from "~/drizzle/schema.ts";
export const refetchInstanceCommand = defineCommand( export const refetchInstanceCommand = defineCommand(
{ {

View file

@ -1,12 +1,12 @@
import { User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import chalk from "chalk"; import chalk from "chalk";
// @ts-expect-error - Root import is required or the Clec type definitions won't work // @ts-expect-error - Root import is required or the Clec type definitions won't work
// biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work // biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work
import { defineCommand, type Root } from "clerc"; import { defineCommand, type Root } from "clerc";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { renderUnicodeCompact } from "uqr"; import { renderUnicodeCompact } from "uqr";
import { User } from "~/classes/database/user";
import { config } from "~/config";
import { Users } from "~/drizzle/schema";
export const createUserCommand = defineCommand( export const createUserCommand = defineCommand(
{ {

View file

@ -1,9 +1,9 @@
import { User } from "@versia/kit/db";
import chalk from "chalk"; import chalk from "chalk";
// @ts-expect-error - Root import is required or the Clec type definitions won't work // @ts-expect-error - Root import is required or the Clec type definitions won't work
// biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work // biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work
import { defineCommand, type Root } from "clerc"; import { defineCommand, type Root } from "clerc";
import ora from "ora"; import ora from "ora";
import { User } from "~/classes/database/user.ts";
import { retrieveUser } from "../utils.ts"; import { retrieveUser } from "../utils.ts";
export const refetchUserCommand = defineCommand( export const refetchUserCommand = defineCommand(

View file

@ -1,10 +1,10 @@
import { Token } from "@versia/kit/db";
import { randomUUIDv7 } from "bun"; import { randomUUIDv7 } from "bun";
import chalk from "chalk"; import chalk from "chalk";
// @ts-expect-error - Root import is required or the Clec type definitions won't work // @ts-expect-error - Root import is required or the Clec type definitions won't work
// biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work // biome-ignore lint/correctness/noUnusedImports: Root import is required or the Clec type definitions won't work
import { defineCommand, type Root } from "clerc"; import { defineCommand, type Root } from "clerc";
import { randomString } from "@/math.ts"; import { randomString } from "@/math.ts";
import { Token } from "~/classes/database/token.ts";
import { retrieveUser } from "../utils.ts"; import { retrieveUser } from "../utils.ts";
export const generateTokenCommand = defineCommand( export const generateTokenCommand = defineCommand(

View file

@ -1,8 +1,7 @@
import { Instance, User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { parseUserAddress } from "@/api"; import { parseUserAddress } from "@/api";
import { Instance } from "~/classes/database/instance";
import { User } from "~/classes/database/user";
import { Users } from "~/drizzle/schema";
export const retrieveUser = async ( export const retrieveUser = async (
usernameOrHandle: string, usernameOrHandle: string,

View file

@ -1,5 +1,5 @@
import { config } from "@versia-server/config";
import type { Config } from "drizzle-kit"; import type { Config } from "drizzle-kit";
import { config } from "~/config.ts";
/** /**
* Drizzle can't properly resolve imports with top-level await, so uncomment * Drizzle can't properly resolve imports with top-level await, so uncomment

View file

@ -1,45 +0,0 @@
import process from "node:process";
import { getLogger } from "@logtape/logtape";
import chalk from "chalk";
import { sentry } from "@/sentry";
import { getDeliveryWorker } from "~/classes/queues/delivery";
import { getFetchWorker } from "~/classes/queues/fetch";
import { getInboxWorker } from "~/classes/queues/inbox";
import { getMediaWorker } from "~/classes/queues/media";
import { getPushWorker } from "~/classes/queues/push";
import { getRelationshipWorker } from "~/classes/queues/relationships";
process.on("SIGINT", () => {
process.exit();
});
await import("~/entrypoints/worker/setup.ts");
sentry?.captureMessage("Server started", "info");
const serverLogger = getLogger("server");
serverLogger.info`Starting Fetch Worker...`;
getFetchWorker();
serverLogger.info`${chalk.green("✔")} Fetch Worker started`;
serverLogger.info`Starting Delivery Worker...`;
getDeliveryWorker();
serverLogger.info`${chalk.green("✔")} Delivery Worker started`;
serverLogger.info`Starting Inbox Worker...`;
getInboxWorker();
serverLogger.info`${chalk.green("✔")} Inbox Worker started`;
serverLogger.info`Starting Push Worker...`;
getPushWorker();
serverLogger.info`${chalk.green("✔")} Push Worker started`;
serverLogger.info`Starting Media Worker...`;
getMediaWorker();
serverLogger.info`${chalk.green("✔")} Media Worker started`;
serverLogger.info`Starting Relationship Worker...`;
getRelationshipWorker();
serverLogger.info`${chalk.green("✔")} Relationship Worker started`;
serverLogger.info`${chalk.green("✔✔✔✔✔✔")} All workers started`;

View file

@ -1 +0,0 @@
await import("~/entrypoints/api/index.ts");

View file

@ -20,9 +20,87 @@
"activitypub", "activitypub",
"bun" "bun"
], ],
"workspaces": [ "workspaces": {
"packages/*" "packages": [
], "packages/*"
],
"catalog": {
"@biomejs/biome": "2.0.0-beta.5",
"@types/bun": "^1.2.16",
"@types/html-to-text": "^9.0.4",
"@types/markdown-it-container": "^2.0.10",
"@types/mime-types": "^3.0.1",
"@types/qs": "^6.14.0",
"@types/web-push": "^3.6.4",
"bun-bagel": "^1.2.0",
"drizzle-kit": "^0.31.1",
"mitt": "^3.0.1",
"markdown-it-image-figures": "^2.1.1",
"ts-prune": "^0.10.3",
"typescript": "^5.8.3",
"vitepress": "^1.6.3",
"vitepress-plugin-tabs": "^0.7.1",
"vitepress-sidebar": "^1.31.1",
"vue": "^3.5.16",
"zod-to-json-schema": "^3.24.5",
"@bull-board/api": "^6.10.1",
"@bull-board/hono": "^6.10.1",
"@clerc/plugin-completions": "^0.44.0",
"@clerc/plugin-friendly-error": "^0.44.0",
"@clerc/plugin-help": "^0.44.0",
"@clerc/plugin-not-found": "^0.44.0",
"@clerc/plugin-version": "^0.44.0",
"@hackmd/markdown-it-task-lists": "^2.1.4",
"@hono/zod-validator": "^0.7.0",
"@inquirer/confirm": "^5.1.12",
"@logtape/file": "^0.12.0",
"@logtape/logtape": "^0.12.0",
"@scalar/hono-api-reference": "^0.9.4",
"@sentry/bun": "^9.29.0",
"altcha-lib": "^1.3.0",
"blurhash": "^2.0.5",
"bullmq": "^5.53.3",
"chalk": "^5.4.1",
"clerc": "^0.44.0",
"confbox": "^0.2.2",
"drizzle-orm": "^0.44.2",
"feed": "^5.1.0",
"hono": "^4.7.11",
"hono-openapi": "^0.4.8",
"hono-rate-limiter": "^0.4.2",
"html-to-text": "^9.0.5",
"ioredis": "^5.6.1",
"ip-matching": "^2.1.2",
"iso-639-1": "^3.1.5",
"jose": "^6.0.11",
"linkify-html": "^4.3.1",
"linkify-string": "^4.3.1",
"linkifyjs": "^4.3.1",
"magic-regexp": "^0.10.0",
"markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.2.0",
"markdown-it-container": "^4.0.0",
"markdown-it-mathjax3": "^4.3.2",
"markdown-it-toc-done-right": "^4.2.0",
"mime-types": "^3.0.1",
"mitata": "^1.0.34",
"oauth4webapi": "^3.5.2",
"ora": "^8.2.0",
"qs": "^6.14.0",
"sharp": "^0.34.2",
"sonic-channel": "^1.3.1",
"string-comparison": "^1.3.0",
"stringify-entities": "^4.0.4",
"unicode-emoji-json": "^0.8.0",
"uqr": "^0.1.2",
"web-push": "^3.6.7",
"xss": "^1.0.15",
"youch": "^4.1.0-beta.7",
"zod": "^3.25.64",
"zod-openapi": "^4.2.4",
"zod-validation-error": "^3.5.0"
}
},
"maintainers": [ "maintainers": [
{ {
"email": "contact@cpluspatch.com", "email": "contact@cpluspatch.com",
@ -36,21 +114,14 @@
}, },
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "bun run --hot index.ts",
"start": "NODE_ENV=production bun run dist/index.js --prod",
"lint": "biome check .", "lint": "biome check .",
"build": "bun run build.ts",
"build:worker": "bun run build-worker.ts",
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs --exclude-ext sql,log,pem", "cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs --exclude-ext sql,log,pem",
"wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-", "wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-",
"cli": "bun run cli/index.ts", "cli": "bun run cli/index.ts",
"prune": "ts-prune | grep -v server/ | grep -v dist/ | grep -v '(used in module)'",
"schema:generate": "bun run classes/config/to-json-schema.ts > config/config.schema.json && bun run packages/plugin-kit/json-schema.ts > packages/plugin-kit/manifest.schema.json",
"check": "bunx tsc -p .", "check": "bunx tsc -p .",
"test": "bun test", "test": "bun test",
"docs:dev": "vitepress dev docs", "run-api": "bun run packages/api/build.ts && cd dist && ln -s ../config config && bun run packages/api/index.js",
"docs:build": "vitepress build docs", "run-worker": "bun run packages/worker/build.ts && cd dist && ln -s ../config config && bun run packages/worker/index.js"
"docs:preview": "vitepress preview docs"
}, },
"trustedDependencies": [ "trustedDependencies": [
"@biomejs/biome", "@biomejs/biome",
@ -60,83 +131,83 @@
"sharp" "sharp"
], ],
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.0.0-beta.5", "@types/bun": "catalog:",
"@types/bun": "^1.2.16", "@types/html-to-text": "catalog:",
"@types/html-to-text": "^9.0.4", "@types/markdown-it-container": "catalog:",
"@types/markdown-it-container": "^2.0.10", "@types/mime-types": "catalog:",
"@types/mime-types": "^3.0.1", "@types/qs": "catalog:",
"@types/qs": "^6.14.0", "@types/web-push": "catalog:",
"@types/web-push": "^3.6.4", "bun-bagel": "catalog:",
"bun-bagel": "^1.2.0", "drizzle-kit": "catalog:",
"drizzle-kit": "^0.31.1", "markdown-it-image-figures": "catalog:",
"markdown-it-image-figures": "^2.1.1", "ts-prune": "catalog:",
"ts-prune": "^0.10.3", "typescript": "catalog:",
"typescript": "^5.8.3", "vitepress": "catalog:",
"vitepress": "^1.6.3", "vitepress-plugin-tabs": "catalog:",
"vitepress-plugin-tabs": "^0.7.1", "vitepress-sidebar": "catalog:",
"vitepress-sidebar": "^1.31.1", "vue": "catalog:",
"vue": "^3.5.16", "zod-to-json-schema": "catalog:"
"zod-to-json-schema": "^3.24.5"
}, },
"dependencies": { "dependencies": {
"@bull-board/api": "^6.10.1", "@bull-board/api": "catalog:",
"@bull-board/hono": "^6.10.1", "@bull-board/hono": "catalog:",
"@clerc/plugin-completions": "^0.44.0", "@clerc/plugin-completions": "catalog:",
"@clerc/plugin-friendly-error": "^0.44.0", "@clerc/plugin-friendly-error": "catalog:",
"@clerc/plugin-help": "^0.44.0", "@clerc/plugin-help": "catalog:",
"@clerc/plugin-not-found": "^0.44.0", "@clerc/plugin-not-found": "catalog:",
"@clerc/plugin-version": "^0.44.0", "@clerc/plugin-version": "catalog:",
"@hackmd/markdown-it-task-lists": "^2.1.4", "@hackmd/markdown-it-task-lists": "catalog:",
"@hono/zod-validator": "^0.7.0", "@hono/zod-validator": "catalog:",
"@inquirer/confirm": "^5.1.12", "@inquirer/confirm": "catalog:",
"@logtape/file": "^0.12.0", "@logtape/file": "catalog:",
"@logtape/logtape": "^0.12.0", "@logtape/logtape": "catalog:",
"@scalar/hono-api-reference": "^0.9.4", "@scalar/hono-api-reference": "catalog:",
"@sentry/bun": "^9.29.0", "@sentry/bun": "catalog:",
"@versia/client": "workspace:*", "@versia/client": "workspace:*",
"@versia/kit": "workspace:*", "@versia/kit": "workspace:*",
"@versia/sdk": "workspace:*", "@versia/sdk": "workspace:*",
"altcha-lib": "^1.3.0", "@versia-server/config": "workspace:*",
"blurhash": "^2.0.5", "altcha-lib": "catalog:",
"bullmq": "^5.53.3", "blurhash": "catalog:",
"chalk": "^5.4.1", "bullmq": "catalog:",
"clerc": "^0.44.0", "chalk": "catalog:",
"confbox": "^0.2.2", "clerc": "catalog:",
"drizzle-orm": "^0.44.2", "confbox": "catalog:",
"feed": "^5.1.0", "drizzle-orm": "catalog:",
"hono": "^4.7.11", "feed": "catalog:",
"hono-openapi": "^0.4.8", "hono": "catalog:",
"hono-rate-limiter": "^0.4.2", "hono-openapi": "catalog:",
"html-to-text": "^9.0.5", "hono-rate-limiter": "catalog:",
"ioredis": "^5.6.1", "html-to-text": "catalog:",
"ip-matching": "^2.1.2", "ioredis": "catalog:",
"ip-matching": "catalog:",
"iso-639-1": "^3.1.5", "iso-639-1": "^3.1.5",
"jose": "^6.0.11", "jose": "catalog:",
"linkify-html": "^4.3.1", "linkify-html": "catalog:",
"linkify-string": "^4.3.1", "linkify-string": "catalog:",
"linkifyjs": "^4.3.1", "linkifyjs": "catalog:",
"magic-regexp": "^0.10.0", "magic-regexp": "catalog:",
"markdown-it": "^14.1.0", "markdown-it": "catalog:",
"markdown-it-anchor": "^9.2.0", "markdown-it-anchor": "catalog:",
"markdown-it-container": "^4.0.0", "markdown-it-container": "catalog:",
"markdown-it-mathjax3": "^4.3.2", "markdown-it-mathjax3": "catalog:",
"markdown-it-toc-done-right": "^4.2.0", "markdown-it-toc-done-right": "catalog:",
"mime-types": "^3.0.1", "mime-types": "catalog:",
"mitata": "^1.0.34", "mitata": "catalog:",
"oauth4webapi": "^3.5.2", "oauth4webapi": "catalog:",
"ora": "^8.2.0", "ora": "catalog:",
"qs": "^6.14.0", "qs": "catalog:",
"sharp": "^0.34.2", "sharp": "catalog:",
"sonic-channel": "^1.3.1", "sonic-channel": "catalog:",
"string-comparison": "^1.3.0", "string-comparison": "catalog:",
"stringify-entities": "^4.0.4", "stringify-entities": "catalog:",
"unicode-emoji-json": "^0.8.0", "unicode-emoji-json": "catalog:",
"uqr": "^0.1.2", "uqr": "catalog:",
"web-push": "^3.6.7", "web-push": "catalog:",
"xss": "^1.0.15", "xss": "catalog:",
"youch": "^4.1.0-beta.7", "youch": "catalog:",
"zod": "^3.25.64", "zod": "catalog:",
"zod-openapi": "^4.2.4", "zod-openapi": "catalog:",
"zod-validation-error": "^3.5.0" "zod-validation-error": "catalog:"
} }
} }

View file

@ -1,6 +1,8 @@
import { resolve } from "node:path"; import { resolve } from "node:path";
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import { Scalar } from "@scalar/hono-api-reference"; import { Scalar } from "@scalar/hono-api-reference";
import { ApiError } from "@versia/kit";
import { config } from "@versia-server/config";
import chalk from "chalk"; import chalk from "chalk";
import { Hono } from "hono"; import { Hono } from "hono";
import { serveStatic } from "hono/bun"; import { serveStatic } from "hono/bun";
@ -13,17 +15,15 @@ import { Youch } from "youch";
import { applyToHono } from "@/bull-board.ts"; import { applyToHono } from "@/bull-board.ts";
import { configureLoggers } from "@/loggers"; import { configureLoggers } from "@/loggers";
import { sentry } from "@/sentry"; import { sentry } from "@/sentry";
import { config } from "~/config.ts";
import pkg from "~/package.json" with { type: "application/json" }; import pkg from "~/package.json" with { type: "application/json" };
import { ApiError } from "./classes/errors/api-error.ts"; import { PluginLoader } from "../../classes/plugin/loader.ts";
import { PluginLoader } from "./classes/plugin/loader.ts"; import type { ApiRouteExports, HonoEnv } from "../../types/api.ts";
import { agentBans } from "./middlewares/agent-bans.ts"; import { agentBans } from "./middlewares/agent-bans.ts";
import { boundaryCheck } from "./middlewares/boundary-check.ts"; import { boundaryCheck } from "./middlewares/boundary-check.ts";
import { ipBans } from "./middlewares/ip-bans.ts"; import { ipBans } from "./middlewares/ip-bans.ts";
import { logger } from "./middlewares/logger.ts"; import { logger } from "./middlewares/logger.ts";
import { rateLimit } from "./middlewares/rate-limit.ts"; import { rateLimit } from "./middlewares/rate-limit.ts";
import { routes } from "./routes.ts"; import { routes } from "./routes.ts";
import type { ApiRouteExports, HonoEnv } from "./types/api.ts";
// Extends Zod with OpenAPI schema generation // Extends Zod with OpenAPI schema generation
import "zod-openapi/extend"; import "zod-openapi/extend";

View file

@ -1,6 +1,6 @@
import { readdir } from "node:fs/promises"; import { readdir } from "node:fs/promises";
import { $, build } from "bun"; import { $, build } from "bun";
import { routes } from "~/routes"; import { routes } from "~/packages/api/routes";
console.log("Building..."); console.log("Building...");
@ -11,9 +11,9 @@ const pluginDirs = await readdir("plugins", { withFileTypes: true });
await build({ await build({
entrypoints: [ entrypoints: [
"index.ts", "packages/api/index.ts",
// HACK: Include to avoid cyclical import errors // HACK: Include to avoid cyclical import errors
"config.ts", "packages/config/index.ts",
"cli/index.ts", "cli/index.ts",
// Force Bun to include endpoints // Force Bun to include endpoints
...Object.values(routes), ...Object.values(routes),
@ -31,8 +31,12 @@ await build({
console.log("Copying files..."); console.log("Copying files...");
// Copy Drizzle migrations to dist // Fix Bun build mistake
await $`cp -r drizzle dist/drizzle`; await $`sed -i 's/ProxiableUrl, url, sensitiveString, keyPair, exportedConfig/url, sensitiveString, keyPair, exportedConfig/g' dist/packages/config/*.js`;
// Copy Drizzle stuff
await $`mkdir -p dist/packages/plugin-kit/tables`;
await $`cp -rL packages/plugin-kit/tables/migrations dist/packages/plugin-kit/tables`;
// Copy plugin manifests // Copy plugin manifests
await $`cp plugins/openid/manifest.json dist/plugins/openid/manifest.json`; await $`cp plugins/openid/manifest.json dist/plugins/openid/manifest.json`;

View file

@ -1,9 +1,9 @@
import process from "node:process"; import process from "node:process";
import { config } from "@versia-server/config";
import { Youch } from "youch"; import { Youch } from "youch";
import { sentry } from "@/sentry"; import { sentry } from "@/sentry";
import { createServer } from "@/server"; import { createServer } from "@/server";
import { appFactory } from "~/app"; import { appFactory } from "./app.ts";
import { config } from "~/config.ts";
process.on("SIGINT", () => { process.on("SIGINT", () => {
process.exit(); process.exit();
@ -15,7 +15,7 @@ process.on("uncaughtException", async (error) => {
console.error(await youch.toANSI(error)); console.error(await youch.toANSI(error));
}); });
await import("~/entrypoints/api/setup.ts"); await import("./setup.ts");
sentry?.captureMessage("Server started", "info"); sentry?.captureMessage("Server started", "info");
createServer(config, await appFactory()); createServer(config, await appFactory());

View file

@ -1,6 +1,6 @@
import { ApiError } from "@versia/kit";
import { config } from "@versia-server/config";
import { createMiddleware } from "hono/factory"; import { createMiddleware } from "hono/factory";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/config.ts";
export const agentBans = createMiddleware(async (context, next) => { export const agentBans = createMiddleware(async (context, next) => {
// Check for banned user agents (regex) // Check for banned user agents (regex)

View file

@ -1,5 +1,5 @@
import { ApiError } from "@versia/kit";
import { createMiddleware } from "hono/factory"; import { createMiddleware } from "hono/factory";
import { ApiError } from "~/classes/errors/api-error";
export const boundaryCheck = createMiddleware(async (context, next) => { export const boundaryCheck = createMiddleware(async (context, next) => {
// Checks that FormData boundary is present // Checks that FormData boundary is present

View file

@ -1,10 +1,10 @@
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import { ApiError } from "@versia/kit";
import { config } from "@versia-server/config";
import type { SocketAddress } from "bun"; import type { SocketAddress } from "bun";
import { createMiddleware } from "hono/factory"; import { createMiddleware } from "hono/factory";
import { matches } from "ip-matching"; import { matches } from "ip-matching";
import { sentry } from "@/sentry"; import { sentry } from "@/sentry";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/config.ts";
export const ipBans = createMiddleware(async (context, next) => { export const ipBans = createMiddleware(async (context, next) => {
// Check for banned IPs // Check for banned IPs

View file

@ -1,8 +1,8 @@
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import { config } from "@versia-server/config";
import { SHA256 } from "bun"; import { SHA256 } from "bun";
import chalk from "chalk"; import chalk from "chalk";
import { createMiddleware } from "hono/factory"; import { createMiddleware } from "hono/factory";
import { config } from "~/config.ts";
export const logger = createMiddleware(async (context, next) => { export const logger = createMiddleware(async (context, next) => {
if (config.logging.types.requests) { if (config.logging.types.requests) {

View file

@ -1,8 +1,8 @@
import type { ApiError } from "@versia/kit";
import { env } from "bun"; import { env } from "bun";
import type { MiddlewareHandler } from "hono"; import type { MiddlewareHandler } from "hono";
import { rateLimiter } from "hono-rate-limiter"; import { rateLimiter } from "hono-rate-limiter";
import type { z } from "zod"; import type { z } from "zod";
import type { ApiError } from "~/classes/errors/api-error";
import type { HonoEnv } from "~/types/api"; import type { HonoEnv } from "~/types/api";
// Not exported by hono-rate-limiter // Not exported by hono-rate-limiter

View file

@ -1,5 +1,5 @@
import { config } from "@versia-server/config";
import { createMiddleware } from "hono/factory"; import { createMiddleware } from "hono/factory";
import { config } from "~/config.ts";
export const urlCheck = createMiddleware(async (context, next) => { export const urlCheck = createMiddleware(async (context, next) => {
// Check that request URL matches base_url // Check that request URL matches base_url

67
packages/api/package.json Normal file
View file

@ -0,0 +1,67 @@
{
"name": "@versia-server/api",
"module": "index.ts",
"type": "module",
"version": "0.9.0-alpha.0",
"description": "Powerful, configurable and modular federated server using the Versia Protocol.",
"homepage": "https://versia.pub",
"author": {
"email": "contact@cpluspatch.com",
"name": "Jesse Wierzbinski",
"url": "https://cpluspatch.com"
},
"bugs": {
"url": "https://github.com/versia-pub/server/issues"
},
"icon": "https://cdn.versia.pub/branding/icon.svg",
"license": "AGPL-3.0-or-later",
"keywords": [
"federated",
"activitypub",
"bun"
],
"maintainers": [
{
"email": "contact@cpluspatch.com",
"name": "Jesse Wierzbinski",
"url": "https://cpluspatch.com"
}
],
"repository": {
"type": "git",
"url": "git+https://github.com/versia-pub/server.git",
"directory": "packages/api"
},
"private": true,
"scripts": {
"dev": "bun run --hot index.ts",
"build": "bun run build.ts",
"schema:generate": "bun run classes/config/to-json-schema.ts > config/config.schema.json && bun run packages/plugin-kit/json-schema.ts > packages/plugin-kit/manifest.schema.json",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"dependencies": {
"@versia-server/config": "workspace:*",
"@versia/kit": "workspace:*",
"@versia/client": "workspace:*",
"@versia/sdk": "workspace:*",
"@logtape/logtape": "catalog:",
"youch": "catalog:",
"hono": "catalog:",
"hono-openapi": "catalog:",
"zod": "catalog:",
"drizzle-orm": "catalog:",
"string-comparison": "catalog:",
"bun-bagel": "catalog:",
"chalk": "catalog:",
"unicode-emoji-json": "catalog:",
"sharp": "catalog:",
"iso-639-1": "catalog:",
"jose": "catalog:",
"zod-openapi": "catalog:",
"@scalar/hono-api-reference": "catalog:",
"hono-rate-limiter": "catalog:",
"ip-matching": "catalog:"
}
}

View file

@ -2,7 +2,7 @@ import { FileSystemRouter } from "bun";
// Returns the route filesystem path when given a URL // Returns the route filesystem path when given a URL
export const routeMatcher = new FileSystemRouter({ export const routeMatcher = new FileSystemRouter({
style: "nextjs", style: "nextjs",
dir: "api", dir: "packages/api/routes",
fileExtensions: [".ts", ".js"], fileExtensions: [".ts", ".js"],
}); });

View file

@ -1,8 +1,8 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import { Application } from "@versia/kit/db"; import { Application } from "@versia/kit/db";
import { config } from "@versia-server/config";
import { randomUUIDv7 } from "bun"; import { randomUUIDv7 } from "bun";
import { randomString } from "@/math"; import { randomString } from "@/math";
import { config } from "~/config.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils"; import { fakeRequest, getTestUsers } from "~/tests/utils";
const { users, deleteUsers, passwords } = await getTestUsers(1); const { users, deleteUsers, passwords } = await getTestUsers(1);

View file

@ -1,5 +1,7 @@
import { ApiError } from "@versia/kit";
import { Application, User } from "@versia/kit/db"; import { Application, User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { password as bunPassword } from "bun"; import { password as bunPassword } from "bun";
import { eq, or } from "drizzle-orm"; import { eq, or } from "drizzle-orm";
import type { Context } from "hono"; import type { Context } from "hono";
@ -9,8 +11,6 @@ import { validator } from "hono-openapi/zod";
import { SignJWT } from "jose"; import { SignJWT } from "jose";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, handleZodError } from "@/api"; import { apiRoute, handleZodError } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/config.ts";
const returnError = ( const returnError = (
context: Context, context: Context,

View file

@ -1,11 +1,11 @@
import { db } from "@versia/kit/db"; import { db } from "@versia/kit/db";
import { Applications, Tokens } from "@versia/kit/tables"; import { Applications, Tokens } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { validator } from "hono-openapi/zod"; import { validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, handleZodError } from "@/api"; import { apiRoute, handleZodError } from "@/api";
import { config } from "~/config.ts";
/** /**
* OAuth Code flow * OAuth Code flow

View file

@ -1,8 +1,8 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import { Application } from "@versia/kit/db"; import { Application } from "@versia/kit/db";
import { config } from "@versia-server/config";
import { randomUUIDv7 } from "bun"; import { randomUUIDv7 } from "bun";
import { randomString } from "@/math"; import { randomString } from "@/math";
import { config } from "~/config.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils"; import { fakeRequest, getTestUsers } from "~/tests/utils";
const { users, deleteUsers, passwords } = await getTestUsers(1); const { users, deleteUsers, passwords } = await getTestUsers(1);

View file

@ -1,5 +1,6 @@
import { User } from "@versia/kit/db"; import { User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { password as bunPassword } from "bun"; import { password as bunPassword } from "bun";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import type { Context } from "hono"; import type { Context } from "hono";
@ -7,7 +8,6 @@ import { describeRoute } from "hono-openapi";
import { validator } from "hono-openapi/zod"; import { validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, handleZodError } from "@/api"; import { apiRoute, handleZodError } from "@/api";
import { config } from "~/config.ts";
const returnError = ( const returnError = (
context: Context, context: Context,

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -1,10 +1,10 @@
import { RolePermission } from "@versia/client/schemas"; import { RolePermission } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { getFeed } from "@/rss"; import { getFeed } from "@/rss";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -1,10 +1,10 @@
import { RolePermission } from "@versia/client/schemas"; import { RolePermission } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { getFeed } from "@/rss"; import { getFeed } from "@/rss";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -3,12 +3,12 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,6 +2,7 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Timeline } from "@versia/kit/db"; import { Timeline } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm"; import { and, gt, gte, lt, sql } from "drizzle-orm";
@ -9,7 +10,6 @@ import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,6 +2,7 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Timeline } from "@versia/kit/db"; import { Timeline } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm"; import { and, gt, gte, lt, sql } from "drizzle-orm";
@ -9,7 +10,6 @@ import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,10 +2,10 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,12 +2,12 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
import { import {
RelationshipJobType, RelationshipJobType,
relationshipQueue, relationshipQueue,

View file

@ -2,12 +2,12 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { User } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { User } from "~/classes/database/user";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -3,12 +3,12 @@ import {
RolePermission, RolePermission,
Role as RoleSchema, Role as RoleSchema,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Role } from "@versia/kit/db"; import { Role } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { validator } from "hono-openapi/zod"; import { validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => { export default apiRoute((app) => {
app.post( app.post(

View file

@ -3,6 +3,7 @@ import {
Status as StatusSchema, Status as StatusSchema,
zBoolean, zBoolean,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Timeline } from "@versia/kit/db"; import { Timeline } from "@versia/kit/db";
import { Notes } from "@versia/kit/tables"; import { Notes } from "@versia/kit/tables";
import { and, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm"; import { and, eq, gt, gte, inArray, isNull, lt, or, sql } from "drizzle-orm";
@ -10,7 +11,6 @@ import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, withUserParam } from "@/api"; import { apiRoute, auth, handleZodError, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Relationship as RelationshipSchema, Relationship as RelationshipSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth, withUserParam } from "@/api"; import { apiRoute, auth, withUserParam } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -3,6 +3,7 @@ import {
FamiliarFollowers as FamiliarFollowersSchema, FamiliarFollowers as FamiliarFollowersSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { db, User } from "@versia/kit/db"; import { db, User } from "@versia/kit/db";
import type { Users } from "@versia/kit/tables"; import type { Users } from "@versia/kit/tables";
import { type InferSelectModel, sql } from "drizzle-orm"; import { type InferSelectModel, sql } from "drizzle-orm";
@ -10,8 +11,7 @@ import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, qsQuery } from "@/api"; import { apiRoute, auth, handleZodError, qsQuery } from "@/api";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
import { rateLimit } from "~/middlewares/rate-limit";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -1,6 +1,8 @@
import { Account as AccountSchema, zBoolean } from "@versia/client/schemas"; import { Account as AccountSchema, zBoolean } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { User } from "@versia/kit/db"; import { User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
@ -8,9 +10,7 @@ import ISO6391 from "iso-639-1";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, jsonOrForm, qsQuery } from "@/api"; import { apiRoute, auth, handleZodError, jsonOrForm, qsQuery } from "@/api";
import { tempmailDomains } from "@/tempmail"; import { tempmailDomains } from "@/tempmail";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../middlewares/rate-limit.ts";
import { config } from "~/config.ts";
import { rateLimit } from "~/middlewares/rate-limit";
const schema = z.object({ const schema = z.object({
username: z.string().openapi({ username: z.string().openapi({

View file

@ -2,16 +2,16 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Instance, User } from "@versia/kit/db"; import { Instance, User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { config } from "@versia-server/config";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api"; import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
import { config } from "~/config.ts";
import { rateLimit } from "~/middlewares/rate-limit";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -4,13 +4,13 @@ import {
RolePermission, RolePermission,
zBoolean, zBoolean,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Relationship } from "@versia/kit/db"; import { Relationship } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, qsQuery } from "@/api"; import { apiRoute, auth, handleZodError, qsQuery } from "@/api";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
import { rateLimit } from "~/middlewares/rate-limit";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -3,6 +3,7 @@ import {
RolePermission, RolePermission,
zBoolean, zBoolean,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { User } from "@versia/kit/db"; import { User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { eq, ilike, not, or, sql } from "drizzle-orm"; import { eq, ilike, not, or, sql } from "drizzle-orm";
@ -11,8 +12,7 @@ import { resolver, validator } from "hono-openapi/zod";
import stringComparison from "string-comparison"; import stringComparison from "string-comparison";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api"; import { apiRoute, auth, handleZodError, parseUserAddress } from "@/api";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
import { rateLimit } from "~/middlewares/rate-limit";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -1,5 +1,5 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import { config } from "~/config.ts"; import { config } from "@versia-server/config";
import { generateClient, getTestUsers } from "~/tests/utils"; import { generateClient, getTestUsers } from "~/tests/utils";
const { users, deleteUsers } = await getTestUsers(1); const { users, deleteUsers } = await getTestUsers(1);

View file

@ -3,8 +3,11 @@ import {
RolePermission, RolePermission,
zBoolean, zBoolean,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Emoji, Media, User } from "@versia/kit/db"; import { Emoji, Media, User } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import * as VersiaEntities from "@versia/sdk/entities";
import { config } from "@versia-server/config";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
@ -12,11 +15,8 @@ import { z } from "zod";
import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api"; import { apiRoute, auth, handleZodError, jsonOrForm } from "@/api";
import { mergeAndDeduplicate } from "@/lib"; import { mergeAndDeduplicate } from "@/lib";
import { sanitizedHtmlStrip } from "@/sanitization"; import { sanitizedHtmlStrip } from "@/sanitization";
import { ApiError } from "~/classes/errors/api-error";
import { contentToHtml } from "~/classes/functions/status"; import { contentToHtml } from "~/classes/functions/status";
import { config } from "~/config.ts"; import { rateLimit } from "../../../../../middlewares/rate-limit.ts";
import { rateLimit } from "~/middlewares/rate-limit";
import * as VersiaEntities from "~/packages/sdk/entities";
export default apiRoute((app) => export default apiRoute((app) =>
app.patch( app.patch(

View file

@ -1,5 +1,5 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import { config } from "~/config"; import { config } from "@versia-server/config";
import { generateClient, getTestUsers } from "~/tests/utils"; import { generateClient, getTestUsers } from "~/tests/utils";
const { users, deleteUsers } = await getTestUsers(1); const { users, deleteUsers } = await getTestUsers(1);

View file

@ -1,8 +1,8 @@
import { Account } from "@versia/client/schemas"; import { Account } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth } from "@/api"; import { apiRoute, auth } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,6 +2,7 @@ import {
Application as ApplicationSchema, Application as ApplicationSchema,
CredentialApplication as CredentialApplicationSchema, CredentialApplication as CredentialApplicationSchema,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Application } from "@versia/kit/db"; import { Application } from "@versia/kit/db";
import { randomUUIDv7 } from "bun"; import { randomUUIDv7 } from "bun";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
@ -9,8 +10,7 @@ import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, handleZodError, jsonOrForm } from "@/api"; import { apiRoute, handleZodError, jsonOrForm } from "@/api";
import { randomString } from "@/math"; import { randomString } from "@/math";
import { ApiError } from "~/classes/errors/api-error"; import { rateLimit } from "../../../../middlewares/rate-limit.ts";
import { rateLimit } from "~/middlewares/rate-limit";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,11 +2,11 @@ import {
Application as ApplicationSchema, Application as ApplicationSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Application } from "@versia/kit/db"; import { Application } from "@versia/kit/db";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth } from "@/api"; import { apiRoute, auth } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -2,6 +2,7 @@ import {
Account as AccountSchema, Account as AccountSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Timeline } from "@versia/kit/db"; import { Timeline } from "@versia/kit/db";
import { Users } from "@versia/kit/tables"; import { Users } from "@versia/kit/tables";
import { and, gt, gte, lt, sql } from "drizzle-orm"; import { and, gt, gte, lt, sql } from "drizzle-orm";
@ -9,7 +10,6 @@ import { describeRoute } from "hono-openapi";
import { resolver, validator } from "hono-openapi/zod"; import { resolver, validator } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth, handleZodError } from "@/api"; import { apiRoute, auth, handleZodError } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

View file

@ -1,10 +1,10 @@
import { Challenge } from "@versia/client/schemas"; import { Challenge } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { config } from "@versia-server/config";
import { describeRoute } from "hono-openapi"; import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { apiRoute, auth } from "@/api"; import { apiRoute, auth } from "@/api";
import { generateChallenge } from "@/challenges"; import { generateChallenge } from "@/challenges";
import { ApiError } from "~/classes/errors/api-error";
import { config } from "~/config.ts";
export default apiRoute((app) => export default apiRoute((app) =>
app.post( app.post(

View file

@ -2,6 +2,7 @@ import {
CustomEmoji as CustomEmojiSchema, CustomEmoji as CustomEmojiSchema,
RolePermission, RolePermission,
} from "@versia/client/schemas"; } from "@versia/client/schemas";
import { ApiError } from "@versia/kit";
import { Emoji } from "@versia/kit/db"; import { Emoji } from "@versia/kit/db";
import { Emojis } from "@versia/kit/tables"; import { Emojis } from "@versia/kit/tables";
import { and, eq, isNull, or } from "drizzle-orm"; import { and, eq, isNull, or } from "drizzle-orm";
@ -9,7 +10,6 @@ import { describeRoute } from "hono-openapi";
import { resolver } from "hono-openapi/zod"; import { resolver } from "hono-openapi/zod";
import { z } from "zod"; import { z } from "zod";
import { apiRoute, auth } from "@/api"; import { apiRoute, auth } from "@/api";
import { ApiError } from "~/classes/errors/api-error";
export default apiRoute((app) => export default apiRoute((app) =>
app.get( app.get(

Some files were not shown because too many files have changed in this diff Show more