Symptom
-------
The upload action rejected anything over 50 MB with a flat
"File too large (>50MB)" — a number that was both too generous for
images (WA caps at 5 MB) and too restrictive for documents (WA
allows 100 MB). And anything over 1 MB was being rejected even
earlier by Next's default Server Action body limit, with a much
less actionable error.
Fix
---
1. New `lib/whatsapp-media.ts` resolves an uploaded file's MIME type
to a WhatsApp delivery kind and validates it against the
per-kind cap that WA actually enforces:
image → 5 MB image/* except sticker-mode
video → 16 MB video/*
audio → 16 MB audio/*
document → 100 MB anything else (PDFs, office docs, …)
Anything not recognised as image/video/audio falls through to
"document", which is also the Baileys sender path the bot uses
to deliver it. So a .zip or .csv ends up correctly classified
AND correctly limited to the document cap.
Error messages now name the kind and show both the actual size
and the cap: "Image too large (5.2 MB > 5.0 MB limit on
WhatsApp)".
2. `next.config.ts` lifts the Server Action body limit from the 1 MB
default to 100 MB, so document uploads actually reach the action
instead of getting bounced at the framework boundary. The WA
per-kind validator inside the action enforces the real limit
from there.
3. The compose-step upload zone hint now reflects the per-kind caps
("Image up to 5 MB · video / audio up to 16 MB · document up to
100 MB") instead of the wrong flat "up to 50 MB" value.
Tests (17 new cases, total 189)
-------------------------------
- classifyMediaKind: image/video/audio prefix routing, fall-through
to document for unknown / empty / octet-stream / text/plain.
- validateForWhatsApp: at-cap, just-under-cap, just-over-cap for
image (5 MB) / video (16 MB) / audio (16 MB) / document (100 MB);
zero-byte rejected; unknown-mime 60 MB upload accepted as document.
- WA_MAX_BYTES sanity: equals the document cap and is >= every other
per-kind limit (so it's safe to use as the framework body cap).
- formatBytes: bytes / KB (no decimals) / MB (one decimal) rendering.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
import type { NextConfig } from "next";
|
|
import { join } from "node:path";
|
|
|
|
// Pin Turbopack's workspace root explicitly — pnpm + Turbopack can't always
|
|
// infer it inside Docker bind mounts.
|
|
const workspaceRoot = join(import.meta.dirname, "..", "..");
|
|
|
|
// We consume @cmbot/db and @cmbot/shared via their compiled dist (their
|
|
// package.json `main` points at ./dist/index.js). The dist is built at
|
|
// container start (see docker-compose.dev.yml) and during the production
|
|
// Docker build (see docker/web.Dockerfile). This sidesteps Turbopack's
|
|
// inability to resolve NodeNext-style `.js` extensions to `.ts` source.
|
|
const nextConfig: NextConfig = {
|
|
reactStrictMode: true,
|
|
output: "standalone",
|
|
outputFileTracingRoot: workspaceRoot,
|
|
// Allow Server Actions and dev HMR from the LAN host (phone testing).
|
|
// Tighten before exposing publicly via the reverse proxy.
|
|
allowedDevOrigins: ["192.168.0.253", "test.04080616.xyz", "rexwa.04080616.xyz"],
|
|
experimental: {
|
|
typedRoutes: true,
|
|
serverActions: {
|
|
// Default Server Action body limit is 1 MB — way under WhatsApp's
|
|
// 100 MB document cap. Lifted to 100 MB so document uploads reach
|
|
// the action; the per-kind WhatsApp validator
|
|
// (lib/whatsapp-media.ts) then enforces the actual limit
|
|
// (5 MB image / 16 MB video/audio / 100 MB document) and returns
|
|
// a useful error for the rest.
|
|
bodySizeLimit: "100mb",
|
|
},
|
|
},
|
|
turbopack: {
|
|
root: workspaceRoot,
|
|
},
|
|
};
|
|
|
|
export default nextConfig;
|