want events

This commit is contained in:
ntr committed 2022-08-17 23:22:48 +10:00
1 parent f5e75f4fe6
commit 30bf7426e4
19 files changed
+293 -108

No files matched your search

-1
View File
@@ -11,7 +11,6 @@ const services = createServices(log);
const HOST = 'http://localhost:41337';
before(function setup() {
console.log('setup')
services.api.listen();
});
+29 -11
View File
@@ -14,8 +14,9 @@ import type { Listing, User, Want, Prisma } from '@prisma/client';
import { Pg } from './pg';
import routerAuth from './routers/router.auth';
import { Events } from './events';
export default function createApi(log: Log, pg: Pg, discogs) {
export default function createApi(log: Log, pg: Pg, discogs, events) {
const PORT = 41337;
const SECRET = 'ohja4Eif9eidah3aj5ta2haa4iemooth';
@@ -147,23 +148,40 @@ export default function createApi(log: Log, pg: Pg, discogs) {
ctx.response.body = listings;
});
router.get('/wants', async function wantPost(ctx, next) {
const { userId, releaseId } = ctx.request.body;
const user = await pg.userFindId(userId);
router.post('/want', async function wantPost(ctx, next) {
ctx.assert(ctx.isAuthenticated(), 401, 'log in required');
const { releaseId } = ctx.request.body;
const user = await pg.userFindId(ctx.state.user.id);
const release = await discogs.release(releaseId);
const want = await pg.wantUpsert(release, user);
ctx.response.body = want;
const want = await pg.wantCreate([release], user);
// fetch listings
const listings = await discogs.listings(want);
ctx.response.body = { want, listings };
});
router.get('/wants', async function wantGet(ctx, next) {
router.post('/want/discogs', async function wantListPost(ctx, next) {
ctx.assert(ctx.isAuthenticated(), 401, 'log in required');
log.warn(ctx.state.user);
const user = ctx.state.user;
const wants = await pg.wantFind(user);
const { username } = ctx.request.body;
const user = await pg.userFindId(ctx.state.user.id);
const wants = await discogs.wantListSync(username, user);
events.emit(Events.WantsAdded, wants);
ctx.response.body = wants;
});
router.post('/wants/search', async function wantPost(ctx, next) {
router.get('/want/all', async function wantGet(ctx, next) {
ctx.assert(ctx.isAuthenticated(), 401, 'log in required');
const user = ctx.state.user;
const wants = await pg.wantList(user);
ctx.response.body = wants;
});
router.post('/want/search', async function wantPost(ctx, next) {
const { artist, title } = ctx.request.body;
const results = await discogs.search(artist, title);
ctx.response.body = results;
+10 -26
View File
@@ -31,30 +31,15 @@ export default function discogs(log: Log, pg: Pg) {
return null;
}
// async function user(discogs: string) {
// const user = await pg.userFindName(discogs);
// if (user) return user;
// log.debug('fetching user', discogs);
// const { data } = await api.get(`${apiBase}/users/${discogs}`);
// return pg.userUpsert(data.username, data.username, data);
// }
async function wantlist(user: User): Promise<Want[]> {
const stored = await pg.userWants(user);
if (stored.length) return stored;
if (!user.discogs) {
log.error(user, 'attempted to fetch wantlist of non discogs user');
throw new Error('User is not associated with a discogs account');
}
return wantlistLatest(user);
}
async function wantlistLatest(user: User): Promise<Want[]> {
const { username } = user.data as { username: string };
async function wantListSync(username: string, user: User): Promise<Want[]> {
const { data: { wants, pagination }} = await api.get(`${apiBase}/users/${username}/wants`);
return Bluebird.mapSeries(wants, async r => pg.wantUpsert(r, user));
const releases = await Promise.all(wants.map(want => release(want.id)));
// convert want object to actual release and ignore duplicate errors
const results = await Promise.allSettled(releases.map(release => pg.wantCreate(release, user)));
// @ts-ignore
const additions = results.filter(r => r.status === 'fulfilled').map(r => r.value);
return additions;
}
async function release(id: DiscogsRelease): Promise<any> {
@@ -99,6 +84,7 @@ export default function discogs(log: Log, pg: Pg) {
try {
log.debug('fetching listing', id);
const res = await api.get(`${apiBase}/marketplace/listings/${id}`);
log.info(res.data);
return pg.listingUpsert(res.data, want);
} catch (e) {
return handleApiError(e);
@@ -106,9 +92,7 @@ export default function discogs(log: Log, pg: Pg) {
}
return {
// user,
wantlist,
wantlistLatest,
wantListSync,
inventory,
listings,
listing,
+25
View File
@@ -0,0 +1,25 @@
import { EventEmitter } from 'node:events';
import type Log from 'bunyan';
import type { Listing, User, Want, Prisma } from '@prisma/client';
import { Pg } from './pg';
import routerAuth from './routers/router.auth';
export enum Events {
WantsAdded = 'WantsAdded',
}
export function eventService(log: Log, pg: Pg, discogs) {
const events = new EventEmitter({ captureRejections: true });
events.on('error', function eventError(e) {
log.error(e);
});
events.on(Events.WantsAdded, async function wantsAdded(wants: Want[]) {
log.info('wants added', wants);
});
return events;
}
+10 -16
View File
@@ -16,8 +16,8 @@ export interface Pg {
userCreate: (params: UserCreateParams) => Promise<User>,
userWants: (user: User) => Promise<Want[]>,
wantUpsert: (want: Want, user: User) => Promise<Want>,
wantFind: (user: User) => Promise<Want[]>,
wantCreate: (discogsWant: any, user: User) => Promise<Want>,
wantList: (user: User) => Promise<Want[]>,
listingUpsert: (listing: Listing, want: Want) => Promise<Listing>,
listingFind: (id: DiscogsListing) => Promise<Listing>,
listingRmUnlisted: (want: Want, ids: DiscogsListing[]) => Promise<number>,
@@ -60,22 +60,15 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
});
}
async function wantUpsert(dcWant, user) {
const values: { userId: UUID, release: DiscogsListing, data: any } = {
data: dcWant,
release: dcWant.id,
async function wantCreate(discogsRelease, user) {
const data: { userId: UUID, release: DiscogsListing, data: any } = {
data: discogsRelease,
release: discogsRelease.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,
return prisma.want.create({
data,
});
}
@@ -154,7 +147,8 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
userCreate,
userWants,
wantUpsert,
wantCreate,
wantList,
listingUpsert,
listingFind,
listingRmUnlisted,
+7 -5
View File
@@ -2,20 +2,22 @@ import { PrismaClient } from '@prisma/client'
import discogsService from './discogs';
import pgService from './pg';
import { logAxiosError } from './utils';
import createLog from './log';
import createApi from './api';
import { eventService } from './events';
export default function createServices(log) {
const prisma = new PrismaClient();
const pg = pgService(log, prisma);
const discogs = discogsService(log, pg);
const api = createApi(log, pg, discogs);
const events = eventService(log, pg, discogs);
const api = createApi(log, pg, discogs, events);
return {
prisma,
pg,
discogs,
api,
discogs,
events,
pg,
prisma,
};
}