Basic instance stuff
This commit is contained in:
10
concord-server/src/controller/instanceController.ts
Normal file
10
concord-server/src/controller/instanceController.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { createInstance, getAllInstances } from "../services/instanceService";
|
||||||
|
import { CreateInstanceRequest } from "../validators/instanceValidator";
|
||||||
|
|
||||||
|
export async function createInstanceReq(data:CreateInstanceRequest) {
|
||||||
|
return await createInstance(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAllInstancesReq() {
|
||||||
|
return await getAllInstances();
|
||||||
|
}
|
||||||
@@ -3,11 +3,13 @@ import { Hono } from "hono";
|
|||||||
import userRoutes from "./userRoutes";
|
import userRoutes from "./userRoutes";
|
||||||
import messageRoutes from "./messageRoutes";
|
import messageRoutes from "./messageRoutes";
|
||||||
import channelRoutes from "./channelRoutes";
|
import channelRoutes from "./channelRoutes";
|
||||||
|
import instanceRoutes from "./instanceRoutes";
|
||||||
|
|
||||||
const routes = new Hono();
|
const routes = new Hono();
|
||||||
|
|
||||||
routes.route("/user", userRoutes);
|
routes.route("/user", userRoutes);
|
||||||
routes.route("/message", messageRoutes);
|
routes.route("/message", messageRoutes);
|
||||||
routes.route("/channel", channelRoutes);
|
routes.route("/channel", channelRoutes);
|
||||||
|
routes.route("/instance", instanceRoutes);
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|||||||
63
concord-server/src/routes/instanceRoutes.ts
Normal file
63
concord-server/src/routes/instanceRoutes.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { Hono } from "hono";
|
||||||
|
import { describeRoute, resolver } from "hono-openapi";
|
||||||
|
import { createInstanceRequestSchema, getAllInstancesResponseSchema } from "../validators/instanceValidator";
|
||||||
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { createInstanceReq, getAllInstancesReq } from "../controller/instanceController";
|
||||||
|
|
||||||
|
const instanceRoutes = new Hono();
|
||||||
|
|
||||||
|
instanceRoutes.post(
|
||||||
|
"",
|
||||||
|
describeRoute({
|
||||||
|
description: "Create instance",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Instance created",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createInstanceRequestSchema) }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Invalid request",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
zValidator('json', createInstanceRequestSchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = await c.req.json();
|
||||||
|
if (!data) {
|
||||||
|
return c.json({ error: "could not parse data" }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = await createInstanceReq(data);
|
||||||
|
return c.json(instance, 201);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
instanceRoutes.get(
|
||||||
|
"",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get all instances",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "List of all instances",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(getAllInstancesResponseSchema) }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
description: "Server error",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const instances = await getAllInstancesReq();
|
||||||
|
if (instances.success) {
|
||||||
|
return c.json(instances, 200);
|
||||||
|
} else {
|
||||||
|
return c.json({ success: false, error: instances.error || "Failed to fetch instances" }, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default instanceRoutes;
|
||||||
57
concord-server/src/services/instanceService.ts
Normal file
57
concord-server/src/services/instanceService.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import { CreateInstanceRequest } from "../validators/instanceValidator";
|
||||||
|
import { getUserCredentials, getUserInformation } from "./userService";
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
export async function createInstance(data: CreateInstanceRequest) {
|
||||||
|
try {
|
||||||
|
const creds = await getUserCredentials(data.requestingUserId);
|
||||||
|
const user = await getUserInformation(data.requestingUserId);
|
||||||
|
if (!creds
|
||||||
|
|| creds.token != data.requestingUserToken
|
||||||
|
|| !user
|
||||||
|
|| !user.admin) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newInstance = await prisma.instance.create({
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
icon: data.icon
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: newInstance
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating instance:", error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: "Failed to create instance"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAllInstances() {
|
||||||
|
try {
|
||||||
|
const instances = await prisma.instance.findMany({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: instances
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching instances:", error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: "Failed to fetch instances"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -256,10 +256,7 @@ export async function getAllUsersFrom(instanceId: string): Promise<
|
|||||||
).includes(u.status as any)
|
).includes(u.status as any)
|
||||||
? (u.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
? (u.status as "online" | "offline" | "dnd" | "idle" | "invis")
|
||||||
: "offline",
|
: "offline",
|
||||||
role: adminRoles.map((r) => ({
|
role: adminRoles,
|
||||||
userId: r.userId,
|
|
||||||
instanceId: r.instanceId,
|
|
||||||
})),
|
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
29
concord-server/src/validators/instanceValidator.ts
Normal file
29
concord-server/src/validators/instanceValidator.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const createInstanceRequestSchema = z.object({
|
||||||
|
name: z.string().min(1, 'Instance name cannot be empty'),
|
||||||
|
icon: z.url().optional(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.string()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getAllInstancesResponseSchema = z.object({
|
||||||
|
success: z.boolean(),
|
||||||
|
data: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
icon: z.string().nullable(),
|
||||||
|
createdAt: z.string().refine((val) => !isNaN(Date.parse(val)), {
|
||||||
|
message: "Invalid date string format"
|
||||||
|
}),
|
||||||
|
updatedAt: z.string().refine((val) => !isNaN(Date.parse(val)), {
|
||||||
|
message: "Invalid date string format"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
).optional(),
|
||||||
|
error: z.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CreateInstanceRequest = z.infer<typeof createInstanceRequestSchema>;
|
||||||
|
export type GetAllInstancesResponse = z.infer<typeof getAllInstancesResponseSchema>;
|
||||||
Reference in New Issue
Block a user