want events
This commit is contained in:
1 parent
f5e75f4fe6
commit
30bf7426e4
19 files changed
+293
-108
No files matched your search
@@ -40,7 +40,7 @@ model User {
|
||||
|
||||
model Want {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
release Int?
|
||||
release Int
|
||||
data Json
|
||||
|
||||
userId String @db.Uuid
|
||||
|
||||
@@ -11,7 +11,6 @@ const services = createServices(log);
|
||||
const HOST = 'http://localhost:41337';
|
||||
|
||||
before(function setup() {
|
||||
console.log('setup')
|
||||
services.api.listen();
|
||||
});
|
||||
|
||||
|
||||
+29
-11
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user