Improved upload

This commit is contained in:
Sebastian Seedorf
2022-08-18 10:38:48 +02:00
parent ffb93d9da4
commit d97786f880
11 changed files with 93 additions and 52 deletions

View File

@@ -91,7 +91,7 @@ interface StoredFile {
excludedSuggestions: string[] excludedSuggestions: string[]
} }
export const postFetchJson = async (url: string, body: Dict<unknown>) => { export const postFetchJson = async (url: string, body: unknown) => {
const res = await fetch(url, { const res = await fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {

View File

@@ -4,11 +4,12 @@ import styles from './Home.module.css'
import { useFactories } from '../../src/hooks/useFactories' import { useFactories } from '../../src/hooks/useFactories'
import { EnrichedEntity } from '../../src/types' import { EnrichedEntity } from '../../src/types'
import { EntitySpan } from './EntitySpan/EntitySpan' import { EntitySpan } from './EntitySpan/EntitySpan'
import { useGroups } from '../contexts/GroupProvider' import {postFetchJson, useGroups} from '../contexts/GroupProvider'
import { Preferences } from './Preferences/Preferences' import { Preferences } from './Preferences/Preferences'
import { download, streamToArrayBuffer } from '../../src/download' import { download, streamToArrayBuffer } from '../../src/download'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import {UploadDataBody} from '../../src/types/ApiSchemasFrontend'
export const Home: FC = () => { export const Home: FC = () => {
const router = useRouter() const router = useRouter()
@@ -49,19 +50,7 @@ export const Home: FC = () => {
Store Store
</button> </button>
<button <button
onClick={async () => { onClick={() => postFetchJson(`/api/${router.query.id}/upload`, { groups, ignored: ignoredFactories, base: baseFactories } as UploadDataBody)}
const res = await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ groups, ignored: ignoredFactories, base: baseFactories })
})
if (res.ok) {
const { uuid } = await res.json()
if (uuid) await router.push({ query: { ...router.query, id: uuid } })
}
}}
> >
Upload Upload
</button> </button>

17
pages/api/[id]/upload.ts Normal file
View File

@@ -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<IdParam>(req.query, '/IdParam')
const { transformed: body } = validate<UploadDataBody>(req.body, '/UploadDataBody')
const uuid = await setData(params.id, body)
res.json({ uuid })
})
export default handler

View File

@@ -9,6 +9,7 @@ const {
const handler = nextHandler(async (req, res) => { const handler = nextHandler(async (req, res) => {
if (req.method !== 'GET') throw new NetworkError('Invalid method') if (req.method !== 'GET') throw new NetworkError('Invalid method')
if (TENANT_TYPE !== 'local') throw new NetworkError('Not allowed', undefined, 400) if (TENANT_TYPE !== 'local') throw new NetworkError('Not allowed', undefined, 400)
waitForInitSchemas.reset()
await waitForInitSchemas.resolve() await waitForInitSchemas.resolve()
res.json({ success: true }) res.json({ success: true })
}) })

View File

@@ -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

View File

@@ -16,9 +16,10 @@ export type InsertMeta<T> = T & {
type GroupFilter = Filter<InsertMeta<GroupData>> type GroupFilter = Filter<InsertMeta<GroupData>>
export async function setGroups(data: GroupData): Promise<string | undefined> { export async function setData(uuid: string|undefined, data: GroupData): Promise<string | undefined> {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return if (!collection) return
if (!uuid) {
const result = await collection.insertOne({ const result = await collection.insertOne({
...data, ...data,
createdOn: new Date(), createdOn: new Date(),
@@ -26,6 +27,15 @@ export async function setGroups(data: GroupData): Promise<string | undefined> {
accessedOn: new Date() accessedOn: new Date()
}) })
return result.insertedId.toString() 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 { function getUuid(uuid: string): GroupFilter {
@@ -45,7 +55,7 @@ export async function setFactories(
return true return true
} }
export async function getGroup(uuid: string) { export async function getData(uuid: string) {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return if (!collection) return
const data = (await collection.findOne(getUuid(uuid))) ?? undefined const data = (await collection.findOne(getUuid(uuid))) ?? undefined
@@ -62,7 +72,7 @@ export async function renameGroup(
): Promise<boolean> { ): Promise<boolean> {
oldName = oldName.replace(/[.$]/g, '') oldName = oldName.replace(/[.$]/g, '')
newName = newName.replace(/[.$]/g, '') newName = newName.replace(/[.$]/g, '')
const data = await getGroup(uuid) const data = await getData(uuid)
if (data?.groups && !(newName in data.groups)) { if (data?.groups && !(newName in data.groups)) {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return false if (!collection) return false
@@ -83,7 +93,7 @@ export async function renameGroup(
export async function addGroup(uuid: string, name: string): Promise<boolean> { export async function addGroup(uuid: string, name: string): Promise<boolean> {
name = name.replace(/[.$]/g, '') name = name.replace(/[.$]/g, '')
const data = await getGroup(uuid) const data = await getData(uuid)
if (data?.groups && !(name in data.groups)) { if (data?.groups && !(name in data.groups)) {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return false if (!collection) return false
@@ -97,7 +107,7 @@ export async function addGroup(uuid: string, name: string): Promise<boolean> {
export async function removeGroup(uuid: string, name: string): Promise<boolean> { export async function removeGroup(uuid: string, name: string): Promise<boolean> {
name = name.replace(/[.$]/g, '') name = name.replace(/[.$]/g, '')
const data = await getGroup(uuid) const data = await getData(uuid)
if (data?.groups && name in data.groups) { if (data?.groups && name in data.groups) {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return false if (!collection) return false
@@ -114,7 +124,7 @@ export async function setFactoriesOfGroup(
factories: string[] factories: string[]
): Promise<boolean> { ): Promise<boolean> {
name = name.replace(/[.$]/g, '') name = name.replace(/[.$]/g, '')
const data = await getGroup(uuid) const data = await getData(uuid)
if (data?.groups && name in data.groups) { if (data?.groups && name in data.groups) {
const collection = (await database.resolve())?.collection('setups') const collection = (await database.resolve())?.collection('setups')
if (!collection) return false if (!collection) return false

View File

@@ -1,5 +1,5 @@
import { GetServerSideProps } from 'next' import { GetServerSideProps } from 'next'
import { getGroup, setGroups } from './database/groups' import { getData, setData } from './database/groups'
import { Dict, Group } from './types' import { Dict, Group } from './types'
export interface PropsGroupProvider { export interface PropsGroupProvider {
@@ -13,7 +13,7 @@ export const getServerSidePropsGroupProvider: GetServerSideProps<PropsGroupProvi
query query
}) => { }) => {
const id = Array.isArray(query?.id) ? query.id[0] : query?.id 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) { if (data) {
return { return {
props: { props: {
@@ -24,7 +24,7 @@ export const getServerSidePropsGroupProvider: GetServerSideProps<PropsGroupProvi
} }
} }
} else if (!id) { } else if (!id) {
const newId = await setGroups({ groups: {}, base: [], ignored: [] }) const newId = await setData(undefined, { groups: {}, base: [], ignored: [] })
return { return {
redirect: { redirect: {
destination: `?id=${newId}`, destination: `?id=${newId}`,

View File

@@ -20,6 +20,17 @@ export interface SetFactoryArrayBody {
type: 'ignored' | 'base' type: 'ignored' | 'base'
factories: string[] factories: string[]
} }
export interface UploadDataBody {
groups: {
[k: string]: {
name: string
exports: string[]
malls: string[]
}
}
ignored: string[]
base: string[]
}
export interface IdParam { export interface IdParam {
id: string id: string
} }

View File

@@ -7,24 +7,30 @@
export interface GroupRenameBody { export interface GroupRenameBody {
newName: string newName: string
[k: string]: unknown
} }
export interface GroupSetFactoryArrayBody { export interface GroupSetFactoryArrayBody {
type: 'exports' | 'malls' type: 'exports' | 'malls'
factories: string[] factories: string[]
[k: string]: unknown
} }
export interface GroupIdParam { export interface GroupIdParam {
id: string id: string
name: string name: string
[k: string]: unknown
} }
export interface SetFactoryArrayBody { export interface SetFactoryArrayBody {
type: 'ignored' | 'base' type: 'ignored' | 'base'
factories: string[] factories: string[]
[k: string]: unknown }
export interface UploadDataBody {
groups: {
[k: string]: {
name: string
exports: string[]
malls: string[]
}
}
ignored: string[]
base: string[]
} }
export interface IdParam { export interface IdParam {
id: string id: string
[k: string]: unknown
} }

View File

@@ -27,9 +27,10 @@ export async function addSchema(schemas: JSONSchema[]) {
// compile schema to interface // compile schema to interface
let entity = await compile(schema, schema.id, { let entity = await compile(schema, schema.id, {
style, style,
bannerComment: data === '' ? undefined : '\n\n\n' bannerComment: data === '' ? undefined : '\n\n\n',
additionalProperties: false
}) })
entity = entity.replace(/^( {2})+\[k: string]: unknown\n/gm, '') //entity = entity.replace(/^( {2})+\[k: string]: unknown\n/gm, '')
dataFrontend += entity dataFrontend += entity
// remove ? from defaulted properties // remove ? from defaulted properties
const defaults = getDefaults(schema) const defaults = getDefaults(schema)

View File

@@ -38,6 +38,26 @@ export function addSchemas() {
factories: { type: 'array', items: { type: 'string', minLength: 3 } } factories: { type: 'array', items: { type: 'string', minLength: 3 } }
} }
}, },
{
id: '/UploadDataBody',
type: 'object',
required: ['groups', 'ignored', 'base'],
properties: {
groups: { type: 'object',
additionalProperties: {
type: 'object',
required: ['name', 'exports', 'malls'],
properties: {
name: {type: 'string', minLength: 1},
exports: {type: 'array', items: {type: 'string', minLength: 3}},
malls: {type: 'array', items: {type: 'string', minLength: 3}}
},
}
},
ignored: { type: 'array', items: { type: 'string', minLength: 3 } },
base: { type: 'array', items: { type: 'string', minLength: 3 } }
}
},
{ {
id: 'IdParam', id: 'IdParam',
type: 'object', type: 'object',