Skip to content

Latest commit

 

History

History
171 lines (129 loc) · 3.98 KB

File metadata and controls

171 lines (129 loc) · 3.98 KB

JOOservices Node FormRequest

CI License: MIT

Laravel-inspired FormRequest validation for Node.js and TypeScript with Zod and an optional Express 4 adapter.

Package name: @jooservices/node-formrequest

Current release: 0.1.0.

Install

npm install @jooservices/node-formrequest zod

What It Is

  • A Laravel-inspired FormRequest lifecycle for Node.js and TypeScript.
  • Zod-powered: rules() returns a Zod schema and validation uses parseAsync.
  • Framework-neutral core with an optional Express 4-style adapter.
  • Class-based: create request classes by extending FormRequest.

What It Is Not

  • Not Laravel-compatible.
  • No Laravel string rules such as required|email|min:8.
  • No database validation rules.
  • No service container.
  • No business logic layer.
  • No Express 5 support unless explicitly tested in a future change.

Basic Usage

import { z } from 'zod';
import { FormRequest } from '@jooservices/node-formrequest';

export class CreateUserRequest extends FormRequest {
  rules() {
    return z.object({
      body: z.object({
        name: z.string().min(1).max(255),
        email: z.email(),
        password: z.string().min(8)
      }),
      params: z.object({}).optional(),
      query: z.object({}).optional()
    });
  }

  authorize() {
    return true;
  }
}

const request = new CreateUserRequest();
const validated = await request.validate({
  body: req.body,
  params: req.params,
  query: req.query,
  headers: req.headers,
  user: req.user
});

const body = validated.body;

Express 4 Adapter

import { validateFormRequest } from '@jooservices/node-formrequest';

router.post(
  '/users',
  validateFormRequest(CreateUserRequest),
  controller.store
);

On success, the adapter attaches:

  • req.validated
  • req.formRequest

On authorization or validation failure, it calls next(error) and does not call the downstream handler.

Error Handling

import {
  AuthorizationException,
  ValidationException
} from '@jooservices/node-formrequest';

try {
  await request.validate(context);
} catch (error) {
  if (error instanceof AuthorizationException) {
    // This action is unauthorized.
  }

  if (error instanceof ValidationException) {
    console.log(error.issues);
    console.log(error.flattened);
  }
}

Authorization

Override authorize() for synchronous or asynchronous authorization:

class UpdateUserRequest extends FormRequest {
  rules() {
    return z.object({
      params: z.object({ id: z.string() }),
      user: z.object({ id: z.string() })
    });
  }

  async authorize() {
    return this.params<{ id: string }>()?.id === this.user<{ id: string }>()?.id;
  }
}

Messages And Attributes

messages() and attributes() are metadata helpers in v0.1. Their values are included on ValidationException.

This is not full Laravel i18n or message interpolation.

TypeScript Notes

  • The core API is TypeScript-first.
  • FormRequest<TSchema> may be used with a concrete Zod schema for inferred validation results.
  • The core package does not import Express types.
  • Zod v4 is the tested validation engine for this package.

Public API

  • FormRequest
  • FormRequestContext
  • FormRequestConstructor
  • validateFormRequest
  • FormRequestException
  • AuthorizationException
  • ValidationException

Development

npm run lint
npm run typecheck
npm run test:coverage
npm run build
npm pack --dry-run

Git And Release Flow

  • Feature work branches from develop and opens PRs back into develop.
  • Release branches such as release/0.1.0 are cut from develop.
  • Version bumps happen in release branches, not in feature branches.
  • Release PRs target master.
  • Tags are created from master.
  • master is merged back into develop after release completion.