From d97786f8803cb282dbdbc85afc059c35b416de22 Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Thu, 18 Aug 2022 10:38:48 +0200 Subject: [PATCH] Improved upload --- components/contexts/GroupProvider.tsx | 2 +- components/home/Home.tsx | 17 +++---------- pages/api/[id]/upload.ts | 17 +++++++++++++ pages/api/dev/schemas.ts | 1 + pages/api/submit.ts | 14 ----------- src/database/groups.ts | 36 +++++++++++++++++---------- src/getServerSideProps.ts | 6 ++--- src/types/ApiSchemas.ts | 11 ++++++++ src/types/ApiSchemasFrontend.ts | 16 ++++++++---- src/validation/index.ts | 5 ++-- src/validation/schemas.ts | 20 +++++++++++++++ 11 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 pages/api/[id]/upload.ts delete mode 100644 pages/api/submit.ts diff --git a/components/contexts/GroupProvider.tsx b/components/contexts/GroupProvider.tsx index e36e4a4..19066e3 100644 --- a/components/contexts/GroupProvider.tsx +++ b/components/contexts/GroupProvider.tsx @@ -91,7 +91,7 @@ interface StoredFile { excludedSuggestions: string[] } -export const postFetchJson = async (url: string, body: Dict) => { +export const postFetchJson = async (url: string, body: unknown) => { const res = await fetch(url, { method: 'POST', headers: { diff --git a/components/home/Home.tsx b/components/home/Home.tsx index cfcf15a..18bf378 100644 --- a/components/home/Home.tsx +++ b/components/home/Home.tsx @@ -4,11 +4,12 @@ import styles from './Home.module.css' import { useFactories } from '../../src/hooks/useFactories' import { EnrichedEntity } from '../../src/types' import { EntitySpan } from './EntitySpan/EntitySpan' -import { useGroups } from '../contexts/GroupProvider' +import {postFetchJson, useGroups} from '../contexts/GroupProvider' import { Preferences } from './Preferences/Preferences' import { download, streamToArrayBuffer } from '../../src/download' import Link from 'next/link' import { useRouter } from 'next/router' +import {UploadDataBody} from '../../src/types/ApiSchemasFrontend' export const Home: FC = () => { const router = useRouter() @@ -49,19 +50,7 @@ export const Home: FC = () => { Store diff --git a/pages/api/[id]/upload.ts b/pages/api/[id]/upload.ts new file mode 100644 index 0000000..a858f26 --- /dev/null +++ b/pages/api/[id]/upload.ts @@ -0,0 +1,17 @@ +import { setData } from '../../../src/database/groups' +import { nextHandler } from '../../../src/utils/errors' +import { waitForInitSchemas } from '../../../src/validation/schemas' +import {validate} from '../../../src/validation' +import {IdParam, UploadDataBody} from '../../../src/types/ApiSchemas' + +const handler = nextHandler(async (req, res) => { + if (req.method !== 'POST') throw new Error('Invalid method') + await waitForInitSchemas.resolve() + const { transformed: params } = validate(req.query, '/IdParam') + const { transformed: body } = validate(req.body, '/UploadDataBody') + + const uuid = await setData(params.id, body) + res.json({ uuid }) +}) + +export default handler diff --git a/pages/api/dev/schemas.ts b/pages/api/dev/schemas.ts index e28ade5..ef7e1a5 100644 --- a/pages/api/dev/schemas.ts +++ b/pages/api/dev/schemas.ts @@ -9,6 +9,7 @@ const { const handler = nextHandler(async (req, res) => { if (req.method !== 'GET') throw new NetworkError('Invalid method') if (TENANT_TYPE !== 'local') throw new NetworkError('Not allowed', undefined, 400) + waitForInitSchemas.reset() await waitForInitSchemas.resolve() res.json({ success: true }) }) diff --git a/pages/api/submit.ts b/pages/api/submit.ts deleted file mode 100644 index c26db4f..0000000 --- a/pages/api/submit.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GroupData, setGroups } from '../../src/database/groups' -import { nextHandler } from '../../src/utils/errors' -import { waitForInitSchemas } from '../../src/validation/schemas' - -const handler = nextHandler(async (req, res) => { - if (req.method !== 'POST') throw new Error('Invalid method') - await waitForInitSchemas.resolve() - const data = req.body as GroupData - - const uuid = await setGroups(data) - res.json({ uuid }) -}) - -export default handler diff --git a/src/database/groups.ts b/src/database/groups.ts index 1d93c11..05c8610 100644 --- a/src/database/groups.ts +++ b/src/database/groups.ts @@ -16,16 +16,26 @@ export type InsertMeta = T & { type GroupFilter = Filter> -export async function setGroups(data: GroupData): Promise { +export async function setData(uuid: string|undefined, data: GroupData): Promise { const collection = (await database.resolve())?.collection('setups') if (!collection) return - const result = await collection.insertOne({ - ...data, - createdOn: new Date(), - modifiedOn: new Date(), - accessedOn: new Date() - }) - return result.insertedId.toString() + if (!uuid) { + const result = await collection.insertOne({ + ...data, + createdOn: new Date(), + modifiedOn: new Date(), + accessedOn: new Date() + }) + return result.insertedId.toString() + } else { + await collection.findOneAndReplace(getUuid(uuid), { + ...data, + createdOn: new Date(), + modifiedOn: new Date(), + accessedOn: new Date() + }) + return uuid + } } function getUuid(uuid: string): GroupFilter { @@ -45,7 +55,7 @@ export async function setFactories( return true } -export async function getGroup(uuid: string) { +export async function getData(uuid: string) { const collection = (await database.resolve())?.collection('setups') if (!collection) return const data = (await collection.findOne(getUuid(uuid))) ?? undefined @@ -62,7 +72,7 @@ export async function renameGroup( ): Promise { oldName = oldName.replace(/[.$]/g, '') newName = newName.replace(/[.$]/g, '') - const data = await getGroup(uuid) + const data = await getData(uuid) if (data?.groups && !(newName in data.groups)) { const collection = (await database.resolve())?.collection('setups') if (!collection) return false @@ -83,7 +93,7 @@ export async function renameGroup( export async function addGroup(uuid: string, name: string): Promise { name = name.replace(/[.$]/g, '') - const data = await getGroup(uuid) + const data = await getData(uuid) if (data?.groups && !(name in data.groups)) { const collection = (await database.resolve())?.collection('setups') if (!collection) return false @@ -97,7 +107,7 @@ export async function addGroup(uuid: string, name: string): Promise { export async function removeGroup(uuid: string, name: string): Promise { name = name.replace(/[.$]/g, '') - const data = await getGroup(uuid) + const data = await getData(uuid) if (data?.groups && name in data.groups) { const collection = (await database.resolve())?.collection('setups') if (!collection) return false @@ -114,7 +124,7 @@ export async function setFactoriesOfGroup( factories: string[] ): Promise { name = name.replace(/[.$]/g, '') - const data = await getGroup(uuid) + const data = await getData(uuid) if (data?.groups && name in data.groups) { const collection = (await database.resolve())?.collection('setups') if (!collection) return false diff --git a/src/getServerSideProps.ts b/src/getServerSideProps.ts index 88f2879..54636aa 100644 --- a/src/getServerSideProps.ts +++ b/src/getServerSideProps.ts @@ -1,5 +1,5 @@ import { GetServerSideProps } from 'next' -import { getGroup, setGroups } from './database/groups' +import { getData, setData } from './database/groups' import { Dict, Group } from './types' export interface PropsGroupProvider { @@ -13,7 +13,7 @@ export const getServerSidePropsGroupProvider: GetServerSideProps { const id = Array.isArray(query?.id) ? query.id[0] : query?.id - const data = id && (await getGroup(id)) + const data = id?.match(/[a-f0-9]{24}/) && (await getData(id).catch(() => undefined)) if (data) { return { props: { @@ -24,7 +24,7 @@ export const getServerSidePropsGroupProvider: GetServerSideProps