You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

108 lines
4.0 KiB

import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
export const ModifyArtistEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => {
if (!api.checkModifyArtistRequest(req)) {
const e: EndpointError = {
internalMessage: 'Invalid ModifyArtist request: ' + JSON.stringify(req.body),
httpStatus: 400
};
throw e;
}
const reqObject: api.ModifyArtistRequest = req.body;
const { id: userId } = req.user;
console.log("User ", userId, ": Modify Artist ", reqObject);
await knex.transaction(async (trx) => {
try {
const artistId = parseInt(req.params.id);
// Start retrieving the artist itself.
const artistPromise = trx.select('id')
.from('artists')
.where({ 'user': userId })
.where({ id: artistId })
.then((r: any) => (r && r[0]) ? r[0]['id'] : undefined)
// Start retrieving tags.
const tagIdsPromise = reqObject.tagIds ?
trx.select('id')
.from('artists_tags')
.whereIn('id', reqObject.tagIds)
.then((ts: any) => ts.map((t: any) => t['tagId'])) :
(async () => { return undefined })();
// Wait for the requests to finish.
var [artist, tags] = await Promise.all([artistPromise, tagIdsPromise]);;
// Check that we found all objects we need.
if ((reqObject.tagIds && tags.length !== reqObject.tagIds.length) ||
!artist) {
const e: EndpointError = {
internalMessage: 'Not all artists and/or tags exist for ModifyArtist request: ' + JSON.stringify(req.body),
httpStatus: 400
};
throw e;
}
// Modify the artist.
var update: any = {};
if ("name" in reqObject) { update["name"] = reqObject.name; }
if ("storeLinks" in reqObject) { update["storeLinks"] = JSON.stringify(reqObject.storeLinks || []); }
const modifyArtistPromise = trx('artists')
.where({ 'user': userId })
.where({ 'id': artistId })
.update(update)
// Remove unlinked tags.
// TODO: test this!
const removeUnlinkedTags = tags ?
trx('artists_tags')
.where({ 'artistId': artistId })
.whereNotIn('tagId', reqObject.tagIds || [])
.delete() :
undefined;
// Link new tags.
// TODO: test this!
const addTags = tags ? trx('artists_tags')
.where({ 'artistId': artistId })
.then((ts: any) => ts.map((t: any) => t['tagId']))
.then((doneTagIds: number[]) => {
// Get the set of tags that are not yet linked
const toLink = tags.filter((id: number) => {
return !doneTagIds.includes(id);
});
const insertObjects = toLink.map((tagId: number) => {
return {
tagId: tagId,
artistId: artistId,
}
})
// Link them
return Promise.all(
insertObjects.map((obj: any) =>
trx('artists_tags').insert(obj)
)
);
}) : undefined;
// Wait for all operations to finish.
await Promise.all([
modifyArtistPromise,
removeUnlinkedTags,
addTags
]);
// Respond to the request.
res.status(200).send();
} catch (e) {
catchUnhandledErrors(e);
trx.rollback();
}
})
}