Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@
"stripe": "^19.1.0",
"music-metadata": "^11.9.0"
}
}
}
11 changes: 4 additions & 7 deletions api/src/routes/artists/+server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { TABLES } from '../../../../shared/config';
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import type { ArtistRaw } from '../../../../shared/types';
import type { Artist } from '../../../../shared/types/core';

export async function GET() {
return handlePostgrestQuery<ArtistRaw[]>(
async () => await supabase.from(TABLES.artists).select(),
{
transform: (data) => data.sort((a, b) => a.name.localeCompare(b.name))
}
);
return handlePostgrestQuery<Artist[]>(async () => await supabase.from(TABLES.artists).select(), {
transform: (data) => data.sort((a, b) => a.name.localeCompare(b.name))
});
}
14 changes: 8 additions & 6 deletions api/src/routes/artists/[slug]/+server.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { TABLES } from '../../../../../shared/config';
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import type { ArtistRaw } from '../../../../../shared/types';
import type { Artist } from '../../../../../shared/types/core';

export async function GET({ params }) {
return handlePostgrestQuery<ArtistRaw>(
async () => await supabase.from(TABLES.artists).select().eq('id', params.slug).single()
return handlePostgrestQuery<Artist>(
async () => await supabase.from(TABLES.artists).select().eq('id', params.slug).single(),
{ errorMessage: 'Failed to fetch artist' }
);
}

export async function PATCH({ request, params }) {
const body: Partial<ArtistRaw> = await request.json();
return handlePostgrestQuery<ArtistRaw>(
async () => await supabase.from(TABLES.artists).update(body).eq('id', params.slug)
const body: Partial<Artist> = await request.json();
return handlePostgrestQuery<Artist>(
async () => await supabase.from(TABLES.artists).update(body).eq('id', params.slug),
{ errorMessage: 'Failed to update artist details' }
);
}
7 changes: 4 additions & 3 deletions api/src/routes/artists/[slug]/releases/+server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { TABLES } from '../../../../../../shared/config';
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import type { ReleaseHydrated } from '../../../../../../shared/types';
import { TABLES } from '../../../../../../shared/config';
import type { ReleaseHydrated } from '../../../../../../shared/types/hydrated';

export async function GET({ params }) {
return handlePostgrestQuery<ReleaseHydrated[]>(
async () => await supabase.from(TABLES.releasesHydrated).select().eq('artist_id', params.slug)
async () => await supabase.from(TABLES.releasesRich).select().eq('artist_id', params.slug),
{ errorMessage: 'Failed to fetch releases for artist' }
);
}
21 changes: 21 additions & 0 deletions api/src/routes/collections/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import { TABLES } from '../../../../shared/config';

export async function POST({ request }) {
const { userId, name, description } = await request.json();

if (!name) {
return json({ error: 'Missing collection name' }, { status: 400 });
}

const { error } = await supabase
.from(TABLES.collections)
.insert({ user_id: userId, name, description });

if (error) {
return json({ error: 'Failed to create collection' }, { status: 500 });
}

return json({ success: true });
}
63 changes: 63 additions & 0 deletions api/src/routes/collections/[slug]/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import { TABLES } from '../../../../../shared/config';

export async function GET({ params }) {
return handlePostgrestQuery(
async () => supabase.from(TABLES.collectionsRich).select('*').eq('id', params.slug).single(),
{ errorMessage: 'Failed to fetch collection' }
);
}

export async function PATCH({ request, params }) {
const collectionId = params.slug;
const { releaseId, addOrRemove } = await request.json();

if (!releaseId) {
return json({ error: 'Missing release ID' }, { status: 400 });
}

if (addOrRemove === 'remove') {
const { error } = await supabase
.from(TABLES.collectionReleases)
.delete()
.eq('collection_id', collectionId)
.eq('release_id', releaseId);

if (error) {
console.error('Error removing release from collection:', error);
return json({ error: 'Failed to remove release from collection' }, { status: 500 });
}

return json({ success: true });
}

const { error } = await supabase
.from(TABLES.collectionReleases)
.insert({ collection_id: collectionId, release_id: releaseId });

if (error) {
console.error('Error adding release to collection:', error);
return json({ error: 'Failed to add release to collection' }, { status: 500 });
}

return json({ success: true });
}

export async function DELETE({ request, params }) {
const collectionId = params.slug;
const { userId } = await request.json();

const { error } = await supabase
.from(TABLES.collections)
.delete()
.eq('id', collectionId)
.eq('user_id', userId);

if (error) {
console.error('Error deleting collection:', error);
return json({ error: 'Failed to delete collection' }, { status: 500 });
}

return json({ success: true });
}
23 changes: 23 additions & 0 deletions api/src/routes/mixtapes/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import { TABLES } from '../../../../shared/config';

export async function POST({ request }) {
const { userId, name, description } = await request.json();

if (!name) {
console.log('Mixtape name is missing');
return json({ error: 'Missing mixtape name' }, { status: 400 });
}

const { error } = await supabase
.from(TABLES.mixtapes)
.insert({ user_id: userId, name, description });

if (error) {
console.log('Error creating mixtape:', error);
return json({ error: 'Failed to create mixtape' }, { status: 500 });
}

return json({ success: true });
}
47 changes: 47 additions & 0 deletions api/src/routes/mixtapes/[slug]/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import { TABLES } from '../../../../../shared/config';

export async function GET({ params }) {
return handlePostgrestQuery(
async () => supabase.from(TABLES.mixtapesRich).select('*').eq('id', params.slug).single(),
{ errorMessage: 'Failed to fetch mixtape' }
);
}

export async function PATCH({ request, params }) {
const mixtapeId = params.slug;
const { trackId } = await request.json();

if (!trackId) {
return json({ error: 'Missing track ID' }, { status: 400 });
}

const { error } = await supabase
.from(TABLES.mixtapeTracks)
.insert({ mixtape_id: mixtapeId, track_id: trackId });

if (error) {
return json({ error: 'Failed to add track to mixtape' }, { status: 500 });
}

return json({ success: true });
}

export const DELETE = async ({ request, params }) => {
const mixtapeId = params.slug;
const { userId } = await request.json();

const { error } = await supabase
.from(TABLES.mixtapes)
.delete()
.eq('id', mixtapeId)
.eq('user_id', userId);

if (error) {
console.error('Error deleting mixtape:', error);
return json({ error: 'Failed to delete mixtape' }, { status: 500 });
}

return json({ success: true });
};
7 changes: 4 additions & 3 deletions api/src/routes/releases/+server.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import { TABLES } from '../../../../shared/config';
import { sortReleasesByDate } from '../../../../shared/utils';
import type { ReleaseHydrated, ReleaseRaw } from '../../../../shared/types';
import type { ReleaseHydrated } from '../../../../shared/types/hydrated';
import { pinata } from '$lib/server/pinata';
import { json } from '@sveltejs/kit';
import type { Release } from '../../../../shared/types/core';

export async function GET() {
return handlePostgrestQuery<ReleaseHydrated[]>(
async () => await supabase.from(TABLES.releasesHydrated).select(),
async () => await supabase.from(TABLES.releasesRich).select(),
{
errorMessage: 'Failed to fetch artist data',
transform: sortReleasesByDate
Expand All @@ -31,7 +32,7 @@ export async function POST({ request }) {
.name(`'${releaseName}' cover art`)
.group(import.meta.env.PINATA_ARTWORK_GROUP);

return handlePostgrestQuery<ReleaseRaw>(
return handlePostgrestQuery<Release>(
async () =>
await supabase
.from(TABLES.releases)
Expand Down
7 changes: 4 additions & 3 deletions api/src/routes/releases/[slug]/+server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { TABLES } from '../../../../../shared/config';
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import type { ReleaseHydrated } from '../../../../../shared/types';
import { TABLES } from '../../../../../shared/config';
import type { ReleaseHydrated } from '../../../../../shared/types/hydrated';

export async function GET({ params }) {
return handlePostgrestQuery<ReleaseHydrated>(
async () => await supabase.from(TABLES.releasesHydrated).select().eq('id', params.slug).single()
async () => await supabase.from(TABLES.releasesRich).select().eq('id', params.slug).single(),
{ errorMessage: 'Failed to fetch release' }
);
}
2 changes: 1 addition & 1 deletion api/src/routes/search/+server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { supabase } from '$lib/server/supabase';
import type { SearchResult } from '../../../../shared/types';
import type { SearchResult } from '../../../../shared/types/core';
import type { RequestHandler } from './$types';
import { json } from '@sveltejs/kit';

Expand Down
4 changes: 2 additions & 2 deletions api/src/routes/users/[slug]/+server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { TABLES } from '../../../../../shared/config';
import { supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import type { UserProfile } from '../../../../../shared/types';
import type { User } from '../../../../../shared/types/core';

const getUser = async (id: string): Promise<UserProfile | null> => {
const getUser = async (id: string): Promise<User | null> => {
const { data } = await supabase
.from(TABLES.users)
.select(`first_name, tokens_balance, pay_per_stream`)
Expand Down
9 changes: 9 additions & 0 deletions api/src/routes/users/[slug]/collections/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import { TABLES } from '../../../../../../shared/config/index';

export async function GET({ params }) {
return handlePostgrestQuery(
async () => supabase.from(TABLES.collectionsRich).select('*').eq('user_id', params.slug),
{ errorMessage: 'Failed to fetch collections' }
);
}
28 changes: 3 additions & 25 deletions api/src/routes/users/[slug]/likes/+server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { TABLES } from '../../../../../../shared/config';
import { supabase } from '$lib/server/supabase';
import { json } from '@sveltejs/kit';
import type { LikedTrackObject } from '../../../../../../shared/types';

export async function GET({ params }) {
const maybeUserID = params.slug;
Expand All @@ -15,9 +14,9 @@ export async function GET({ params }) {
return json({ error: 'Failed to fetch liked tracks' }, { status: 500 });
}

const { data: likedTracksRaw, error: likedTracksError } = await supabase
.from(TABLES.tracks)
.select(`id, artist_id, title, ipfs_cid, duration_seconds, created_at`)
const { data: likedTracks, error: likedTracksError } = await supabase
.from('tracks_hydrated')
.select('*')
.in(
'id',
likedTrackIDs.map((item) => item.track_id)
Expand All @@ -27,27 +26,6 @@ export async function GET({ params }) {
return json({ error: 'Failed to fetch liked tracks details' }, { status: 500 });
}

const likedTracks: LikedTrackObject[] = [];

for (const likedTrack of likedTracksRaw) {
const { data: releaseID, error: releaseIDError } = await supabase
.from(TABLES.releaseTracks)
.select('release_id')
.eq('track_id', likedTrack.id)
.limit(1)
.single();
if (releaseIDError) {
console.error('Error fetching release ID:', releaseIDError);
continue;
}
const { data: release } = await supabase
.from(TABLES.releasesHydrated)
.select('*')
.eq('id', releaseID.release_id)
.single();
likedTracks.push({ track: likedTrack, release });
}

return json(likedTracks);
}

Expand Down
9 changes: 9 additions & 0 deletions api/src/routes/users/[slug]/mixtapes/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { handlePostgrestQuery, supabase } from '$lib/server/supabase';
import { TABLES } from '../../../../../../shared/config';

export async function GET({ params }) {
return handlePostgrestQuery(
async () => supabase.from(TABLES.mixtapesRich).select('*').eq('user_id', params.slug),
{ errorMessage: 'Failed to fetch mixtapes' }
);
}
12 changes: 11 additions & 1 deletion app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"dependencies": {
"@supabase/ssr": "^0.7.0",
"@supabase/supabase-js": "^2.74.0"
"@supabase/supabase-js": "^2.74.0",
"zod": "^4.1.12"
}
}
}
Loading