add mongo

This commit is contained in:
Sebastian Seedorf
2022-08-17 09:09:49 +02:00
parent 1522962edd
commit fe7e6d8ae2
10 changed files with 326 additions and 2 deletions

19
src/database/groups.ts Normal file
View File

@@ -0,0 +1,19 @@
import {database} from "./start";
import {Dict, Group} from "../types";
import crypto from "crypto"
export async function setGroups(groups: Dict<Group>, ignored: string[], base: string[]) {
const collection = (await database.resolve())?.collection('setups')
if (!collection) return
await collection.deleteMany({}).catch(e => {
if (e.message !== 'ns not found') throw e
})
const result = await collection.insertOne({
groups,
ignored,
base,
createdOn: new Date(),
modifiedOn: new Date()
})
return result.insertedId.toString()
}

20
src/database/start.ts Normal file
View File

@@ -0,0 +1,20 @@
import {Db, MongoClient} from 'mongodb'
import getConfig from 'next/config'
import {Resolvable} from "../utils/Resolvable";
const { serverRuntimeConfig: {
MONGO_URL,
MONGO_USER,
MONGO_PASS,
MONGO_DB
} } = getConfig()
async function getDatabase(): Promise<Db | undefined> {
const url = `mongodb://${MONGO_USER ? `${MONGO_USER}:${MONGO_PASS ?? ''}@` : ''}${MONGO_URL}`;
const client = new MongoClient(url);
await client.connect();
console.log('Connected successfully to server')
return client.db(MONGO_DB)
}
export const database = new Resolvable(getDatabase)

22
src/next-types.d.ts vendored Normal file
View File

@@ -0,0 +1,22 @@
declare module 'next/config' {
export interface ServerRuntimeConfig {
MONGO_URL: string
MONGO_DB: string
MONGO_USER?: string
MONGO_PASS?: string
}
export interface PublicRuntimeConfig {
}
const getConfig: () => {
serverRuntimeConfig: ServerRuntimeConfig,
publicRuntimeConfig: PublicRuntimeConfig
}
//export const serConfig = () =>
export default getConfig
}

97
src/utils/Resolvable.ts Normal file
View File

@@ -0,0 +1,97 @@
// eslint-disable-next-line no-shadow
enum ResolvableState {
WAITING,
PENDING,
ERROR,
DONE
}
class FetchOnce<T> {
protected data: T | undefined
protected error: unknown | undefined
protected state: ResolvableState = ResolvableState.WAITING
protected pendingList: [(res: Promise<T> | T) => void, (reason: unknown) => void][] = []
constructor(protected fetchMethod?: () => Promise<T>) {}
public reset(): void {
this.data = undefined
this.error = undefined
this.state = ResolvableState.WAITING
}
public resolve(): Promise<T> {
return new Promise((resolve, reject) => {
switch (this.state) {
case ResolvableState.WAITING:
this.state = ResolvableState.PENDING
this.pendingList.push([resolve, reject])
if (this.fetchMethod) this.parsePromise(this.fetchMethod())
break
case ResolvableState.PENDING:
this.pendingList.push([resolve, reject])
break
case ResolvableState.DONE:
resolve(this.data!)
break
case ResolvableState.ERROR:
reject(this.error)
break
}
})
}
protected isFinished(): boolean {
return this.state === ResolvableState.DONE || this.state === ResolvableState.ERROR
}
protected parsePromise(promise: Promise<T>): void {
promise
.then(data => {
this.data = data
this.state = ResolvableState.DONE
this.pendingList.forEach(pending => pending[0](data))
})
.catch(err => {
this.error = err
this.state = ResolvableState.ERROR
this.pendingList.forEach(pending => pending[1](err))
})
}
}
export class Resolvable<T, U extends Array<unknown>> extends FetchOnce<T> {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(fetchMethod: (...args: U) => Promise<T>) {
super(fetchMethod)
}
}
export class WaitForSync<T> extends FetchOnce<T> {
protected state: ResolvableState = ResolvableState.PENDING
constructor() {
super(undefined)
}
public setData(data: T): void {
if (!this.isFinished()) {
this.parsePromise((async () => data)())
}
}
public setError(error: unknown): void {
if (!this.isFinished()) {
this.parsePromise(
(async () => {
throw error
})()
)
}
}
public reset(): void {
super.reset()
this.state = ResolvableState.PENDING
}
}