mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 00:18:19 +01:00
fix: 🚨 Enable more Biome 2.0 rules
Some checks failed
CodeQL Scan / Analyze (javascript-typescript) (push) Failing after 4s
Build Docker Images / lint (push) Failing after 10s
Build Docker Images / check (push) Failing after 10s
Build Docker Images / tests (push) Failing after 6s
Deploy Docs to GitHub Pages / build (push) Failing after 0s
Build Docker Images / build (server, Dockerfile, ${{ github.repository_owner }}/server) (push) Has been skipped
Build Docker Images / build (worker, Worker.Dockerfile, ${{ github.repository_owner }}/worker) (push) Has been skipped
Deploy Docs to GitHub Pages / Deploy (push) Has been skipped
Mirror to Codeberg / Mirror (push) Failing after 0s
Nix Build / check (push) Failing after 0s
Some checks failed
CodeQL Scan / Analyze (javascript-typescript) (push) Failing after 4s
Build Docker Images / lint (push) Failing after 10s
Build Docker Images / check (push) Failing after 10s
Build Docker Images / tests (push) Failing after 6s
Deploy Docs to GitHub Pages / build (push) Failing after 0s
Build Docker Images / build (server, Dockerfile, ${{ github.repository_owner }}/server) (push) Has been skipped
Build Docker Images / build (worker, Worker.Dockerfile, ${{ github.repository_owner }}/worker) (push) Has been skipped
Deploy Docs to GitHub Pages / Deploy (push) Has been skipped
Mirror to Codeberg / Mirror (push) Failing after 0s
Nix Build / check (push) Failing after 0s
This commit is contained in:
parent
963173cdae
commit
1679585c4c
3
app.ts
3
app.ts
|
|
@ -27,6 +27,7 @@ import { routes } from "./routes.ts";
|
|||
import type { ApiRouteExports, HonoEnv } from "./types/api.ts";
|
||||
// Extends Zod with OpenAPI schema generation
|
||||
import "zod-openapi/extend";
|
||||
import { cwd } from "node:process";
|
||||
|
||||
export const appFactory = async (): Promise<Hono<HonoEnv>> => {
|
||||
await configureLoggers();
|
||||
|
|
@ -121,7 +122,7 @@ export const appFactory = async (): Promise<Hono<HonoEnv>> => {
|
|||
const loader = new PluginLoader();
|
||||
|
||||
const plugins = await loader.loadPlugins(
|
||||
join(process.cwd(), "plugins"),
|
||||
join(cwd(), "plugins"),
|
||||
config.plugins?.autoload ?? true,
|
||||
config.plugins?.overrides.enabled,
|
||||
config.plugins?.overrides.disabled,
|
||||
|
|
|
|||
58
biome.json
58
biome.json
|
|
@ -45,6 +45,23 @@
|
|||
},
|
||||
"useLiteralEnumMembers": "error",
|
||||
"noCommaOperator": "error",
|
||||
"noNegationElse": "error",
|
||||
"noYodaExpression": "error",
|
||||
"useBlockStatements": "error",
|
||||
"useCollapsedElseIf": "error",
|
||||
"useConsistentArrayType": {
|
||||
"level": "error",
|
||||
"options": {
|
||||
"syntax": "shorthand"
|
||||
}
|
||||
},
|
||||
"useConsistentBuiltinInstantiation": "error",
|
||||
"useExplicitLengthCheck": "error",
|
||||
"useForOf": "error",
|
||||
"useNodeAssertStrict": "error",
|
||||
"useShorthandAssign": "error",
|
||||
"useThrowNewError": "error",
|
||||
"useThrowOnlyError": "error",
|
||||
"useNodejsImportProtocol": "error",
|
||||
"useAsConstAssertion": "error",
|
||||
"useNumericLiterals": "error",
|
||||
|
|
@ -67,16 +84,39 @@
|
|||
"useShorthandFunctionType": "error"
|
||||
},
|
||||
"correctness": {
|
||||
"useImportExtensions": "error"
|
||||
"useImportExtensions": "error",
|
||||
"noConstantMathMinMaxClamp": "error",
|
||||
"noUndeclaredDependencies": "error",
|
||||
"noUnusedFunctionParameters": "error",
|
||||
"noUnusedImports": "error",
|
||||
"noUnusedPrivateClassMembers": "error",
|
||||
"useArrayLiterals": "error"
|
||||
},
|
||||
"nursery": {
|
||||
"noBitwiseOperators": "error",
|
||||
"noConstantBinaryExpression": "error",
|
||||
"noFloatingPromises": "error",
|
||||
"noGlobalDirnameFilename": "error",
|
||||
"noOctalEscape": "error",
|
||||
"noProcessEnv": "error",
|
||||
"noDuplicateElseIf": "warn",
|
||||
"noProcessGlobal": "warn",
|
||||
"noTsIgnore": "warn",
|
||||
"useAtIndex": "warn",
|
||||
"useCollapsedIf": "warn",
|
||||
"useConsistentObjectDefinition": {
|
||||
"level": "warn",
|
||||
"options": {
|
||||
"syntax": "shorthand"
|
||||
}
|
||||
},
|
||||
"useConsistentMemberAccessibility": {
|
||||
"level": "warn",
|
||||
"options": {
|
||||
"accessibility": "explicit"
|
||||
}
|
||||
},
|
||||
"useParseIntRadix": "warn",
|
||||
"noCommonJs": "warn",
|
||||
"noDynamicNamespaceImportAccess": "warn",
|
||||
"noExportedImports": "warn",
|
||||
|
|
@ -91,11 +131,21 @@
|
|||
"useTrimStartEnd": "warn"
|
||||
},
|
||||
"complexity": {
|
||||
"noExcessiveCognitiveComplexity": "off"
|
||||
"noForEach": "error",
|
||||
"noUselessStringConcat": "error",
|
||||
"useDateNow": "error",
|
||||
"useSimplifiedLogicExpression": "error",
|
||||
"useWhile": "error"
|
||||
},
|
||||
"suspicious": {
|
||||
"noMisplacedAssertion": "off",
|
||||
"noConsole": "off"
|
||||
"noDuplicateTestHooks": "error",
|
||||
"noEmptyBlockStatements": "error",
|
||||
"noEvolvingTypes": "error",
|
||||
"noExportsInTest": "error",
|
||||
"noVar": "error",
|
||||
"useAwait": "error",
|
||||
"useErrorMessage": "error",
|
||||
"useNumberToFixedDigitsArgument": "error"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
9
bun.lock
9
bun.lock
|
|
@ -93,12 +93,16 @@
|
|||
"version": "0.2.0-alpha.1",
|
||||
"dependencies": {
|
||||
"@badgateway/oauth2-client": "^2.4.2",
|
||||
"iso-639-1": "^3.1.5",
|
||||
"zod": "^3.24.2",
|
||||
},
|
||||
},
|
||||
"packages/plugin-kit": {
|
||||
"name": "@versia/kit",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"hono": "^4.7.6",
|
||||
"mitt": "^3.0.1",
|
||||
"zod": "^3.23.8",
|
||||
"zod-to-json-schema": "^3.23.3",
|
||||
|
|
@ -108,6 +112,11 @@
|
|||
"packages/sdk": {
|
||||
"name": "@versia/sdk",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"magic-regexp": "^0.9.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"zod": "^3.24.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
"trustedDependencies": [
|
||||
|
|
|
|||
|
|
@ -141,11 +141,11 @@ export class Timeline<Type extends Note | User | Notification> {
|
|||
|
||||
if (notes.length >= (limit ?? 20)) {
|
||||
const objectAfter = await Note.fromSql(
|
||||
gt(Notes.id, notes[notes.length - 1].data.id),
|
||||
gt(Notes.id, notes.at(-1)?.data.id ?? ""),
|
||||
);
|
||||
if (objectAfter) {
|
||||
linkHeader.push(
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${notes[notes.length - 1].data.id}>; rel="next"`,
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${notes.at(-1)?.data.id}>; rel="next"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -169,11 +169,11 @@ export class Timeline<Type extends Note | User | Notification> {
|
|||
|
||||
if (users.length >= (limit ?? 20)) {
|
||||
const objectAfter = await User.fromSql(
|
||||
gt(Users.id, users[users.length - 1].id),
|
||||
gt(Users.id, users.at(-1)?.id ?? ""),
|
||||
);
|
||||
if (objectAfter) {
|
||||
linkHeader.push(
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${users[users.length - 1].id}>; rel="next"`,
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${users.at(-1)?.id}>; rel="next"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -199,14 +199,11 @@ export class Timeline<Type extends Note | User | Notification> {
|
|||
|
||||
if (notifications.length >= (limit ?? 20)) {
|
||||
const objectAfter = await Notification.fromSql(
|
||||
gt(
|
||||
Notifications.id,
|
||||
notifications[notifications.length - 1].data.id,
|
||||
),
|
||||
gt(Notifications.id, notifications.at(-1)?.data.id ?? ""),
|
||||
);
|
||||
if (objectAfter) {
|
||||
linkHeader.push(
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${notifications[notifications.length - 1].data.id}>; rel="next"`,
|
||||
`<${urlWithoutQuery}?limit=${limit ?? 20}&max_id=${notifications.at(-1)?.data.id}>; rel="next"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
await note.author.notify("favourite", this, note);
|
||||
} else if (this.local && note.author.remote) {
|
||||
// Federate the like
|
||||
this.federateToFollowers(newLike.toVersia());
|
||||
await this.federateToFollowers(newLike.toVersia());
|
||||
}
|
||||
|
||||
return newLike;
|
||||
|
|
@ -528,7 +528,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
await likeToDelete.clearRelatedNotifications();
|
||||
} else if (this.local && note.author.remote) {
|
||||
// User is local, federate the delete
|
||||
this.federateToFollowers(likeToDelete.unlikeToVersia(this));
|
||||
await this.federateToFollowers(likeToDelete.unlikeToVersia(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const isConvertible = (
|
|||
*/
|
||||
const extractFilenameFromPath = (path: string): string => {
|
||||
const pathParts = path.split(/(?<!\\)\//);
|
||||
return pathParts[pathParts.length - 1];
|
||||
return pathParts.at(-1) as string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import ora from "ora";
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import chalk from "chalk";
|
||||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { Instance } from "~/classes/database/instance.ts";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import chalk from "chalk";
|
||||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import { renderUnicodeCompact } from "uqr";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import confirm from "@inquirer/confirm";
|
||||
import chalk from "chalk";
|
||||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import { retrieveUser } from "../utils.ts";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import chalk from "chalk";
|
||||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import ora from "ora";
|
||||
import { User } from "~/classes/database/user.ts";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { randomUUIDv7 } from "bun";
|
||||
import chalk from "chalk";
|
||||
// @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
|
||||
import { defineCommand, type Root } from "clerc";
|
||||
import { randomString } from "@/math.ts";
|
||||
import { Token } from "~/classes/database/token.ts";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import cluster from "node:cluster";
|
||||
import process from "node:process";
|
||||
import { Youch } from "youch";
|
||||
import { sentry } from "@/sentry";
|
||||
import { createServer } from "@/server";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import process from "node:process";
|
||||
import { getLogger } from "@logtape/logtape";
|
||||
import chalk from "chalk";
|
||||
import { sentry } from "@/sentry";
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@ export const boundaryCheck = createMiddleware(async (context, next) => {
|
|||
// Checks that FormData boundary is present
|
||||
const contentType = context.req.header("content-type");
|
||||
|
||||
if (contentType?.includes("multipart/form-data")) {
|
||||
if (!contentType.includes("boundary")) {
|
||||
throw new ApiError(
|
||||
400,
|
||||
"Missing FormData boundary",
|
||||
"You are sending a request with a multipart/form-data content type but without a boundary. Please include a boundary in the Content-Type header. For more information, visit https://stackoverflow.com/questions/3508338/what-is-the-boundary-in-multipart-form-data",
|
||||
);
|
||||
}
|
||||
if (
|
||||
contentType?.includes("multipart/form-data") &&
|
||||
!contentType.includes("boundary")
|
||||
) {
|
||||
throw new ApiError(
|
||||
400,
|
||||
"Missing FormData boundary",
|
||||
"You are sending a request with a multipart/form-data content type but without a boundary. Please include a boundary in the Content-Type header. For more information, visit https://stackoverflow.com/questions/3508338/what-is-the-boundary-in-multipart-form-data",
|
||||
);
|
||||
}
|
||||
|
||||
await next();
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@
|
|||
],
|
||||
"packageManager": "bun@1.2.5",
|
||||
"dependencies": {
|
||||
"@badgateway/oauth2-client": "^2.4.2"
|
||||
"@badgateway/oauth2-client": "^2.4.2",
|
||||
"iso-639-1": "^3.1.5",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,11 +151,9 @@ export class BaseClient {
|
|||
if (this.accessToken) {
|
||||
headers.set("Authorization", `Bearer ${this.accessToken}`);
|
||||
}
|
||||
if (body) {
|
||||
if (!(body instanceof FormData)) {
|
||||
headers.set("Content-Type", "application/json; charset=utf-8");
|
||||
} // else: let FormData set the content type, as it knows best (boundary, etc.)
|
||||
}
|
||||
if (body && !(body instanceof FormData)) {
|
||||
headers.set("Content-Type", "application/json; charset=utf-8");
|
||||
} // else: let FormData set the content type, as it knows best (boundary, etc.)
|
||||
|
||||
for (const [key, value] of Object.entries(extra?.headers || {})) {
|
||||
headers.set(key, value);
|
||||
|
|
|
|||
|
|
@ -1229,10 +1229,8 @@ export class Client extends BaseClient {
|
|||
): Promise<Output<z.infer<typeof Account>[]>> {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (options) {
|
||||
if (options.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
if (options?.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
|
||||
return this.get<z.infer<typeof Account>[]>(
|
||||
|
|
@ -1449,10 +1447,8 @@ export class Client extends BaseClient {
|
|||
): Promise<Output<z.infer<typeof Tag>[]>> {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (options) {
|
||||
if (options.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
if (options?.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
|
||||
return this.get<z.infer<typeof Tag>[]>(`/api/v1/trends?${params}`);
|
||||
|
|
@ -1839,10 +1835,8 @@ export class Client extends BaseClient {
|
|||
params.append("id[]", id);
|
||||
}
|
||||
|
||||
if (options) {
|
||||
if (options.with_suspended) {
|
||||
params.set("with_suspended", "true");
|
||||
}
|
||||
if (options?.with_suspended) {
|
||||
params.set("with_suspended", "true");
|
||||
}
|
||||
|
||||
return this.get<z.infer<typeof Relationship>[]>(
|
||||
|
|
@ -2121,10 +2115,8 @@ export class Client extends BaseClient {
|
|||
): Promise<Output<z.infer<typeof Account>[]>> {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (options) {
|
||||
if (options.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
if (options?.limit) {
|
||||
params.set("limit", options.limit.toString());
|
||||
}
|
||||
|
||||
return this.get<z.infer<typeof Account>[]>(
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"hono": "^4.7.6",
|
||||
"mitt": "^3.0.1",
|
||||
"zod": "^3.23.8",
|
||||
"zod-to-json-schema": "^3.23.3",
|
||||
|
|
|
|||
|
|
@ -71,5 +71,10 @@
|
|||
"typescript",
|
||||
"sdk"
|
||||
],
|
||||
"packageManager": "bun@1.2.5"
|
||||
"packageManager": "bun@1.2.5",
|
||||
"dependencies": {
|
||||
"magic-regexp": "^0.9.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import { join } from "node:path";
|
||||
import { cwd } from "node:process";
|
||||
import { FileSystemRouter } from "bun";
|
||||
// Returns the route filesystem path when given a URL
|
||||
export const routeMatcher = new FileSystemRouter({
|
||||
style: "nextjs",
|
||||
dir: `${process.cwd()}/api`,
|
||||
dir: `${cwd()}/api`,
|
||||
fileExtensions: [".ts", ".js"],
|
||||
});
|
||||
|
||||
export const routes = Object.fromEntries(
|
||||
Object.entries(routeMatcher.routes)
|
||||
.filter(([route]) => !route.endsWith(".test"))
|
||||
.map(([route, path]) => [
|
||||
route,
|
||||
path.replace(join(process.cwd()), "."),
|
||||
]),
|
||||
.map(([route, path]) => [route, path.replace(join(cwd()), ".")]),
|
||||
) as Record<string, string>;
|
||||
|
|
|
|||
Loading…
Reference in a new issue