Skip to content
Open
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
13 changes: 5 additions & 8 deletions src/artists/getBatchArtistSocials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@ import { getArtistSocials } from "../recoup/getArtistSocials";
/**
* Fetches socials for all artists in parallel.
* Returns a Map of artistId -> socials array.
*
* @param artistIds
*/
export async function getBatchArtistSocials(
artistIds: string[]
artistIds: string[],
): Promise<Map<string, Awaited<ReturnType<typeof getArtistSocials>>>> {
logger.log("Fetching socials for all artists", {
totalArtists: artistIds.length,
});

const socialsResponses = await Promise.all(
artistIds.map((artistId) => getArtistSocials(artistId))
);
const socialsResponses = await Promise.all(artistIds.map(artistId => getArtistSocials(artistId)));

// Store socials in map
const artistSocialsMap = new Map<
string,
Awaited<ReturnType<typeof getArtistSocials>>
>();
const artistSocialsMap = new Map<string, Awaited<ReturnType<typeof getArtistSocials>>>();

for (let i = 0; i < artistIds.length; i++) {
artistSocialsMap.set(artistIds[i], socialsResponses[i]);
Expand Down
4 changes: 3 additions & 1 deletion src/artists/isScrapableSocial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import type { ArtistSocialProfile } from "../recoup/getArtistSocials";
*
* Non-scrapable platforms:
* - open.spotify.com
*
* @param social
*/
export function isScrapableSocial(social: ArtistSocialProfile): boolean {
const profileUrl = social.profile_url.toLowerCase();
Expand Down Expand Up @@ -39,5 +41,5 @@ export function isScrapableSocial(social: ArtistSocialProfile): boolean {
"youtube.com",
];

return scrapableDomains.some((domain) => profileUrl.includes(domain));
return scrapableDomains.some(domain => profileUrl.includes(domain));
}
4 changes: 1 addition & 3 deletions src/chats/getTaskRoomId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ type GetTaskRoomIdParams = {
* @param params - Parameters containing optional roomId and artistId
* @returns The room ID, or undefined if creation fails
*/
export async function getTaskRoomId(
params: GetTaskRoomIdParams
): Promise<string | undefined> {
export async function getTaskRoomId(params: GetTaskRoomIdParams): Promise<string | undefined> {
if (params.roomId) {
logger.log("Using existing roomId", { roomId: params.roomId });
return params.roomId;
Expand Down
2 changes: 1 addition & 1 deletion src/consts.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const NEW_API_BASE_URL = "https://recoup-api.vercel.app";
export const RECOUP_API_KEY = process.env.RECOUP_API_KEY;
export const RECOUP_API_KEY = process.env.RECOUP_API_KEY;
11 changes: 3 additions & 8 deletions src/github/__tests__/createOrgGithubRepo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ describe("createOrgGithubRepo", () => {

const result = await createOrgGithubRepo("Test Org", "uuid-123");

expect(result).toBe(
"https://github.com/Recoupable-Com/org-test-org-uuid-123"
);
expect(result).toBe("https://github.com/Recoupable-Com/org-test-org-uuid-123");
expect(mockFetch).toHaveBeenCalledOnce();

// Verify the request body has the right repo name and auto_init
Expand Down Expand Up @@ -57,9 +55,7 @@ describe("createOrgGithubRepo", () => {

const result = await createOrgGithubRepo("My Org", "uuid-456");

expect(result).toBe(
"https://github.com/Recoupable-Com/org-my-org-uuid-456"
);
expect(result).toBe("https://github.com/Recoupable-Com/org-my-org-uuid-456");
expect(mockFetch).toHaveBeenCalledTimes(2);
});

Expand Down Expand Up @@ -104,8 +100,7 @@ describe("createOrgGithubRepo", () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => ({
html_url:
"https://github.com/Recoupable-Com/org-my-cool-org-uuid-111",
html_url: "https://github.com/Recoupable-Com/org-my-cool-org-uuid-111",
}),
});

Expand Down
29 changes: 13 additions & 16 deletions src/github/createGithubRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const GITHUB_ORG = "recoupable";
*/
export async function createGithubRepo(
accountName: string,
accountId: string
accountId: string,
): Promise<string | undefined> {
const token = process.env.GITHUB_TOKEN;

Expand All @@ -32,21 +32,18 @@ export async function createGithubRepo(
});

try {
const response = await fetch(
`https://api.github.com/orgs/${GITHUB_ORG}/repos`,
{
method: "POST",
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
body: JSON.stringify({
name: repoName,
private: true,
}),
}
);
const response = await fetch(`https://api.github.com/orgs/${GITHUB_ORG}/repos`, {
method: "POST",
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
body: JSON.stringify({
name: repoName,
private: true,
}),
});

if (!response.ok) {
// 422 means repo already exists — fetch existing URL
Expand Down
31 changes: 14 additions & 17 deletions src/github/createOrgGithubRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const GITHUB_ORG = "recoupable";
*/
export async function createOrgGithubRepo(
orgName: string,
orgId: string
orgId: string,
): Promise<string | undefined> {
const token = process.env.GITHUB_TOKEN;

Expand All @@ -35,22 +35,19 @@ export async function createOrgGithubRepo(
});

try {
const response = await fetch(
`https://api.github.com/orgs/${GITHUB_ORG}/repos`,
{
method: "POST",
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
body: JSON.stringify({
name: repoName,
private: true,
auto_init: true,
}),
}
);
const response = await fetch(`https://api.github.com/orgs/${GITHUB_ORG}/repos`, {
method: "POST",
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
body: JSON.stringify({
name: repoName,
private: true,
auto_init: true,
}),
});

if (!response.ok) {
// 422 means repo already exists — fetch existing URL
Expand Down
21 changes: 8 additions & 13 deletions src/github/getExistingGithubRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ const GITHUB_ORG = "recoupable";
* @param repoName - The full repository name (e.g. "account-name-uuid")
* @returns The repository HTML URL, or undefined if not found or on error
*/
export async function getExistingGithubRepo(
repoName: string
): Promise<string | undefined> {
export async function getExistingGithubRepo(repoName: string): Promise<string | undefined> {
const token = process.env.GITHUB_TOKEN;

if (!token) {
Expand All @@ -24,16 +22,13 @@ export async function getExistingGithubRepo(
});

try {
const response = await fetch(
`https://api.github.com/repos/${GITHUB_ORG}/${repoName}`,
{
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
}
);
const response = await fetch(`https://api.github.com/repos/${GITHUB_ORG}/${repoName}`, {
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
});

if (!response.ok) {
logger.error("Failed to fetch existing GitHub repo", {
Expand Down
12 changes: 5 additions & 7 deletions src/polling/pollScraperResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@ export type PollResult = ScrapeRun & {
/**
* Polls each scraper run in parallel until all are completed (SUCCEEDED or FAILED).
* Returns an array of results for each run.
*
* @param runs
*/
export async function pollScraperResults(
runs: ScrapeRun[]
): Promise<PollResult[]> {
export async function pollScraperResults(runs: ScrapeRun[]): Promise<PollResult[]> {
const results: PollResult[] = [];
const pendingRuns = new Map<string, ScrapeRun>(
runs.map((run) => [run.runId, run])
);
const pendingRuns = new Map<string, ScrapeRun>(runs.map(run => [run.runId, run]));

while (pendingRuns.size > 0) {
// Poll all pending runs in parallel
const pollPromises = Array.from(pendingRuns.values()).map(async (run) => {
const pollPromises = Array.from(pendingRuns.values()).map(async run => {
const result = await getScraperResults(run.runId);

if (!result) {
Expand Down
6 changes: 3 additions & 3 deletions src/pulse/__tests__/executePulseInSandbox.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ describe("executePulseInSandbox", () => {
}));
const mod = await import("../executePulseInSandbox");

await expect(
mod.executePulseInSandbox({ accountId, prompt })
).rejects.toThrow("RECOUP_API_KEY not configured");
await expect(mod.executePulseInSandbox({ accountId, prompt })).rejects.toThrow(
"RECOUP_API_KEY not configured",
);

process.env.RECOUP_API_KEY = original;
});
Expand Down
3 changes: 3 additions & 0 deletions src/pulse/executePulseInSandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const executePulseResponseSchema = z.object({
*
* @param params.accountId - The account ID to execute the pulse for
* @param params.prompt - The pulse prompt to execute
* @param root0
* @param root0.accountId
* @param root0.prompt
* @returns The sandbox ID and run ID on success, undefined on error
*/
export async function executePulseInSandbox({
Expand Down
4 changes: 1 addition & 3 deletions src/recoup/__tests__/getAccountOrgs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ describe("getAccountOrgs", () => {
{ organizationId: "org-456", organizationName: "Another Org" },
]);
expect(mockFetch).toHaveBeenCalledOnce();
expect(mockFetch.mock.calls[0][0]).toContain(
"/api/organizations?account_id=account-1"
);
expect(mockFetch.mock.calls[0][0]).toContain("/api/organizations?account_id=account-1");
});

it("returns empty array when account has no orgs", async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/recoup/createAccountSandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const createSandboxResponseSchema = z.object({
* @returns The created sandbox ID, or undefined on error
*/
export async function createAccountSandbox(
accountId: string
accountId: string,
): Promise<{ sandboxId: string } | undefined> {
const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent(accountId)}`;

Expand Down
4 changes: 1 addition & 3 deletions src/recoup/createChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ type CreateChatResponse = {
* @param params - Chat creation parameters
* @returns Promise that resolves to the created chat, or undefined on error
*/
export async function createChat(
params?: CreateChatParams
): Promise<Room | undefined> {
export async function createChat(params?: CreateChatParams): Promise<Room | undefined> {
if (!RECOUP_API_KEY) {
logger.error("Missing RECOUP_API_KEY environment variable");
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/recoup/fetchActivePulses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function fetchActivePulses(): Promise<Pulse[]> {

logger.log("Fetched active pulses", {
count: pulses.length,
pulses: pulses.map((p) => ({
pulses: pulses.map(p => ({
id: p.id,
account_id: p.account_id,
active: p.active,
Expand Down
8 changes: 4 additions & 4 deletions src/recoup/fetchTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const taskResponseSchema = z.object({
artist_account_id: z.string(),
enabled: z.boolean().nullable(),
model: z.string().nullish(),
})
}),
),
});

Expand All @@ -27,10 +27,10 @@ const taskResponseSchema = z.object({
* - Task not found
* - Task is disabled
* - API error occurs
*
* @param externalId
*/
export async function fetchTask(
externalId?: string
): Promise<ChatConfig | undefined> {
export async function fetchTask(externalId?: string): Promise<ChatConfig | undefined> {
if (!externalId) {
logger.warn("No externalId provided, skipping task fetch");
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/recoup/generateChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ChatGenerateResponse = {
* @returns Promise that resolves to the parsed response, or undefined on error
*/
export async function generateChat(
params: ChatGenerateParams
params: ChatGenerateParams,
): Promise<ChatGenerateResponse | undefined> {
if (!RECOUP_API_KEY) {
logger.error("Missing RECOUP_API_KEY environment variable");
Expand Down
4 changes: 1 addition & 3 deletions src/recoup/getAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export interface AccountInfo {
* @param accountId - The account ID to look up
* @returns The account id and name, or undefined on error
*/
export async function getAccount(
accountId: string
): Promise<AccountInfo | undefined> {
export async function getAccount(accountId: string): Promise<AccountInfo | undefined> {
const url = `${NEW_API_BASE_URL}/api/accounts/${encodeURIComponent(accountId)}`;

logger.log("Fetching account info", { accountId, url });
Expand Down
8 changes: 3 additions & 5 deletions src/recoup/getAccountOrgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ export interface OrgInfo {
* @param accountId - The account ID to look up orgs for
* @returns Array of org id/name pairs, or undefined on error
*/
export async function getAccountOrgs(
accountId: string
): Promise<OrgInfo[] | undefined> {
export async function getAccountOrgs(accountId: string): Promise<OrgInfo[] | undefined> {
const url = `${NEW_API_BASE_URL}/api/organizations?account_id=${encodeURIComponent(accountId)}`;

logger.log("Fetching account organizations", { accountId, url });
Expand Down Expand Up @@ -59,8 +57,8 @@ export async function getAccountOrgs(
}

const orgs = validation.data.organizations
.filter((org) => org.organization_id && org.organization_name)
.map((org) => ({
.filter(org => org.organization_id && org.organization_name)
.map(org => ({
organizationId: org.organization_id,
organizationName: org.organization_name!,
}));
Expand Down
6 changes: 2 additions & 4 deletions src/recoup/getAccountSandboxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ export interface AccountSandboxesInfo {
* @returns The snapshot ID and github repo URL, or undefined on error
*/
export async function getAccountSandboxes(
accountId: string
accountId: string,
): Promise<AccountSandboxesInfo | undefined> {
const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent(
accountId
)}`;
const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent(accountId)}`;

logger.log("Fetching account sandboxes", { accountId, url });

Expand Down
Loading