All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 8m58s
132 lines
4.3 KiB
TypeScript
132 lines
4.3 KiB
TypeScript
import "server-only";
|
|
import { admin, required } from "./supabase";
|
|
import { z } from "zod";
|
|
import { ServiceError } from "./service-error";
|
|
export type MapListing = {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
source: "plugin" | "fabric";
|
|
state: string;
|
|
parent_dataset_id: string | null;
|
|
contribution_status: string | null;
|
|
allow_contributions: boolean;
|
|
contribution_server_address: string | null;
|
|
update_state: string | null;
|
|
bounds: { minX: number; minZ: number; maxX: number; maxZ: number };
|
|
panorama_count: number;
|
|
server_id: string;
|
|
owner_id: string | null;
|
|
cover_path: string | null;
|
|
map_path: string | null;
|
|
rejection_reason: string | null;
|
|
report_strikes: number;
|
|
banned_at: string | null;
|
|
ban_reason: string | null;
|
|
image?: string;
|
|
mapImage?: string;
|
|
credit?: string;
|
|
creditGlow?: boolean;
|
|
creditAppearance?: import("../shared/profile-appearance").ProfileAppearance;
|
|
};
|
|
export async function mediaUrl(path: string | null, expires = 3600) {
|
|
return (await mediaUrls([path], expires))[0];
|
|
}
|
|
export async function mediaUrls(paths: (string | null)[], expires = 3600) {
|
|
const unique = [...new Set(paths.filter((path): path is string => !!path))];
|
|
if (!unique.length) return paths.map(() => null);
|
|
const { data, error } = await admin()
|
|
.storage.from("minegeo-media")
|
|
.createSignedUrls(unique, expires);
|
|
if (error || !data || data.some((item) => item.error || !item.signedUrl))
|
|
throw new ServiceError(
|
|
"Map images are temporarily unavailable. Please try again.",
|
|
);
|
|
const signed = new Map(
|
|
data.map((item, index) => [unique[index], item.signedUrl]),
|
|
);
|
|
return paths.map((path) => (path ? (signed.get(path) ?? null) : null));
|
|
}
|
|
export async function catalog() {
|
|
const client = admin();
|
|
const [mapResult, serverResult] = await Promise.all([
|
|
client
|
|
.from("datasets")
|
|
.select("*")
|
|
.eq("state", "published")
|
|
.order("created_at", { ascending: false }),
|
|
client.from("catalog_servers").select("*"),
|
|
]);
|
|
const maps = required(mapResult) as unknown as MapListing[];
|
|
const servers = required(serverResult) as {
|
|
id: string;
|
|
name: string;
|
|
address: string | null;
|
|
}[];
|
|
const ownerIds = [
|
|
...new Set(maps.flatMap((map) => (map.owner_id ? [map.owner_id] : []))),
|
|
];
|
|
const [ownersResult, signed] = await Promise.all([
|
|
ownerIds.length
|
|
? client
|
|
.from("profiles")
|
|
.select(
|
|
"id,display_name,avatar_path,name_glow,glow_color,role,bug_finder,custom_prefix,custom_prefix_icon",
|
|
)
|
|
.in("id", ownerIds)
|
|
: Promise.resolve({ data: [], error: null }),
|
|
mediaUrls(
|
|
maps.flatMap((map) => [map.map_path || map.cover_path, map.map_path]),
|
|
),
|
|
]);
|
|
const owners = new Map(
|
|
required(ownersResult).map((owner) => [owner.id, owner]),
|
|
);
|
|
const serverById = new Map(servers.map((server) => [server.id, server]));
|
|
return maps.map((m, index) => ({
|
|
...m,
|
|
credit:
|
|
owners.get(m.owner_id ?? "")?.display_name ??
|
|
(m.owner_id ? "Explorer" : "Deleted player"),
|
|
creditGlow: owners.get(m.owner_id ?? "")?.name_glow ?? false,
|
|
creditAppearance: owners.get(m.owner_id ?? ""),
|
|
image: signed[index * 2] ?? undefined,
|
|
mapImage: signed[index * 2 + 1] ?? undefined,
|
|
server: serverById.get(m.server_id),
|
|
}));
|
|
}
|
|
export async function getMap(id: string) {
|
|
if (!z.string().uuid().safeParse(id).success) return null;
|
|
const result = await admin()
|
|
.from("datasets")
|
|
.select("*")
|
|
.eq("id", id)
|
|
.eq("state", "published")
|
|
.maybeSingle();
|
|
if (result.error) required(result);
|
|
if (!result.data) return null;
|
|
const map = result.data as unknown as MapListing;
|
|
const [owner, signed] = await Promise.all([
|
|
map.owner_id
|
|
? admin()
|
|
.from("profiles")
|
|
.select(
|
|
"display_name,avatar_path,name_glow,glow_color,role,bug_finder,custom_prefix,custom_prefix_icon",
|
|
)
|
|
.eq("id", map.owner_id)
|
|
.maybeSingle()
|
|
: Promise.resolve({ data: null }),
|
|
mediaUrls([map.cover_path, map.map_path]),
|
|
]);
|
|
return {
|
|
...map,
|
|
credit:
|
|
owner.data?.display_name ??
|
|
(map.owner_id ? "Explorer" : "Deleted player"),
|
|
creditGlow: owner.data?.name_glow ?? false,
|
|
creditAppearance: owner.data ?? undefined,
|
|
image: signed[0],
|
|
mapImage: signed[1],
|
|
};
|
|
}
|