Files
lst/lstV2/server/globalUtils/apiHits.ts

75 lines
2.4 KiB
TypeScript

import type { Context } from "hono";
import { z, ZodError } from "zod";
import { getConnInfo } from "@hono/node-server/conninfo";
import { tryCatch } from "./tryCatch.js";
import { db } from "../../database/dbclient.js";
import { apiHits } from "../../database/schema/apiHits.js";
import { sql } from "drizzle-orm";
// Define the request body schema
const requestSchema = z.object({
ip: z.string().optional(),
endpoint: z.string(),
action: z.string().optional(),
lastBody: z.array(z.object({})).or(z.object({})).optional(),
stats: z.string().optional(),
});
type ApiHitData = z.infer<typeof requestSchema>;
export const apiHit = async (
c: Context,
data: ApiHitData
): Promise<{ success: boolean; data?: ApiHitData; errors?: any[] }> => {
const info = getConnInfo(c);
// console.log(`Your remote address is ${info.remote.address}`);
try {
// Extract IP from request headers or connection info
const forwarded = c.req.header("host");
//console.log(forwarded);
// Validate the data
const checkData = {
ip: info.remote.address!,
endpoint: data?.endpoint,
lastBody: data?.lastBody,
action: data?.action,
//stats: data?.stats,
};
const validatedData = requestSchema.parse(checkData);
const { data: apitHitData, error } = await tryCatch(
db
.insert(apiHits)
.values(checkData)
.onConflictDoUpdate({
target: [apiHits.endpoint, apiHits.ip],
set: {
stats: sql`${apiHits.stats} + 1`,
lastBody: data?.lastBody,
action: data?.action,
upd_date: sql`NOW()`,
},
})
);
if (error) {
console.log(error);
}
// Proceed with the validated data
return { success: true, data: validatedData };
} catch (error) {
// Explicitly check if the error is an instance of ZodError
if (error instanceof ZodError) {
console.log({ success: false, errors: error.errors });
return { success: false, errors: error.errors };
}
// Catch other unexpected errors
return {
success: false,
errors: [{ message: "An unknown error occurred" }],
};
}
};