import * as api from '../../client/src/api'; import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types'; import Knex from 'knex'; export const CreateSongEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => { if (!api.checkCreateSongRequest(req)) { const e: EndpointError = { internalMessage: 'Invalid CreateSong request: ' + JSON.stringify(req.body), httpStatus: 400 }; throw e; } const reqObject: api.CreateSongRequest = req.body; console.log("Create Song:", reqObject); await knex.transaction(async (trx) => { try { // Start retrieving artists. const artistIdsPromise = reqObject.artistIds ? trx.select('id') .from('artists') .whereIn('id', reqObject.artistIds) .then((as: any) => as.map((a: any) => a['id'])) : (async () => { return [] })(); // Start retrieving tags. const tagIdsPromise = reqObject.tagIds ? trx.select('id') .from('tags') .whereIn('id', reqObject.tagIds) .then((as: any) => as.map((a: any) => a['id'])) : (async () => { return [] })(); // Start retrieving albums. const albumIdsPromise = reqObject.albumIds ? trx.select('id') .from('albums') .whereIn('id', reqObject.albumIds) .then((as: any) => as.map((a: any) => a['id'])) : (async () => { return [] })(); // Wait for the requests to finish. var [artists, tags, albums] = await Promise.all([artistIdsPromise, tagIdsPromise, albumIdsPromise]);; // Check that we found all objects we need. if ((reqObject.artistIds && artists.length !== reqObject.artistIds.length) || (reqObject.tagIds && tags.length !== reqObject.tagIds.length) || (reqObject.albumIds && albums.length !== reqObject.albumIds.length)) { const e: EndpointError = { internalMessage: 'Not all albums and/or artists and/or tags exist for CreateSong request: ' + JSON.stringify(req.body), httpStatus: 400 }; throw e; } // Create the song. const songId = (await trx('songs') .insert({ title: reqObject.title, storeLinks: JSON.stringify(reqObject.storeLinks || []), }) )[0]; // Link the artists via the linking table. if (artists && artists.length) { await Promise.all( artists.map((artistId: number) => { return trx('songs_artists').insert({ artistId: artistId, songId: songId, }) }) ) } // Link the tags via the linking table. if (tags && tags.length) { await Promise.all( tags.map((tagId: number) => { return trx('songs_tags').insert({ songId: songId, tagId: tagId, }) }) ) } // Link the albums via the linking table. if (albums && albums.length) { await Promise.all( albums.map((albumId: number) => { return trx('songs_albums').insert({ songId: songId, albumId: albumId, }) }) ) } // Respond to the request. const responseObject: api.CreateSongResponse = { id: songId }; res.status(200).send(responseObject); } catch (e) { catchUnhandledErrors(e); trx.rollback(); } }) }