mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 00:18:19 +01:00
feat(api): ✨ Implement /v1/instance/rules and /v1/instance/extended_description
This commit is contained in:
parent
5b0d2014ff
commit
96a2fbf178
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -173,4 +173,5 @@ uploads/
|
|||
pages/dist
|
||||
log.txt
|
||||
*.log
|
||||
build
|
||||
build
|
||||
config/extended_description_test.md
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
|
@ -2,5 +2,5 @@
|
|||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"jest.jestCommandLine": "/home/jessew/.bun/bin/bun test",
|
||||
"jest.rootPath": ".",
|
||||
"conventionalCommits.scopes": ["database", "frontend", "build"]
|
||||
"conventionalCommits.scopes": ["database", "frontend", "build", "api"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,6 +286,9 @@ avatars = []
|
|||
[instance]
|
||||
name = "Lysand"
|
||||
description = "A test instance of Lysand"
|
||||
# Path to a file containing a longer description of your instance
|
||||
# This will be parsed as Markdown
|
||||
extended_description_path = ""
|
||||
# URL to your instance logo (jpg files should be renamed to jpeg)
|
||||
logo = ""
|
||||
# URL to your instance banner (jpg files should be renamed to jpeg)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ cd /app/dist
|
|||
# Parse first argument
|
||||
case "$1" in
|
||||
"start")
|
||||
NITRO_PORT=5173 bun run ./frontend/server/index.mjs & NODE_ENV=production bun run ./index.js --prod
|
||||
NODE_ENV=production bun run ./index.js --prod
|
||||
;;
|
||||
"cli")
|
||||
# Start the CLI
|
||||
|
|
|
|||
13
index.ts
13
index.ts
|
|
@ -1,14 +1,23 @@
|
|||
import { dualLogger } from "@loggers";
|
||||
import { connectMeili } from "@meilisearch";
|
||||
import { config } from "config-manager";
|
||||
import { count } from "drizzle-orm";
|
||||
import { LogLevel } from "log-manager";
|
||||
import { LogLevel, LogManager, type MultiLogManager } from "log-manager";
|
||||
import { db, setupDatabase } from "~drizzle/db";
|
||||
import { status } from "~drizzle/schema";
|
||||
import { createServer } from "~server";
|
||||
|
||||
const timeAtStart = performance.now();
|
||||
|
||||
const isEntry = import.meta.path === Bun.main;
|
||||
|
||||
let dualLogger: LogManager | MultiLogManager = new LogManager(
|
||||
Bun.file("/dev/null"),
|
||||
);
|
||||
|
||||
if (isEntry) {
|
||||
dualLogger = (await import("@loggers")).dualLogger;
|
||||
}
|
||||
|
||||
await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
|
||||
|
||||
await setupDatabase(dualLogger);
|
||||
|
|
|
|||
|
|
@ -315,6 +315,9 @@ export interface Config {
|
|||
/** @default "A test instance of Lysand" */
|
||||
description: string;
|
||||
|
||||
/** @default "" */
|
||||
extended_description_path: string;
|
||||
|
||||
/** @default "" */
|
||||
logo: string;
|
||||
|
||||
|
|
@ -589,6 +592,7 @@ export const defaultConfig: Config = {
|
|||
instance: {
|
||||
name: "Lysand",
|
||||
description: "A test instance of Lysand",
|
||||
extended_description_path: "",
|
||||
logo: "",
|
||||
banner: "",
|
||||
},
|
||||
|
|
|
|||
23
server/api/api/v1/instance/extended_description.test.ts
Normal file
23
server/api/api/v1/instance/extended_description.test.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { meta } from "./extended_description";
|
||||
import { sendTestRequest } from "~tests/utils";
|
||||
import { config } from "config-manager";
|
||||
|
||||
// /api/v1/instance/extended_description
|
||||
describe(meta.route, () => {
|
||||
test("should return extended description", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(new URL(meta.route, config.http.base_url)),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual({
|
||||
updated_at: new Date(2024, 0, 0).toISOString(),
|
||||
// This is a [Lysand](https://lysand.org) server with the default extended description.
|
||||
content:
|
||||
'<p>This is a <a href="https://lysand.org">Lysand</a> server with the default extended description.</p>\n',
|
||||
});
|
||||
});
|
||||
});
|
||||
47
server/api/api/v1/instance/extended_description.ts
Normal file
47
server/api/api/v1/instance/extended_description.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { dualLogger } from "@loggers";
|
||||
import { jsonResponse } from "@response";
|
||||
import { parse } from "marked";
|
||||
import { LogLevel } from "~packages/log-manager";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
route: "/api/v1/instance/extended_description",
|
||||
ratelimits: {
|
||||
max: 300,
|
||||
duration: 60,
|
||||
},
|
||||
auth: {
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
let extended_description = parse(
|
||||
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
||||
);
|
||||
let lastModified = new Date(2024, 0, 0);
|
||||
|
||||
const extended_description_file = Bun.file(
|
||||
config.instance.extended_description_path,
|
||||
);
|
||||
|
||||
if (await extended_description_file.exists()) {
|
||||
extended_description =
|
||||
(await parse(
|
||||
(await extended_description_file.text().catch(async (e) => {
|
||||
await dualLogger.logError(LogLevel.ERROR, "Routes", e);
|
||||
return "";
|
||||
})) ||
|
||||
"This is a [Lysand](https://lysand.org) server with the default extended description.",
|
||||
)) || "";
|
||||
lastModified = new Date(extended_description_file.lastModified);
|
||||
}
|
||||
|
||||
return jsonResponse({
|
||||
updated_at: lastModified.toISOString(),
|
||||
content: extended_description,
|
||||
});
|
||||
});
|
||||
23
server/api/api/v1/instance/rules.test.ts
Normal file
23
server/api/api/v1/instance/rules.test.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { meta } from "./rules";
|
||||
import { sendTestRequest } from "~tests/utils";
|
||||
import { config } from "config-manager";
|
||||
|
||||
// /api/v1/instance/rules
|
||||
describe(meta.route, () => {
|
||||
test("should return rules", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(new URL(meta.route, config.http.base_url)),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = await response.json();
|
||||
expect(json).toEqual(
|
||||
config.signups.rules.map((rule, index) => ({
|
||||
id: String(index),
|
||||
text: rule,
|
||||
})),
|
||||
);
|
||||
});
|
||||
});
|
||||
25
server/api/api/v1/instance/rules.ts
Normal file
25
server/api/api/v1/instance/rules.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
route: "/api/v1/instance/rules",
|
||||
ratelimits: {
|
||||
max: 300,
|
||||
duration: 60,
|
||||
},
|
||||
auth: {
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
return jsonResponse(
|
||||
config.signups.rules.map((rule, index) => ({
|
||||
id: String(index),
|
||||
text: rule,
|
||||
})),
|
||||
);
|
||||
});
|
||||
|
|
@ -9,7 +9,6 @@ import {
|
|||
import { db } from "~drizzle/db";
|
||||
import { status, token, user } from "~drizzle/schema";
|
||||
import { server } from "~index";
|
||||
|
||||
/**
|
||||
* This allows us to send a test request to the server even when it isnt running
|
||||
* CURRENTLY NOT WORKING, NEEDS TO BE FIXED
|
||||
|
|
|
|||
Loading…
Reference in a new issue