ITADN

Add optional Zod/Standard Schema support for runtime validation

#3802OpenOskarLebuda 创建于 2025-11-19
type:feature
O
OskarLebudacommented
**Description** <!-- *(Brief description of the feature)* --> Hi! 👋 First of all - thank you for this package. It makes working with the GitLab API much easier and the developer experience is great. After using Gitbeaker in a few projects, I noticed that the current API responses map very cleanly to [Zod](https://zod.dev/) or [Standard Schema](https://standardschema.dev/). Gitbeaker already has solid TypeScript definitions, so there's a good foundation to generate proper runtime validation schemas on top of them. This could open the door to safer integrations - especially in environments where API responses need to be validated, transformed, or exposed through other internal services. Right now developers need to maintain their own schemas manually. Adding optional built-in schemas (or a generator) would make this much simpler and reduce duplication. --- **Proposal** <!-- *(Outline how you plan to implement this feature if you have one)* --> Introduce a way to use Gitbeaker with Zod or Standard Schema: * Provide Zod schemas generated from existing TypeScript types (either directly bundled or generated through a small build step). * Expose them as a separate optional module, e.g. `@gitbeaker/zod` or `gitbeaker/schemas`. * Keep it fully optional so core users aren't affected - but allow developers who rely on runtime validation to plug schemas in easily. * Ensure schemas stay in sync with the official GitLab API types. Ideally the generation would run automatically during releases. * If full coverage is too large for the first iteration, start with core resources (Projects, Users, Issues, Merge Requests) and expand over time. * And if it helps - I'm happy to contribute and assist with the implementation. --- **Example use cases** ### 1. Basic API response validation ```typescript import { Gitlab } from '@gitbeaker/rest'; import { zProjectSchema, zUserSchema } from '@gitbeaker/zod'; const api = new Gitlab({ token: 'xxx' }); // Validate single project const rawProject = await api.Projects.show(123); const project = zProjectSchema.parse(rawProject); // ✅ Guaranteed type safety + runtime validation // Validate list of users const rawUsers = await api.Users.all(); const users = zUserSchema.array().parse(rawUsers); ``` ### 2. Webhook validation in API endpoints ```typescript import { zWebhookPushEventSchema, zWebhookMergeRequestEventSchema } from '@gitbeaker/zod'; import { z } from 'zod'; // Express/Next.js endpoint app.post('/webhook/gitlab', async (req, res) => { const eventType = req.headers['x-gitlab-event']; try { if (eventType === 'Push Hook') { const event = zWebhookPushEventSchema.parse(req.body); await handlePushEvent(event); } else if (eventType === 'Merge Request Hook') { const event = zWebhookMergeRequestEventSchema.parse(req.body); await handleMergeRequest(event); } res.status(200).send('OK'); } catch (error) { if (error instanceof z.ZodError) { console.error('Invalid webhook payload:', error.errors); res.status(400).json({ error: 'Invalid payload' }); } } }); ``` ### 3. Safe transformations to internal models ```typescript import { zMergeRequestSchema } from '@gitbeaker/zod'; // Transform to internal model with validation const InternalMRSchema = zMergeRequestSchema.transform((mr) => ({ id: mr.id, title: mr.title, author: mr.author.username, status: mr.state === 'merged' ? 'completed' : 'pending', createdAt: new Date(mr.created_at), })); const mrs = await api.MergeRequests.all({ projectId: 123 }); const internalMRs = mrs.map(mr => InternalMRSchema.parse(mr)); ``` ### 4. Integration with tRPC or other type-safe frameworks ```typescript import { zProjectSchema } from '@gitbeaker/zod'; import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); export const appRouter = t.router({ getProject: t.procedure .input(z.object({ id: z.number() })) .output(zProjectSchema) .query(async ({ input }) => { const project = await api.Projects.show(input.id); return zProjectSchema.parse(project); }), }); ``` --- **Checklist** * [x] I have checked that this is not a duplicate issue. * [x] I have read the documentation.
0 条评论