Updates and more
This commit is contained in:
11
src/components/repo/data.ts
Normal file
11
src/components/repo/data.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type {Server} from "../types/data.ts";
|
||||
import {ServerSchema} from "../types/data.ts";
|
||||
import {fetchWithToken} from "./repo.ts";
|
||||
|
||||
export class DataRepo {
|
||||
constructor(private token: string) {}
|
||||
|
||||
public async getServer(): Promise<Server> {
|
||||
return await fetchWithToken(this.token, "/data/server").then(value => value.json()).then(value => ServerSchema.parse(value));
|
||||
}
|
||||
}
|
||||
96
src/components/repo/event.ts
Normal file
96
src/components/repo/event.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import type {ExtendedEvent, ShortEvent, SWEvent} from "../types/event.js";
|
||||
import {fetchWithToken} from "./repo.js";
|
||||
import type {Moment} from "moment";
|
||||
import {ExtendedEventSchema, ShortEventSchema, SWEventSchema} from "../types/event.js";
|
||||
import {z} from "zod";
|
||||
|
||||
export interface CreateEvent {
|
||||
name: string
|
||||
start: Moment
|
||||
end: Moment
|
||||
}
|
||||
|
||||
export interface UpdateEvent {
|
||||
name: string
|
||||
start: Moment
|
||||
end: Moment
|
||||
deadline: Moment
|
||||
maxTeamMembers: number
|
||||
schemType: string | null
|
||||
publicSchemsOnly: boolean
|
||||
spectateSystem: boolean
|
||||
}
|
||||
|
||||
export class EventRepo {
|
||||
constructor(private token: string) {}
|
||||
|
||||
public async listEvents(): Promise<ShortEvent[]> {
|
||||
const res = await fetchWithToken(this.token, "/events");
|
||||
|
||||
if (res.ok) {
|
||||
return z.array(ShortEventSchema).parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not fetch events: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async getEvent(id: string): Promise<ExtendedEvent> {
|
||||
const res = await fetchWithToken(this.token, `/events/${id}`);
|
||||
|
||||
if (res.ok) {
|
||||
return ExtendedEventSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not fetch event: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async createEvent(event: CreateEvent): Promise<SWEvent> {
|
||||
const res = await fetchWithToken(this.token, "/events", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: event.name,
|
||||
start: +event.start,
|
||||
end: +event.end
|
||||
}),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return SWEventSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not create event: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async updateEvent(id: string, event: UpdateEvent): Promise<SWEvent> {
|
||||
const res = await fetchWithToken(this.token, `/events/${id}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
name: event.name,
|
||||
start: +event.start,
|
||||
end: +event.end,
|
||||
deadline: +event.deadline,
|
||||
maxTeamMembers: event.maxTeamMembers,
|
||||
schemType: event.schemType,
|
||||
publicSchemsOnly: event.publicSchemsOnly,
|
||||
spectateSystem: event.spectateSystem
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return SWEventSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not update event: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteEvent(id: string): Promise<boolean> {
|
||||
const res = await fetchWithToken(this.token, `/events/${id}`, {
|
||||
method: "DELETE"
|
||||
});
|
||||
|
||||
return res.ok;
|
||||
}
|
||||
}
|
||||
92
src/components/repo/fight.ts
Normal file
92
src/components/repo/fight.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import type {EventFight} from "../types/event.js";
|
||||
import {fetchWithToken} from "./repo.js";
|
||||
import type {Moment} from "moment";
|
||||
import {z} from "zod";
|
||||
import {EventFightSchema} from "../types/event.js";
|
||||
|
||||
export interface CreateFight {
|
||||
spielmodus: string
|
||||
map: string
|
||||
blueTeam: number
|
||||
redTeam: number
|
||||
start: Moment
|
||||
kampfleiter: number | null
|
||||
group: string | null
|
||||
}
|
||||
|
||||
export interface UpdateFight {
|
||||
spielmodus: string | null
|
||||
map: string | null
|
||||
blueTeam: number | null
|
||||
redTeam: number | null
|
||||
start: Moment | null
|
||||
kampfleiter: number | null
|
||||
group: string | null
|
||||
}
|
||||
|
||||
export class FightRepo {
|
||||
constructor(private token: string) {}
|
||||
|
||||
public async listFights(eventId: number): Promise<EventFight[]> {
|
||||
const res = await fetchWithToken(this.token, `/events/${eventId}/fights`);
|
||||
|
||||
if (res.ok) {
|
||||
return z.array(EventFightSchema).parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not fetch fights: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async createFight(eventId: number, fight: CreateFight): Promise<EventFight> {
|
||||
let res = await fetchWithToken(this.token, `/fights`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
event: eventId,
|
||||
spielmodus: fight.spielmodus,
|
||||
map: fight.map,
|
||||
blueTeam: fight.blueTeam,
|
||||
redTeam: fight.redTeam,
|
||||
start: +fight.start,
|
||||
kampfleiter: fight.kampfleiter,
|
||||
group: fight.group
|
||||
})
|
||||
})
|
||||
|
||||
if (res.ok) {
|
||||
return EventFightSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not create fight: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async updateFight(fightId: number, fight: UpdateFight): Promise<EventFight> {
|
||||
let res = await fetchWithToken(this.token, `/fights/${fightId}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
spielmodus: fight.spielmodus,
|
||||
map: fight.map,
|
||||
blueTeam: fight.blueTeam,
|
||||
redTeam: fight.redTeam,
|
||||
start: fight.start?.valueOf(),
|
||||
kampfleiter: fight.kampfleiter,
|
||||
group: fight.group
|
||||
})
|
||||
})
|
||||
|
||||
if (res.ok) {
|
||||
return EventFightSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not update fight: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteFight(fightId: number): Promise<void> {
|
||||
let res = await fetchWithToken(this.token, `/fights/${fightId}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Could not delete fight: " + res.statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
src/components/repo/page.ts
Normal file
56
src/components/repo/page.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type {Page, PageList} from "../types/page.ts";
|
||||
import {fetchWithToken} from "./repo.ts";
|
||||
import {PageListSchema, PageSchema} from "../types/page.ts";
|
||||
import {bytesToBase64} from "../admin/util.ts";
|
||||
import {branches} from "../stores/stores.ts";
|
||||
|
||||
export class PageRepo {
|
||||
constructor(private token: string) {}
|
||||
|
||||
public async listPages(branch: string = "master"): Promise<PageList> {
|
||||
return await fetchWithToken(this.token, `/page?branch=${branch}`)
|
||||
.then(value => value.json())
|
||||
.then(value => PageListSchema.parse(value).map(value1 => ({...value1, path: value1.path.replace("src/content/", "")})))
|
||||
}
|
||||
|
||||
public async getPage(id: number, branch: string = "master"): Promise<Page> {
|
||||
return await fetchWithToken(this.token, `/page/${id}?branch=${branch}`)
|
||||
.then(value => value.json())
|
||||
.then(value => PageSchema.parse(value))
|
||||
}
|
||||
|
||||
public async updatePage(id: number, content: string, sha: string, message: string, branch: string = "master"): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page/${id}?branch=${branch}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
content: bytesToBase64(new TextEncoder().encode(content)),
|
||||
sha, message
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async getBranches(): Promise<string[]> {
|
||||
return await fetchWithToken(this.token, "/page/branch")
|
||||
.then(value => value.json())
|
||||
}
|
||||
|
||||
public async createBranch(branch: string): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page/branch`, {method: "POST", body: JSON.stringify({branch})})
|
||||
}
|
||||
|
||||
public async deleteBranch(branch: string): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page/branch`, {method: "DELETE", body: JSON.stringify({branch})})
|
||||
}
|
||||
|
||||
public async createFile(path: string, branch: string = "master"): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page?branch=${branch}`, {method: "POST", body: JSON.stringify({path})})
|
||||
}
|
||||
|
||||
public async merge(branch: string, message: string): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page/branch/merge`, {method: "POST", body: JSON.stringify({branch, message})})
|
||||
}
|
||||
|
||||
public async deletePage(id: number, message: string, sha: string, branch: string = "master"): Promise<void> {
|
||||
await fetchWithToken(this.token, `/page/${id}?branch=${branch}`, {method: "DELETE", body: JSON.stringify({message, sha})})
|
||||
}
|
||||
}
|
||||
57
src/components/repo/perms.ts
Normal file
57
src/components/repo/perms.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import type {Perms, UserPerms} from "../types/perms.js";
|
||||
import {fetchWithToken} from "./repo.js";
|
||||
import {PermsSchema, UserPermsSchema} from "../types/perms.js";
|
||||
|
||||
export class PermsRepo {
|
||||
constructor(private token: string) {}
|
||||
|
||||
public async listPerms(): Promise<Perms> {
|
||||
const res = await fetchWithToken(this.token, "/perms");
|
||||
|
||||
if (res.ok) {
|
||||
return PermsSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not fetch perms: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async getPerms(userId: number): Promise<UserPerms> {
|
||||
const res = await fetchWithToken(this.token, `/perms/user/${userId}`);
|
||||
|
||||
if (res.ok) {
|
||||
return UserPermsSchema.parse(await res.json());
|
||||
} else {
|
||||
throw new Error("Could not fetch perms: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async setPrefix(userId: number, prefix: string): Promise<void> {
|
||||
const res = await fetchWithToken(this.token, `/perms/user/${userId}/prefix/${prefix}`, {
|
||||
method: "PUT",
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Could not set prefix: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async addPerm(userId: number, perm: string): Promise<void> {
|
||||
const res = await fetchWithToken(this.token, `/perms/user/${userId}/${perm}`, {
|
||||
method: "PUT",
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Could not add perm: " + res.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
public async removePerm(userId: number, perm: string): Promise<void> {
|
||||
const res = await fetchWithToken(this.token, `/perms/user/${userId}/${perm}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Could not remove perm: " + res.statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/components/repo/repo.ts
Normal file
31
src/components/repo/repo.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {derived, writable} from "svelte/store";
|
||||
import {EventRepo} from "./event.js";
|
||||
import {FightRepo} from "./fight.js";
|
||||
import {PermsRepo} from "./perms.js";
|
||||
import {PageRepo} from "./page.ts";
|
||||
import {DataRepo} from "./data.ts";
|
||||
|
||||
import { AES, enc, format } from "crypto-js";
|
||||
|
||||
export { EventRepo } from "./event.js"
|
||||
|
||||
export const apiUrl = import.meta.env.PUBLIC_API_SERVER;
|
||||
const secret = import.meta.env.PUBLIC_SECRET;
|
||||
|
||||
function encryptToken(token: string): string {
|
||||
return AES.encrypt(token, secret).toString();
|
||||
}
|
||||
|
||||
function decryptToken(token: string): string {
|
||||
return AES.decrypt(token, secret).toString(enc.Utf8);
|
||||
}
|
||||
|
||||
export const fetchWithToken = (token: string, url: string, params: RequestInit = {}) => fetch(`${apiUrl}${url}`, {...params, headers: {...(token !== "" ? {"Authorization": "Bearer " + (token)}:{}), "Content-Type": "application/json", ...params.headers}});
|
||||
export const tokenStore = writable(decryptToken(localStorage.getItem("sw-session") ?? ""))
|
||||
tokenStore.subscribe((value) => localStorage.setItem("sw-session", encryptToken(value)))
|
||||
|
||||
export const eventRepo = derived(tokenStore, ($token) => new EventRepo($token))
|
||||
export const fightRepo = derived(tokenStore, ($token) => new FightRepo($token))
|
||||
export const permsRepo = derived(tokenStore, ($token) => new PermsRepo($token))
|
||||
export const pageRepo = derived(tokenStore, ($token) => new PageRepo($token))
|
||||
export const dataRepo = derived(tokenStore, ($token) => new DataRepo($token))
|
||||
Reference in New Issue
Block a user