Compare commits
No commits in common. "56f0442d33060923fd93cab1bb9e5826db9e70fc" and "df20a472533bd9bd518f232315f6125472217d68" have entirely different histories.
56f0442d33
...
df20a47253
3
.gitignore
vendored
3
.gitignore
vendored
@ -27,7 +27,6 @@ yarn-error.log*
|
|||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env*.local
|
.env*.local
|
||||||
.env
|
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
@ -41,5 +40,3 @@ next-env.d.ts
|
|||||||
|
|
||||||
temp.json
|
temp.json
|
||||||
temp.md
|
temp.md
|
||||||
|
|
||||||
.dragonshoard/
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
"use server";
|
|
||||||
|
|
||||||
import { prisma } from "@/prisma/prismaClient";
|
|
||||||
|
|
||||||
export const createGameSystem = async (name: string) => {
|
|
||||||
const { id } = await prisma.gameSystem.create({
|
|
||||||
data: {
|
|
||||||
name,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return id;
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
"use server";
|
|
||||||
import { prisma } from "@/prisma/prismaClient";
|
|
||||||
|
|
||||||
// DEV TOOL ONLY
|
|
||||||
export async function deleteAllGameSystems() {
|
|
||||||
await prisma.gameSystem.deleteMany();
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
import { Sticky } from "@/lib/sticky";
|
|
||||||
import { prisma } from "@/prisma/prismaClient";
|
|
||||||
|
|
||||||
export default async function GameSystem(
|
|
||||||
{ params: { id } }: { params: { id: string } },
|
|
||||||
) {
|
|
||||||
if (!id) throw "HOW DID YOU GET HERE?";
|
|
||||||
|
|
||||||
const gameSystem = await prisma.gameSystem.findFirst({
|
|
||||||
where: {
|
|
||||||
id,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
schemas: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
id: true,
|
|
||||||
publications: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<section className="heading">
|
|
||||||
<h2 className="strapline">Game System</h2>
|
|
||||||
<h1>{gameSystem?.name}</h1>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<ul>
|
|
||||||
{gameSystem?.schemas.map((schema) => (
|
|
||||||
<li key={schema.id}>{schema.name}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<Sticky sidedness={-1}>
|
|
||||||
<h1>HELLO!</h1>
|
|
||||||
</Sticky>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { deleteAllGameSystems } from "@/actions/GameSystems/deleteAll";
|
|
||||||
import { DevTool } from "@/components/devtools/DevTool";
|
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { FC, PropsWithChildren } from "react";
|
|
||||||
|
|
||||||
export const GameSystemsClient: FC<PropsWithChildren> = ({ children }) => {
|
|
||||||
const router = useRouter();
|
|
||||||
// DEV TOOL ONLY
|
|
||||||
async function deleteAll() {
|
|
||||||
await deleteAllGameSystems();
|
|
||||||
router.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<DevTool id="game-system-home">
|
|
||||||
<button onClick={deleteAll} className="btn-primary bg-lime-600">
|
|
||||||
Delete All Game Systems
|
|
||||||
</button>
|
|
||||||
</DevTool>
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,35 +0,0 @@
|
|||||||
import { prisma } from "@/prisma/prismaClient";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
|
|
||||||
export default function CreateGameSystem() {
|
|
||||||
async function create(form: FormData) {
|
|
||||||
"use server";
|
|
||||||
|
|
||||||
const name = form.get("name")?.toString();
|
|
||||||
if (!name) return;
|
|
||||||
const { id } = await prisma.gameSystem.create({
|
|
||||||
data: {
|
|
||||||
name,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
redirect(`/game-systems/${id}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form action={create}>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
// {...bind}
|
|
||||||
name="name"
|
|
||||||
placeholder="Create a new game system..."
|
|
||||||
className="w-min"
|
|
||||||
/>
|
|
||||||
<button className="btn-primary p-2 px-2 ml-2" type="submit">
|
|
||||||
Create
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import { prisma } from "@/prisma/prismaClient";
|
|
||||||
import CreateGameSystem from "./create";
|
|
||||||
import { GameSystemsClient } from "./client";
|
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export default async function GameSystems() {
|
|
||||||
const existingGameSystems = await prisma.gameSystem.findMany({
|
|
||||||
orderBy: {
|
|
||||||
created: "asc",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<GameSystemsClient>
|
|
||||||
<section className="heading">
|
|
||||||
<h2 className="strapline">Tabletop Commander</h2>
|
|
||||||
<h1>Game Systems</h1>
|
|
||||||
</section>
|
|
||||||
<section className="mb-6">
|
|
||||||
<CreateGameSystem />
|
|
||||||
</section>
|
|
||||||
<section className="">
|
|
||||||
<ul>
|
|
||||||
{existingGameSystems.map((g) => (
|
|
||||||
<li key={g.id} className="odd:bg-black/20 p-2 text-lg">
|
|
||||||
<Link href={`/game-systems/${g.id}`}>{g.name}</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
</GameSystemsClient>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Roboto } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import {
|
import {
|
||||||
BookOpenIcon,
|
BookOpenIcon,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { DevToolboxContextProvider } from "@/components/devtools/context";
|
import { DevToolboxContextProvider } from "@/components/devtools/context";
|
||||||
|
|
||||||
const roboto = Roboto({ subsets: ["latin"], weight: "400" });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Tabletop Commander",
|
title: "Tabletop Commander",
|
||||||
@ -51,9 +51,11 @@ export default function RootLayout({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
console.log(process.env.NODE_ENV);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className={roboto.className + " flex min-h-[100vh]"}>
|
<body className={inter.className + " flex min-h-[100vh]"}>
|
||||||
<nav className="h-[100vh] sticky top-0 left-0 bottom-0 p-8 rounded-r-3xl dark:bg-mixed-300 bg-primary-400 w-max shadow-2xl">
|
<nav className="h-[100vh] sticky top-0 left-0 bottom-0 p-8 rounded-r-3xl dark:bg-mixed-300 bg-primary-400 w-max shadow-2xl">
|
||||||
<h1 className="text-lg font-bold pb-6 border-b dark:border-dark-500 border-primary-600">
|
<h1 className="text-lg font-bold pb-6 border-b dark:border-dark-500 border-primary-600">
|
||||||
<Link href="/">Tabletop Commander</Link>
|
<Link href="/">Tabletop Commander</Link>
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { FC, PropsWithChildren, use, useEffect } from "react";
|
|
||||||
import { DevToolboxContext } from "./context";
|
|
||||||
|
|
||||||
export const DevTool: FC<PropsWithChildren<{ id: string }>> = (
|
|
||||||
{ children, id },
|
|
||||||
) => {
|
|
||||||
const { addTool, removeTool } = use(DevToolboxContext);
|
|
||||||
useEffect(() => {
|
|
||||||
addTool(id, children);
|
|
||||||
(() => removeTool(id));
|
|
||||||
}, [addTool, children, id, removeTool]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
import { Portal } from "@/lib/portal/components";
|
import { Portal } from "@/lib/portal/components";
|
||||||
import { FC, use, useState } from "react";
|
import { FC, PropsWithChildren, use, useEffect, useState } from "react";
|
||||||
import { DevToolboxContext } from "./context";
|
import { DevToolboxContext } from "./context";
|
||||||
import { WrenchScrewdriverIcon } from "@heroicons/react/24/solid";
|
import { WrenchScrewdriverIcon } from "@heroicons/react/24/solid";
|
||||||
import { XMarkIcon } from "@heroicons/react/16/solid";
|
import { XMarkIcon } from "@heroicons/react/16/solid";
|
||||||
@ -38,3 +38,15 @@ export const DevToolbox: FC = () => {
|
|||||||
)
|
)
|
||||||
: <></>;
|
: <></>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DevTool: FC<PropsWithChildren<{ id: string }>> = (
|
||||||
|
{ children, id },
|
||||||
|
) => {
|
||||||
|
const { addTool, removeTool } = use(DevToolboxContext);
|
||||||
|
useEffect(() => {
|
||||||
|
addTool(id, children);
|
||||||
|
(() => removeTool(id));
|
||||||
|
}, [addTool, children, id, removeTool]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
|
@ -34,6 +34,7 @@ export const DevToolboxContextProvider: FC<
|
|||||||
> = (
|
> = (
|
||||||
{ children, isDev },
|
{ children, isDev },
|
||||||
) => {
|
) => {
|
||||||
|
console.log(isDev);
|
||||||
const [tools, setTools] = useState<Record<string, ReactNode>>({});
|
const [tools, setTools] = useState<Record<string, ReactNode>>({});
|
||||||
const [shouldShowDevTools, setShouldShowDevTools] = useState(isDev);
|
const [shouldShowDevTools, setShouldShowDevTools] = useState(isDev);
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ export const TTCMD: FC<Props> = (
|
|||||||
setHasEscapedTOC(escapeTOC(toc));
|
setHasEscapedTOC(escapeTOC(toc));
|
||||||
}, [escapeTOC, toc]);
|
}, [escapeTOC, toc]);
|
||||||
|
|
||||||
|
console.log("mdId", parserId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<MDSkeletonLoader />}>
|
<Suspense fallback={<MDSkeletonLoader />}>
|
||||||
<DevTool id={parserId}>
|
<DevTool id={parserId}>
|
||||||
|
5
global.d.ts
vendored
5
global.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
import { DHSecretClient } from "./lib/secret";
|
|
||||||
|
|
||||||
export declare global {
|
|
||||||
var Secrets: DHSecretClient;
|
|
||||||
}
|
|
@ -9,17 +9,20 @@ interface IProps {
|
|||||||
export const Portal: FC<PropsWithChildren<IProps>> = (
|
export const Portal: FC<PropsWithChildren<IProps>> = (
|
||||||
{ children, className = "root-portal", el = "div" },
|
{ children, className = "root-portal", el = "div" },
|
||||||
) => {
|
) => {
|
||||||
const [container, setContainer] = useState<HTMLElement>();
|
const [container] = useState(() => {
|
||||||
|
// This will be executed only on the initial render
|
||||||
|
// https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
|
||||||
|
return document.createElement(el);
|
||||||
|
});
|
||||||
|
|
||||||
|
// todo: this smells. appending the same element?
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = document.createElement(el);
|
|
||||||
container.classList.add(className);
|
container.classList.add(className);
|
||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
setContainer(container);
|
|
||||||
return () => {
|
return () => {
|
||||||
document.body.removeChild(container);
|
document.body.removeChild(container);
|
||||||
};
|
};
|
||||||
}, [className, el]);
|
}, [className, container]);
|
||||||
|
|
||||||
return container && createPortal(children, container);
|
return createPortal(children, container);
|
||||||
};
|
};
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
// import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
||||||
// import { writeFile } from "fs/promises";
|
|
||||||
|
|
||||||
export class DHSecretClient {
|
|
||||||
private token!: Promise<string>; //Set by init
|
|
||||||
|
|
||||||
private headerName = "x-hoard-auth-token";
|
|
||||||
|
|
||||||
private cache: Record<string, { value: string; expires?: number }> = {};
|
|
||||||
private cacheLocation: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param dhBaseUri uri for hosted Dragon's Hoard instance
|
|
||||||
* @param cacheDir path to cache dir
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
private dhBaseUri: string,
|
|
||||||
private cacheDir: string,
|
|
||||||
) {
|
|
||||||
this.cacheLocation = this.cacheDir.trim().replace(/\/^/, "") + "/.dh_cache";
|
|
||||||
// mkdirSync(this.cacheDir, { recursive: true });
|
|
||||||
// writeFileSync(this.cacheLocation, "{}", { encoding: "utf-8", flag: "wx" });
|
|
||||||
// this.readDiskCache();
|
|
||||||
this.token = this.fetchToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async fetchToken() {
|
|
||||||
const cacheKey = "token";
|
|
||||||
if (this.cache[cacheKey]) {
|
|
||||||
return this.cache[cacheKey].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const req = await fetch(this.dhBaseUri + "/api/access/token");
|
|
||||||
|
|
||||||
if (req.status !== 200) throw Error(await req.text());
|
|
||||||
|
|
||||||
const token = await req.text();
|
|
||||||
|
|
||||||
if (!token) throw Error("Token not included in response body");
|
|
||||||
|
|
||||||
this.writeCache(cacheKey, token);
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private readDiskCache() {
|
|
||||||
// const cache = readFileSync(this.cacheLocation, "utf-8");
|
|
||||||
|
|
||||||
// this.cache = JSON.parse(cache || "{}");
|
|
||||||
// }
|
|
||||||
// private async writeDiskCache() {
|
|
||||||
// await writeFile(this.cacheLocation, JSON.stringify(this.cache), "utf-8");
|
|
||||||
// }
|
|
||||||
|
|
||||||
private writeCache(key: string, value: string, expires?: number) {
|
|
||||||
this.cache[key] = { value, expires };
|
|
||||||
|
|
||||||
// this.writeDiskCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private readCache(key: string) {
|
|
||||||
const item = this.cache[key];
|
|
||||||
|
|
||||||
if (!item) return null;
|
|
||||||
|
|
||||||
if (item && item.expires && item.expires < Date.now()) {
|
|
||||||
delete this.cache[key];
|
|
||||||
// this.writeDiskCache();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return item.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchSecret(secret_name: string, environment?: string) {
|
|
||||||
const uri = this.dhBaseUri + "/api/keys/" + secret_name +
|
|
||||||
(environment ? "?env=" + environment : "");
|
|
||||||
|
|
||||||
const cached = this.readCache(secret_name);
|
|
||||||
|
|
||||||
if (cached !== null) return cached;
|
|
||||||
|
|
||||||
const req = await fetch(uri, {
|
|
||||||
headers: {
|
|
||||||
[this.headerName]: await this.token,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (req.status !== 200) throw Error(await req.text());
|
|
||||||
|
|
||||||
const secret = await req.text();
|
|
||||||
|
|
||||||
if (!secret) throw Error("Secret not included in response body");
|
|
||||||
|
|
||||||
this.writeCache(secret_name, secret);
|
|
||||||
|
|
||||||
return secret;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import { DHSecretClient } from ".";
|
|
||||||
|
|
||||||
if (!globalThis.Secrets) {
|
|
||||||
globalThis.Secrets = new DHSecretClient(
|
|
||||||
"https://dragonshoard.cyborggrizzly.com",
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? "./.dragonshoard"
|
|
||||||
: "/.dragonshoard",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SecretClient = () => globalThis.Secrets;
|
|
@ -1,100 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import {
|
|
||||||
FC,
|
|
||||||
MouseEventHandler,
|
|
||||||
PropsWithChildren,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import { Portal } from "../portal/components";
|
|
||||||
|
|
||||||
export const Sticky: FC<
|
|
||||||
PropsWithChildren<{ sidedness: 1 | -1; initialX?: number; initialY?: number }>
|
|
||||||
> = (
|
|
||||||
{ children, sidedness, initialX, initialY },
|
|
||||||
) => {
|
|
||||||
const [position, setPosition] = useState({
|
|
||||||
x: initialX ?? 10,
|
|
||||||
y: initialY ?? 10,
|
|
||||||
});
|
|
||||||
const divRef = useRef<HTMLDivElement>(null);
|
|
||||||
const [dragging, setDragging] = useState(false);
|
|
||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
|
||||||
if (dragging) {
|
|
||||||
setPosition({
|
|
||||||
x: ((sidedness === -1 ? document.body.clientWidth : 0) -
|
|
||||||
(e.pageX - offset.x * sidedness)) * -sidedness,
|
|
||||||
y: e.pageY - offset.y,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
|
||||||
if (dragging) {
|
|
||||||
setDragging(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (dragging) {
|
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousemove", handleMouseMove);
|
|
||||||
document.removeEventListener("mouseup", handleMouseUp);
|
|
||||||
};
|
|
||||||
}, [dragging, offset, sidedness]);
|
|
||||||
|
|
||||||
const handleMouseDown: MouseEventHandler = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const rect = divRef.current!.getBoundingClientRect();
|
|
||||||
const offsetX = e.pageX - rect.left;
|
|
||||||
const offsetY = e.pageY - rect.top;
|
|
||||||
setOffset({ x: offsetX, y: offsetY });
|
|
||||||
setDragging(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Portal>
|
|
||||||
<div
|
|
||||||
className="fixed card p-0 overflow-clip"
|
|
||||||
style={{
|
|
||||||
top: position.y,
|
|
||||||
left: sidedness === 1 ? position.x : "unset",
|
|
||||||
right: sidedness === -1 ? position.x : "unset",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
ref={divRef}
|
|
||||||
className="cursor-move p-1 bg-black/20 flex justify-center"
|
|
||||||
onMouseDown={handleMouseDown}
|
|
||||||
draggable="false"
|
|
||||||
style={{ position: "relative" }}
|
|
||||||
>
|
|
||||||
<svg width="70" height="30" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle cx="10" cy="10" r="1" fill="grey" />
|
|
||||||
<circle cx="20" cy="10" r="1" fill="grey" />
|
|
||||||
<circle cx="30" cy="10" r="1" fill="grey" />
|
|
||||||
<circle cx="40" cy="10" r="1" fill="grey" />
|
|
||||||
<circle cx="50" cy="10" r="1" fill="grey" />
|
|
||||||
<circle cx="60" cy="10" r="1" fill="grey" />
|
|
||||||
|
|
||||||
<circle cx="10" cy="20" r="1" fill="grey" />
|
|
||||||
<circle cx="20" cy="20" r="1" fill="grey" />
|
|
||||||
<circle cx="30" cy="20" r="1" fill="grey" />
|
|
||||||
<circle cx="40" cy="20" r="1" fill="grey" />
|
|
||||||
<circle cx="50" cy="20" r="1" fill="grey" />
|
|
||||||
<circle cx="60" cy="20" r="1" fill="grey" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="p-4">{children}</div>
|
|
||||||
</div>
|
|
||||||
</Portal>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,6 +1,4 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {};
|
||||||
output: "standalone",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
5606
package-lock.json
generated
5606
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,10 +10,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.1.1",
|
"@heroicons/react": "^2.1.1",
|
||||||
"@prisma/client": "^5.11.0",
|
|
||||||
"isomorphic-dompurify": "^2.4.0",
|
"isomorphic-dompurify": "^2.4.0",
|
||||||
"next": "14.1.0",
|
"next": "14.1.0",
|
||||||
"prisma": "^5.11.0",
|
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
},
|
},
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
-- CreateTable
|
|
||||||
CREATE TABLE `GameSystem` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`name` VARCHAR(191) NOT NULL,
|
|
||||||
`created` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `Schema` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`gameSystemId` VARCHAR(191) NOT NULL,
|
|
||||||
`name` VARCHAR(191) NOT NULL,
|
|
||||||
`schema` JSON NOT NULL,
|
|
||||||
`version` INTEGER NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `Publication` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`schemaId` VARCHAR(191) NOT NULL,
|
|
||||||
`name` VARCHAR(191) NOT NULL,
|
|
||||||
`data` JSON NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `Tag` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`publicationId` VARCHAR(191) NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `Schema` ADD CONSTRAINT `Schema_gameSystemId_fkey` FOREIGN KEY (`gameSystemId`) REFERENCES `GameSystem`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `Publication` ADD CONSTRAINT `Publication_schemaId_fkey` FOREIGN KEY (`schemaId`) REFERENCES `Schema`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `Tag` ADD CONSTRAINT `Tag_publicationId_fkey` FOREIGN KEY (`publicationId`) REFERENCES `Publication`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- A unique constraint covering the columns `[name]` on the table `GameSystem` will be added. If there are existing duplicate values, this will fail.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX `GameSystem_name_key` ON `GameSystem`(`name`);
|
|
@ -1,3 +0,0 @@
|
|||||||
# Please do not edit this file manually
|
|
||||||
# It should be added in your version-control system (i.e. Git)
|
|
||||||
provider = "mysql"
|
|
@ -1,13 +0,0 @@
|
|||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
|
|
||||||
const prismaClientSingleton = () => {
|
|
||||||
return new PrismaClient();
|
|
||||||
};
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
var prismaGlobal: undefined | ReturnType<typeof prismaClientSingleton>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;
|
|
@ -1,49 +0,0 @@
|
|||||||
// This is your Prisma schema file,
|
|
||||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
||||||
|
|
||||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
|
||||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
|
||||||
|
|
||||||
generator client {
|
|
||||||
provider = "prisma-client-js"
|
|
||||||
}
|
|
||||||
|
|
||||||
datasource db {
|
|
||||||
provider = "mysql"
|
|
||||||
url = env("DATABASE_URL")
|
|
||||||
}
|
|
||||||
|
|
||||||
model GameSystem {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
schemas Schema[]
|
|
||||||
|
|
||||||
name String @unique
|
|
||||||
created DateTime @default(now())
|
|
||||||
}
|
|
||||||
|
|
||||||
model Schema {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
gameSystem GameSystem @relation(fields: [gameSystemId], references: [id])
|
|
||||||
gameSystemId String
|
|
||||||
publications Publication[]
|
|
||||||
|
|
||||||
name String
|
|
||||||
schema Json
|
|
||||||
version Int
|
|
||||||
}
|
|
||||||
|
|
||||||
model Publication {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
schema Schema @relation(fields: [schemaId], references: [id])
|
|
||||||
schemaId String
|
|
||||||
tags Tag[]
|
|
||||||
|
|
||||||
name String
|
|
||||||
data Json
|
|
||||||
}
|
|
||||||
|
|
||||||
model Tag {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
publication Publication @relation(fields: [publicationId], references: [id])
|
|
||||||
publicationId String
|
|
||||||
}
|
|
@ -32,12 +32,9 @@
|
|||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
".next/types/**/*.ts",
|
".next/types/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules"
|
"node_modules"
|
||||||
],
|
|
||||||
"files": [
|
|
||||||
"global.d.ts"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user