enables schema saving in db, initial refactor of db schema for revisions
This commit is contained in:
parent
fd5e5bcc8b
commit
5b16cc60f7
@ -1,29 +0,0 @@
|
||||
"use server";
|
||||
|
||||
import { auth } from "@/auth";
|
||||
import { prisma } from "@/prisma/prismaClient";
|
||||
import { isEmailVerified } from "@/util/isEmailVerified";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export const createSchema = async (form: FormData) => {
|
||||
const name = form.get("name")?.toString();
|
||||
const gsId = form.get("gsId")?.toString();
|
||||
|
||||
const session = await auth();
|
||||
|
||||
if (!name || !gsId || !session?.user?.id || !isEmailVerified(session.user.id))
|
||||
return;
|
||||
|
||||
const { id } = await prisma.schema.create({
|
||||
data: {
|
||||
name,
|
||||
schema: "{}",
|
||||
types: "{}",
|
||||
version: 0,
|
||||
gameSystemId: gsId,
|
||||
authorId: session.user.id,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
redirect(`/game-systems/${gsId}/schema/${id}`);
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/prisma/prismaClient";
|
||||
|
||||
export const findSchema = async (id: string) => {
|
||||
const schema = await prisma.schema.findFirst({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
gameSystem: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return schema;
|
||||
};
|
79
actions/Schemas/index.ts
Normal file
79
actions/Schemas/index.ts
Normal file
@ -0,0 +1,79 @@
|
||||
"use server";
|
||||
import { auth } from "@/auth";
|
||||
import { isEmailVerified } from "@/util/isEmailVerified";
|
||||
import { redirect } from "next/navigation";
|
||||
import { prisma } from "@/prisma/prismaClient";
|
||||
|
||||
export const saveSchemaDb = async (s: Schema) => {
|
||||
const sesh = await auth();
|
||||
if (!sesh?.user?.id) return;
|
||||
|
||||
const { id } = await prisma.schema.upsert({
|
||||
// data: {
|
||||
// ...s,
|
||||
// },
|
||||
create: {
|
||||
...s,
|
||||
version: 0,
|
||||
authorId: sesh.user.id,
|
||||
id: undefined,
|
||||
},
|
||||
update: s,
|
||||
where: {
|
||||
id: s.id,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
redirect(`/game-systems/${s.gameSystemId}/schema/${id}`);
|
||||
};
|
||||
|
||||
export const findSchema = async (id: string): Promise<Schema | null> => {
|
||||
const schema = await prisma.schema.findFirst({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
// include: {
|
||||
// gameSystem: {
|
||||
// select: {
|
||||
// id: true,
|
||||
// name: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
schema: true,
|
||||
types: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!schema) return null;
|
||||
|
||||
return schema as Schema;
|
||||
};
|
||||
|
||||
export const createSchema = async (form: FormData) => {
|
||||
const name = form.get("name")?.toString();
|
||||
const gsId = form.get("gsId")?.toString();
|
||||
|
||||
const session = await auth();
|
||||
|
||||
if (!name || !gsId || !session?.user?.id || !isEmailVerified(session.user.id))
|
||||
return;
|
||||
|
||||
const { id } = await prisma.schema.create({
|
||||
data: {
|
||||
name,
|
||||
schema: "{}",
|
||||
types: "{}",
|
||||
version: 0,
|
||||
gameSystemId: gsId,
|
||||
authorId: session.user.id,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
redirect(`/game-systems/${gsId}/schema/${id}`);
|
||||
};
|
@ -1,18 +1,18 @@
|
||||
import { prisma } from "@/prisma/prismaClient";
|
||||
import Link from "next/link";
|
||||
|
||||
export default async function GameSystem(
|
||||
{ params: { id } }: { params: { id: string } },
|
||||
) {
|
||||
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,
|
||||
include: {
|
||||
schemas: {
|
||||
select: {
|
||||
name: true,
|
||||
@ -26,6 +26,10 @@ export default async function GameSystem(
|
||||
},
|
||||
},
|
||||
},
|
||||
// select: {
|
||||
// id: true,
|
||||
// name: true,
|
||||
// },
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -30,7 +30,7 @@ export const { handlers, signIn, signOut, auth } = NextAuth(async () => {
|
||||
let user = null;
|
||||
|
||||
const pwHash = await saltAndHashPassword(
|
||||
credentials.password as string
|
||||
credentials.password as string,
|
||||
);
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
|
@ -1,30 +1,45 @@
|
||||
"use client";
|
||||
|
||||
import { FC, useCallback, useState } from "react";
|
||||
import { FC, useCallback, useEffect, useState } from "react";
|
||||
import AnimatedPageContainer from "@/components/AnimatedPageContainer";
|
||||
import { TypeEditor } from "./type-editor";
|
||||
import { useObjectStateWrapper } from "@/hooks/useObjectState";
|
||||
import { useInput } from "../../hooks/useInput";
|
||||
import { useRecoilState, useResetRecoilState } from "recoil";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { SchemaEditAtom } from "@/recoil/atoms/schema";
|
||||
import { SchemaViewer } from "./schema-viewer";
|
||||
import { TemplateEditor } from "./template-editor";
|
||||
import { Icon } from "@/components/Icon";
|
||||
import { useParams } from "next/navigation";
|
||||
import { FieldTypes } from "./fieldtypes";
|
||||
import { prisma } from "@/prisma/prismaClient";
|
||||
import { findSchema, saveSchemaDb } from "@/actions/Schemas/index";
|
||||
import { useToast } from "../toast";
|
||||
|
||||
export const SchemaBuilder: FC = () => {
|
||||
const [schema, setSchema] = useRecoilState(SchemaEditAtom);
|
||||
const resetSchema = useResetRecoilState(SchemaEditAtom);
|
||||
// const resetSchema = useResetRecoilState(SchemaEditAtom);
|
||||
const { createToast } = useToast();
|
||||
const { update: updateSchema, bindProperty: bindSchemaProperty } =
|
||||
useObjectStateWrapper<Schema>(schema, setSchema);
|
||||
|
||||
const { schemaId, gameSystemId } = useParams<{
|
||||
const { schemaId, id: gameSystemId } = useParams<{
|
||||
schemaId: string;
|
||||
gameSystemId?: string;
|
||||
id: string;
|
||||
}>();
|
||||
|
||||
useEffect(() => {
|
||||
if (schemaId !== "create" && schemaId !== schema.id)
|
||||
findSchema(schemaId).then((sc) => {
|
||||
if (!sc) return;
|
||||
setSchema(sc);
|
||||
});
|
||||
}, [schema.id, schemaId, setSchema]);
|
||||
|
||||
useEffect(() => {
|
||||
if (gameSystemId && !schema.gameSystemId)
|
||||
setSchema((sc) => ({ ...sc, gameSystemId }));
|
||||
}, [gameSystemId, schema.gameSystemId, setSchema]);
|
||||
|
||||
const {
|
||||
value: typeName,
|
||||
bind: bindTypeName,
|
||||
@ -33,7 +48,7 @@ export const SchemaBuilder: FC = () => {
|
||||
|
||||
const [pageNumber, setPageNumber] = useState(0);
|
||||
|
||||
const [lastSaved, setLastSaved] = useState(schema);
|
||||
const [lastSaved, _setLastSaved] = useState(schema);
|
||||
|
||||
const [selectedType, setSelectedType] = useState("");
|
||||
|
||||
@ -49,24 +64,13 @@ export const SchemaBuilder: FC = () => {
|
||||
setPageNumber(0);
|
||||
setSelectedType("");
|
||||
},
|
||||
[resetTypeName, updateSchema]
|
||||
[resetTypeName, updateSchema],
|
||||
);
|
||||
|
||||
const saveSchema = useCallback(async () => {
|
||||
// "use server";
|
||||
// setLastSaved(schema);
|
||||
// await prisma.schema.upsert({
|
||||
// where: { id: schema.id },
|
||||
// update: { ...schema },
|
||||
// create: {
|
||||
// name: schema.name,
|
||||
// schema: schema.schema,
|
||||
// types: schema.types,
|
||||
// version: 0,
|
||||
// gameSystemId,
|
||||
// },
|
||||
// });
|
||||
}, [schema, gameSystemId]);
|
||||
createToast({ msg: "Saving Schema", fading: true });
|
||||
await saveSchemaDb(schema);
|
||||
}, [createToast, schema]);
|
||||
|
||||
const selectTypeForEdit = useCallback((typeKey: string) => {
|
||||
setSelectedType(typeKey);
|
||||
@ -82,10 +86,7 @@ export const SchemaBuilder: FC = () => {
|
||||
updateSchema((s) => ({
|
||||
schema: {
|
||||
...s.schema,
|
||||
[schemaFieldName]: {
|
||||
display: "",
|
||||
type: FieldTypes.any,
|
||||
},
|
||||
[schemaFieldName]: FieldTypes.any,
|
||||
},
|
||||
}));
|
||||
resetSchemaFieldName();
|
||||
@ -100,7 +101,7 @@ export const SchemaBuilder: FC = () => {
|
||||
},
|
||||
}));
|
||||
},
|
||||
[updateSchema]
|
||||
[updateSchema],
|
||||
);
|
||||
|
||||
const deleteType = useCallback(
|
||||
@ -111,7 +112,7 @@ export const SchemaBuilder: FC = () => {
|
||||
return { types };
|
||||
});
|
||||
},
|
||||
[updateSchema]
|
||||
[updateSchema],
|
||||
);
|
||||
|
||||
return (
|
||||
@ -141,7 +142,7 @@ export const SchemaBuilder: FC = () => {
|
||||
template={schemaField}
|
||||
update={updateSchemaField}
|
||||
/>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -15,9 +15,13 @@ export class DHSecretClient {
|
||||
* @param dhBaseUri uri for hosted Dragon's Hoard instance
|
||||
* @param cacheDir path to cache dir
|
||||
*/
|
||||
constructor(private dhBaseUri: string, private cacheDir: string) {
|
||||
constructor(
|
||||
private dhBaseUri: string,
|
||||
private cacheDir: string,
|
||||
) {
|
||||
this.cacheLocation = this.cacheDir.trim().replace(/\/^/, "") + "/.dh_cache";
|
||||
mkdirSync(this.cacheDir, { recursive: true });
|
||||
|
||||
this.readDiskCache();
|
||||
this.token = this.fetchToken();
|
||||
}
|
||||
@ -42,12 +46,13 @@ export class DHSecretClient {
|
||||
}
|
||||
|
||||
private readDiskCache() {
|
||||
try {
|
||||
const cache = readFileSync(this.cacheLocation, "utf-8");
|
||||
|
||||
if (!cache) {
|
||||
this.cache = JSON.parse(cache || "{}");
|
||||
} catch {
|
||||
this.cache = {};
|
||||
this.writeDiskCache();
|
||||
} else this.cache = JSON.parse(cache || "{}");
|
||||
this.writeDiskCache().then(this.readDiskCache);
|
||||
}
|
||||
}
|
||||
private async writeDiskCache() {
|
||||
await writeFile(this.cacheLocation, JSON.stringify(this.cache), "utf-8");
|
||||
|
@ -1,9 +1,3 @@
|
||||
// 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"
|
||||
}
|
||||
@ -31,24 +25,53 @@ model Schema {
|
||||
author User @relation(fields: [authorId], references: [id])
|
||||
authorId String
|
||||
|
||||
originalId String?
|
||||
name String
|
||||
|
||||
SchemaRevision SchemaRevision[]
|
||||
}
|
||||
|
||||
model SchemaRevision {
|
||||
id String @id @default(cuid())
|
||||
schemaId String
|
||||
parentSchema Schema @relation(fields: [schemaId], references: [id])
|
||||
|
||||
schema Json
|
||||
types Json
|
||||
version Int
|
||||
Publication Publication[]
|
||||
|
||||
@@unique([schemaId, version])
|
||||
}
|
||||
|
||||
model Publication {
|
||||
id String @id @default(cuid())
|
||||
schema Schema @relation(fields: [schemaId], references: [id])
|
||||
schemaId String
|
||||
schemaVersion Int
|
||||
schemaRevision SchemaRevision @relation(fields: [schemaVersion, schemaId], references: [version, schemaId])
|
||||
tags Tag[]
|
||||
|
||||
name String
|
||||
|
||||
TagsOnPublications TagsOnPublications[]
|
||||
PublicationRevision PublicationRevision[]
|
||||
}
|
||||
|
||||
model PublicationRevision {
|
||||
id String @id @default(cuid())
|
||||
version String
|
||||
isFinal Boolean
|
||||
data Json
|
||||
|
||||
previousId String?
|
||||
publicationId String
|
||||
publication Publication @relation(fields: [publicationId], references: [id])
|
||||
previousRevision PublicationRevision? @relation(name: "downlineRevisions", fields: [previousId], references: [id])
|
||||
downlineRevisions PublicationRevision[] @relation("downlineRevisions")
|
||||
author User @relation(fields: [authorId], references: [id])
|
||||
authorId String
|
||||
|
||||
name String
|
||||
data Json
|
||||
TagsOnPublications TagsOnPublications[]
|
||||
@@unique([publicationId, version])
|
||||
}
|
||||
|
||||
model TagsOnPublications {
|
||||
@ -83,7 +106,6 @@ model User {
|
||||
id String @id @default(cuid())
|
||||
schemas Schema[]
|
||||
gameSystems GameSystem[]
|
||||
publications Publication[]
|
||||
|
||||
name String?
|
||||
username String? @unique
|
||||
@ -96,6 +118,7 @@ model User {
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
PublicationRevision PublicationRevision[]
|
||||
}
|
||||
|
||||
model Account {
|
||||
|
15
types.d.ts
vendored
15
types.d.ts
vendored
@ -31,7 +31,7 @@ type FrontMatter = Record<string, string>;
|
||||
type SearchFunction = (
|
||||
s: string,
|
||||
start: number,
|
||||
end: number
|
||||
end: number,
|
||||
) => {
|
||||
start: number;
|
||||
end: number;
|
||||
@ -53,7 +53,7 @@ type IdentifierRegistration = <N = Record<string, string>>(
|
||||
parseFunction: (s: string, rx: RegExp) => IdentifiedToken<N>,
|
||||
renderFunction: TokenRenderer<N>,
|
||||
openTagRx?: RegExp,
|
||||
closeTagRx?: RegExp
|
||||
closeTagRx?: RegExp,
|
||||
) => void;
|
||||
|
||||
// Schema
|
||||
@ -76,11 +76,16 @@ type Template = {
|
||||
display: string;
|
||||
};
|
||||
|
||||
type SchemaFields = Record<string, string>;
|
||||
|
||||
type SchemaTypes = Record<string, TypeType>;
|
||||
|
||||
type Schema = {
|
||||
id: string;
|
||||
name: string;
|
||||
schema: Record<string, Template>;
|
||||
types: Record<string, TypeType>;
|
||||
schema: SchemaFields;
|
||||
types: SchemaTypes;
|
||||
gameSystemId?: string;
|
||||
};
|
||||
|
||||
// Input Binder
|
||||
@ -88,7 +93,7 @@ type InputBinder = {
|
||||
name: string;
|
||||
value: string | number;
|
||||
onChange: (
|
||||
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>
|
||||
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,
|
||||
) => void;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user