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
15 changes: 11 additions & 4 deletions lib/artist/updateArtistSocials.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getSocialPlatformByLink } from "@/lib/artists/getSocialPlatformByLink";
import { getUsernameFromProfileUrl } from "@/lib/socials/getUsernameFromProfileUrl";
import { normalizeProfileUrl } from "@/lib/socials/normalizeProfileUrl";
import { selectAccountSocials } from "@/lib/supabase/account_socials/selectAccountSocials";
import { deleteAccountSocial } from "@/lib/supabase/account_socials/deleteAccountSocial";
import { insertAccountSocial } from "@/lib/supabase/account_socials/insertAccountSocial";
Expand All @@ -23,8 +24,13 @@ export async function updateArtistSocials(

// Process each platform type
const profilePromises = Object.entries(profileUrls).map(async ([type, value]) => {
const socials = value ? await selectSocials({ profile_url: value }) : null;
const normalizedUrl = normalizeProfileUrl(value);

const socials = normalizedUrl
? await selectSocials({ profile_url: normalizedUrl })
: null;
const social = socials && socials.length > 0 ? socials[0] : null;

const existingSocial = (accountSocials || []).find(
(account_social: AccountSocialWithSocial) =>
getSocialPlatformByLink(account_social.social?.profile_url || "") === type,
Expand All @@ -36,7 +42,7 @@ export async function updateArtistSocials(
}

// Insert new social if URL provided
if (value) {
if (normalizedUrl) {
if (social) {
// Social already exists, check if account_social relationship exists
const existing = (accountSocials || []).find(
Expand All @@ -47,10 +53,11 @@ export async function updateArtistSocials(
}
} else {
// Create new social record
const username = getUsernameFromProfileUrl(value);
const newSocials = await insertSocials([
{
username: getUsernameFromProfileUrl(value),
profile_url: value,
username,
profile_url: normalizedUrl,
},
]);
if (newSocials.length > 0) {
Expand Down
6 changes: 5 additions & 1 deletion lib/chat/toolChains/createNewArtistToolChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export const createNewArtistToolChain: ToolChainItem[] = [
system:
"From the get_spotify_search results, select the artist whose name best matches the user-provided artist name (prefer exact, case-insensitive match; otherwise choose the closest by name and popularity). Update the account using the update_account_info tool with the artist's basic information: name, image, label, etc.",
},
{ toolName: "update_artist_socials" },
{
toolName: "update_artist_socials",
system:
"Using the matched Spotify artist from the get_spotify_search results, update the artist's socials with the Spotify profile URL (found in external_urls.spotify). Pass the URL in the urls array to update_artist_socials.",
},
{ toolName: "artist_deep_research" },
{ toolName: "spotify_deep_research" },
{ toolName: "get_artist_socials" },
Expand Down
35 changes: 35 additions & 0 deletions lib/socials/__tests__/normalizeProfileUrl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, it, expect } from "vitest";
import { normalizeProfileUrl } from "../normalizeProfileUrl";

describe("normalizeProfileUrl", () => {
it("removes https:// protocol from URL", () => {
expect(normalizeProfileUrl("https://open.spotify.com/artist/123")).toBe(
"open.spotify.com/artist/123",
);
});

it("removes http:// protocol from URL", () => {
expect(normalizeProfileUrl("http://twitter.com/user")).toBe("twitter.com/user");
});

it("returns URL unchanged if no protocol", () => {
expect(normalizeProfileUrl("open.spotify.com/artist/123")).toBe(
"open.spotify.com/artist/123",
);
});

it("handles empty string", () => {
expect(normalizeProfileUrl("")).toBe("");
});

it("handles null/undefined", () => {
expect(normalizeProfileUrl(null as unknown as string)).toBe("");
expect(normalizeProfileUrl(undefined as unknown as string)).toBe("");
});

it("removes trailing slash", () => {
expect(normalizeProfileUrl("https://instagram.com/user/")).toBe(
"instagram.com/user",
);
});
});
14 changes: 14 additions & 0 deletions lib/socials/normalizeProfileUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Normalizes a profile URL by removing the protocol and trailing slash.
* This ensures consistent URL format for database queries and storage.
*
* @param url - The profile URL to normalize
* @returns The normalized URL without protocol or trailing slash
*/
export function normalizeProfileUrl(url: string | null | undefined): string {
if (!url) return "";

return url
.replace(/^https?:\/\//, "")
.replace(/\/$/, "");
}