auth init

This commit is contained in:
ntr committed 2022-08-08 19:51:17 +10:00
1 parent faa2e70e08
commit 413aeedadf
29 files changed
+2854 -649

No files matched your search

+157
View File
@@ -0,0 +1,157 @@
import bcrypt from 'bcrypt';
import type Log from 'bunyan';
import type { PrismaClient, Want, User, Listing, Prisma } from '@prisma/client';
import * as Bluebird from 'bluebird';
export interface UserCreateParams {
discogs: DiscogsName | null,
email: string,
password: string,
data: any,
}
export interface Pg {
userFindId: (id: UUID) => Promise<User>,
userFindEmail: (email: Email) => Promise<User>,
userCreate: (params: UserCreateParams) => Promise<User>,
userWants: (user: User) => Promise<Want[]>,
wantUpsert: (want: Want, user: User) => Promise<Want>,
listingUpsert: (listing: Listing, want: Want) => Promise<Listing>,
listingFind: (id: DiscogsListing) => Promise<Listing>,
listingRmUnlisted: (want: Want, ids: DiscogsListing[]) => Promise<number>,
bundleCandidates: () => Promise<Listing[][]>,
}
export default function createPg(log: Log, prisma: PrismaClient): Pg {
async function userFindId(id: UUID) {
return prisma.user.findUnique({ where: { id }});
}
async function userFindEmail(email: Email) {
return prisma.user.findUnique({ where: { email }});
}
async function userWants(user: User) {
return prisma.want.findMany({ where: { userId: user.id }});
}
async function userCreate(params: UserCreateParams) {
const hashRounds = 10;
const password = await bcrypt.hash(params.password, hashRounds);
const data = {
discogs: params.discogs,
email: params.email,
data: params.data,
password,
};
return prisma.user.create({
data,
});
}
async function wantUpsert(dcWant, user) {
const values: { userId: UUID, release: DiscogsListing, data: any } = {
data: dcWant,
release: dcWant.id,
userId: user.id,
};
return prisma.want.upsert({
// get these from the generated types
// ./node_modules/.prisma/client/index.d.ts
where: { userId_release: {
userId: values.userId,
release: values.release || null,
}},
update: values,
create: values,
});
}
async function listingRmUnlisted(want: Want, ids: DiscogsListing[]) {
const { count } = await prisma.listing.deleteMany({
where: {
wantId: want.id,
id: {
notIn: ids,
}
}
});
return count;
}
async function listingUpsert(listing, want) {
const values = {
id: listing.id,
wantId: want.id,
seller: listing.seller.id,
data: listing,
};
return prisma.listing.upsert({
where: {
id: listing.id
},
update: values,
create: values,
});
}
async function listingFind(id: DiscogsListing) {
return prisma.listing.findUnique({
where: {
id,
},
include: {
want: {
include: { user: true },
}
}
});
}
async function bundleCandidates(): Promise<Listing[][]> {
const candidates = await prisma.$queryRaw`
select
seller, count(distinct("wantId")), array_agg(id) as listings
from
listings
group by
seller
order by
count desc
limit 5;
` as BundleCandidate[];
return Promise.all(candidates.map(async c => prisma.listing.findMany({
where: {
id: { in: c.listings }
},
include: {
want: {
include: { user: true },
}
},
distinct: ['wantId'],
})));
}
return {
userFindId,
userFindEmail,
userCreate,
userWants,
wantUpsert,
listingUpsert,
listingFind,
listingRmUnlisted,
bundleCandidates,
};
}