UNPKG

nuxt-apex

Version:

Auto-generates fully typed useFetch composables for Nuxt 3/4 server endpoints with Zod validation and zero boilerplate

49 lines (48 loc) 1.65 kB
import { isError, createError, defineEventHandler, readBody, getRouterParams, getQuery } from "h3"; import { z } from "zod"; import { useEvent } from "nitropack/runtime"; export function defineApexHandler(handler, validator) { return defineEventHandler(async (event) => { let shape; let parsed; try { const raw = await useData(); if (validator) { shape = typeof validator === "function" ? validator(z, raw) : validator; const schema = shape ? z.object(validator) : null; const parsed2 = schema?.safeParse(raw); if (!parsed2?.success) { throw createError({ statusCode: 422, message: JSON.stringify(parsed2?.error.flatten().fieldErrors) }); } } return await handler(parsed?.data || raw, event); } catch (error) { console.error(error); if (isError(error)) throw error; throw createError({ message: error.message, statusCode: error.statusCode || 500 }); } }); } export async function useData() { const e = useEvent(); const hasBody = ["POST", "PUT", "PATCH"].includes(e.method.toUpperCase()); const bodyInfo = hasBody ? await readBody(e) ?? {} : {}; const paramsInfo = getRouterParams(e) ?? {}; const queryInfo = getQuery(e) ?? {}; return mergeSources(bodyInfo, paramsInfo, queryInfo); } function mergeSources(...sources) { const result = {}; for (const src of sources) { for (const key of Object.keys(src)) { if (key in result) { throw createError({ statusCode: 500, message: `Duplicate key "${key}"` }); } result[key] = src[key]; } } return result; }