feat: turbostarter boilerplate
Production-ready Next.js boilerplate with: - Runtime env validation (fail-fast on missing vars) - Feature-gated config (S3, Stripe, email, OAuth) - Docker + Coolify deployment pipeline - PostgreSQL + pgvector, MinIO S3, Better Auth - TypeScript strict mode (no ignoreBuildErrors) - i18n (en/es), AI modules, billing, monitoring Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
40
packages/api/src/modules/ai/tts.ts
Normal file
40
packages/api/src/modules/ai/tts.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Hono } from "hono";
|
||||
|
||||
import { Credits } from "@turbostarter/ai/credits/utils";
|
||||
import { getVoices, textToSpeech } from "@turbostarter/ai/tts/api";
|
||||
import { ttsSchema } from "@turbostarter/ai/tts/schema";
|
||||
|
||||
import { deductCredits, enforceAuth, rateLimiter, validate } from "../../middleware";
|
||||
|
||||
import type { User } from "@turbostarter/auth";
|
||||
|
||||
export const ttsRouter = new Hono<{
|
||||
Variables: {
|
||||
user: User;
|
||||
};
|
||||
}>()
|
||||
.post(
|
||||
"/",
|
||||
enforceAuth,
|
||||
rateLimiter,
|
||||
validate("json", ttsSchema),
|
||||
async (c) => {
|
||||
const input = c.req.valid("json");
|
||||
|
||||
// Deduct credits
|
||||
await deductCredits(Credits.COST.HIGH, "text-to-speech")(c, async () => { /* noop */ });
|
||||
|
||||
return new Response(
|
||||
(await textToSpeech(input)) as unknown as ConstructorParameters<
|
||||
typeof Response
|
||||
>[0],
|
||||
{
|
||||
headers: { "Content-Type": "audio/mpeg" },
|
||||
},
|
||||
);
|
||||
},
|
||||
)
|
||||
.get("/voices", enforceAuth, async (c) => {
|
||||
const voices = await getVoices();
|
||||
return c.json(voices);
|
||||
});
|
||||
Reference in New Issue
Block a user