mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): add Mux health check action (#542)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
78de97ec23
commit
1d6cc2b8c0
@@ -649,6 +649,8 @@ The site uses OAuth for authentication and Mux for video management. Required va
|
||||
| Variable | Purpose |
|
||||
| --- | --- |
|
||||
| `MUX_API_URL` | Override Mux API endpoint (defaults to `https://api.mux.com`) |
|
||||
| `MUX_TOKEN_ID` | Mux API token ID (for server-side health checks) |
|
||||
| `MUX_TOKEN_SECRET` | Mux API token secret (for server-side health checks) |
|
||||
| `SENTRY_AUTH_TOKEN` | Sentry error tracking auth token |
|
||||
|
||||
## Authentication & Mux Integration
|
||||
|
||||
@@ -22,7 +22,41 @@ function getMuxClient(token: string | undefined) {
|
||||
});
|
||||
}
|
||||
|
||||
function getHealthMuxClient() {
|
||||
const tokenId = process.env.MUX_TOKEN_ID || import.meta.env.MUX_TOKEN_ID;
|
||||
const tokenSecret = process.env.MUX_TOKEN_SECRET || import.meta.env.MUX_TOKEN_SECRET;
|
||||
|
||||
if (!tokenId || !tokenSecret) {
|
||||
throw new ActionError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: 'MUX_TOKEN_ID and MUX_TOKEN_SECRET must be set',
|
||||
});
|
||||
}
|
||||
|
||||
return new Mux({
|
||||
tokenId,
|
||||
tokenSecret,
|
||||
});
|
||||
}
|
||||
|
||||
export const mux = {
|
||||
/** Unauthenticated health check that verifies the Mux API proxy layer. */
|
||||
health: defineAction({
|
||||
handler: async () => {
|
||||
try {
|
||||
const muxClient = getHealthMuxClient();
|
||||
await muxClient.video.assets.list({ limit: 0 });
|
||||
return { ok: true };
|
||||
} catch (error) {
|
||||
if (error instanceof ActionError) throw error;
|
||||
|
||||
throw new ActionError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: error instanceof Error ? error.message : 'Mux health check failed',
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* List video assets with pagination
|
||||
*
|
||||
|
||||
@@ -22,6 +22,9 @@ function isGated(actionName: string | undefined) {
|
||||
// detect UNAUTHORIZED and show a login UI before uploading
|
||||
if (actionName === 'mux.createDirectUpload') return false;
|
||||
|
||||
// Health check uses server-side credentials, not user OAuth
|
||||
if (actionName === 'mux.health') return false;
|
||||
|
||||
// I don't love the magic string nature of this pattern but it's what is recommended in the docs
|
||||
return actionName.startsWith('mux');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { actions } from 'astro:actions';
|
||||
import type { APIRoute } from 'astro';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export const GET: APIRoute = async (context) => {
|
||||
const { data, error } = await context.callAction(actions.mux.health, {});
|
||||
|
||||
if (error) {
|
||||
return Response.json({ ok: false, error: error.message }, { status: 502 });
|
||||
}
|
||||
|
||||
return Response.json(data);
|
||||
};
|
||||
Reference in New Issue
Block a user