diff --git a/api/avatar.js b/api/avatar.js index e2b646ff..52fdba75 100644 --- a/api/avatar.js +++ b/api/avatar.js @@ -34,7 +34,7 @@ export function isAllowedAvatarUrl(rawUrl) { return ALLOWED_AVATAR_HOSTS.has(url.hostname.toLowerCase()); } -export default async function handler(req) { +export async function handler(req) { if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } @@ -76,3 +76,7 @@ export default async function handler(req) { return new Response('Avatar proxy error', { status: 502, headers: corsHeaders }); } } + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/deleteAccount.js b/api/deleteAccount.js index c4c7eac7..e5629220 100644 --- a/api/deleteAccount.js +++ b/api/deleteAccount.js @@ -6,7 +6,7 @@ const corsHeaders = { 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }; -export default async function handler(req) { +export async function handler(req) { if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } @@ -95,3 +95,7 @@ export default async function handler(req) { }); } } + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/download.js b/api/download.js index 5f3c388c..c2a0f407 100644 --- a/api/download.js +++ b/api/download.js @@ -97,7 +97,7 @@ const corsHeaders = { 'Access-Control-Allow-Headers': 'Content-Type', }; -export default async function handler(req) { +export async function handler(req) { if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } @@ -236,3 +236,7 @@ export default async function handler(req) { }); } } + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/downloadThumbnail.js b/api/downloadThumbnail.js index bef3ac41..45dd917f 100644 --- a/api/downloadThumbnail.js +++ b/api/downloadThumbnail.js @@ -24,7 +24,7 @@ function isAllowedThumbnailUrl(rawUrl) { return ALLOWED_THUMBNAIL_HOSTS.has(u.hostname.toLowerCase()); } -export default async function handler(req) { +export async function handler(req) { if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } @@ -89,4 +89,8 @@ export default async function handler(req) { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, }); } -} \ No newline at end of file +} + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/generateTitles.js b/api/generateTitles.js index 40506442..7a79cee3 100644 --- a/api/generateTitles.js +++ b/api/generateTitles.js @@ -39,7 +39,7 @@ async function generateTitlesWithOpenRouter(description, creativity) { return data.choices[0].message.content; } -export default async function handler(req) { +export async function handler(req) { // Handle OPTIONS preflight request if (req.method === 'OPTIONS') { return new Response(null, { @@ -132,4 +132,8 @@ export default async function handler(req) { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }); } -} \ No newline at end of file +} + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/info.js b/api/info.js index f07ca18b..65fc02d3 100644 --- a/api/info.js +++ b/api/info.js @@ -176,7 +176,7 @@ function setCachedInfo(url, data) { } } -export default async function handler(req) { +export async function handler(req) { if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } @@ -353,3 +353,7 @@ This is a common issue affecting all YouTube downloaders and is not specific to }); } } + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/looney-check.js b/api/looney-check.js index 9108aeb9..5bc6c007 100644 --- a/api/looney-check.js +++ b/api/looney-check.js @@ -244,7 +244,7 @@ export const config = { class ValidationError extends Error {} -export default async function handler(request) { +export async function handler(request) { if (request.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders(request) }); } @@ -318,3 +318,7 @@ export default async function handler(request) { return jsonResponse(request, { error: message }, status); } } + +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/api/uptime.js b/api/uptime.js index 348b08cf..ab4b79d7 100644 --- a/api/uptime.js +++ b/api/uptime.js @@ -154,4 +154,6 @@ export async function handler(request) { } } -export default handler; +// Vercel's Node.js runtime ignores a Response returned from a default-exported +// function, so expose the Web `fetch` handler it recognizes instead. +export default { fetch: handler }; diff --git a/server.js b/server.js index 49e341f6..3e5d3efe 100644 --- a/server.js +++ b/server.js @@ -2,13 +2,13 @@ import dotenv from 'dotenv'; import express from 'express'; import cors from 'cors'; import { Readable } from 'stream'; -import infoHandler from './api/info.js'; -import downloadHandler from './api/download.js'; -import downloadThumbnailHandler from './api/downloadThumbnail.js'; -import generateTitlesHandler from './api/generateTitles.js'; -import deleteAccountHandler from './api/deleteAccount.js'; -import avatarHandler from './api/avatar.js'; -import looneyCheckHandler from './api/looney-check.js'; +import { handler as infoHandler } from './api/info.js'; +import { handler as downloadHandler } from './api/download.js'; +import { handler as downloadThumbnailHandler } from './api/downloadThumbnail.js'; +import { handler as generateTitlesHandler } from './api/generateTitles.js'; +import { handler as deleteAccountHandler } from './api/deleteAccount.js'; +import { handler as avatarHandler } from './api/avatar.js'; +import { handler as looneyCheckHandler } from './api/looney-check.js'; import { handler as musicLinkHandler } from './api/music-link.js'; import { handler as trackHandler } from './api/track.js'; import { handler as statsHandler } from './api/stats.js';