SHARE UR REVIEW
GIT HUB
LIVE PACKAGES
✨ Features
- Shape-based filtering — Define what you want, auto-remove everything else
-
Sensitive field protection —
password,token,secretautomatically removed - Zero dependencies — Pure TypeScript, no external packages
- Universal — Works in Node.js, Browser, React Native
- TypeScript-first — Full type inference from shape definitions
- Blazing fast — Compiled schemas for production performance
- Never crashes — Graceful failure mode, production-safe
📦 Installation
npm install payload-guard
# or
yarn add payload-guard
# or
pnpm add payload-guard
🚀 Quick Start
Basic Usage
import { guard } from 'payload-guard';
// Define a shape
const userShape = guard.shape({
id: 'number',
name: 'string',
email: 'string',
});
// Filter data
const rawData = {
id: 1,
name: 'John Doe',
email: 'john@example.com',
password: 'secret123', // ❌ Will be removed
internalNotes: 'VIP user', // ❌ Will be removed
};
const safeData = userShape(rawData);
// Result: { id: 1, name: 'John Doe', email: 'john@example.com' }
Express Middleware
import express from 'express';
import { guard, guardMiddleware } from 'payload-guard';
const app = express();
app.use(express.json());
// Apply middleware
app.use(guardMiddleware({
sanitizeBody: true,
sensitiveFields: ['password', 'token'],
devMode: process.env.NODE_ENV === 'development',
}));
const userShape = guard.shape({
id: 'number',
name: 'string',
email: 'string',
});
app.post('/users', (req, res) => {
const user = createUser(req.body);
res.guardJson(userShape, user); // ✅ Filtered response
});
app.listen(3000);
Frontend Usage
import { validateShape } from 'payload-guard/client';
const userShape = { id: 'number', name: 'string', email: 'string' };
const validateUser = validateShape(userShape, { devMode: true });
// Fetch and validate
const user = await fetch('/api/user')
.then(r => r.json())
.then(validateUser);
// Dev mode warnings:
// ⚠️ Unexpected field "createdAt" in response
// ⚠️ Missing field "email" in response
📖 API Reference
guard.shape(descriptor, options?)
Create a filter function from a shape descriptor.
const userShape = guard.shape({
id: 'number',
name: 'string',
email: 'string',
role: { type: 'string', default: 'user' },
});
Supported types:
-
'string'— String values (auto-trimmed) -
'number'— Numeric values -
'boolean'— Boolean values -
'any'— Any value (no transformation)
Field config options:
{
type: 'string',
required: false, // Optional field
default: 'value', // Default value if missing
}
guard.array(itemShape)
Create an array filter.
const postsShape = guard.shape({
posts: guard.array({
id: 'number',
title: 'string',
}),
});
guardMiddleware(options)
Express middleware for automatic sanitization.
app.use(guardMiddleware({
sanitizeBody: true, // Filter req.body
requestShape: userShape, // Shape for request body
filterResponse: true, // Auto-filter all res.json()
sensitiveFields: [], // Extra sensitive field names
devMode: false, // Enable dev warnings
}));
res.guardJson(shape, data)
Added by middleware — send filtered JSON response.
app.get('/user', (req, res) => {
res.guardJson(userShape, userData);
});
validateShape(shape, options?) (Client)
Create a validator for frontend use.
import { validateShape } from 'payload-guard/client';
const validate = validateShape(userShape, {
devMode: true, // Log warnings
strict: false, // Throw on errors
});
🔒 Security
Default Sensitive Fields
These fields are automatically removed from all outputs:
-
password,password_hash,password_reset_token,pwd -
token,access_token,refresh_token,auth_token -
secret,api_key,private_key,encryption_key -
authorization,auth,session_id -
ssn,credit_card,cvv,card_number
Add Custom Sensitive Fields
guard.config({
sensitiveFields: ['internal_id', 'admin_notes', 'salary'],
});
🏗️ Nested Objects & Arrays
const postShape = guard.shape({
id: 'number',
title: 'string',
author: guard.shape({
id: 'number',
name: 'string',
// author.password, author.token auto-removed!
}),
tags: guard.array({
id: 'number',
name: 'string',
}),
comments: guard.array(
guard.shape({
id: 'number',
text: 'string',
user: guard.shape({
id: 'number',
name: 'string',
}),
})
),
});
⚡ Performance
| Operation | payload-guard | Zod | JOI |
|---|---|---|---|
| Simple filter | 0.05ms | 0.8ms | 1.2ms |
| Nested (3 levels) | 0.15ms | 2.5ms | 3.8ms |
| Array (100 items) | 1.2ms | 15ms | 22ms |
| Bundle size | <8KB | 50KB+ | 70KB+ |
| Dependencies | 0 | 5+ | 10+ |
🏢 Enterprise Features
These features are designed for high-throughput, production systems where bandwidth, predictability and observability matter.
- Payload Metrics (payload reduction): enable measurements to show before/after sizes and percentage saved. This makes cost and bandwidth impact visible to engineers.
// enable metrics globally
import { guard } from 'payload-guard';
guard.config({
payloadMetrics: true,
logger: (msg, level = 'info') => console.log(`[payload-guard:${level}]`, msg),
});
When enabled middleware or res.guardJson() will log reductions such as:
payload reduced: 18KB → 4KB (78%)
- Strict Mode: in strict mode the filter will throw on invalid or missing required fields instead of silently ignoring them. Use when you want validation failures to fail-fast in production.
// per-shape strict mode
const userStrict = guard.shape({ id: 'number', email: 'string' }, { strict: true });
// or global
guard.config({ strict: true });
- Compile Mode: pre-compile shapes once and reuse the compiled function for maximum throughput. This avoids repeated runtime parsing and makes performance predictable.
// compile once at startup
const compiledUser = guard.compile({ id: 'number', name: 'string' });
// then use per-request
app.get('/user/:id', (req, res) => {
const raw = getUserFromDb();
res.json(compiledUser(raw));
});
- Ignore Routes: skip middleware processing for low-value routes (health checks, metrics, webhooks) to avoid adding overhead.
app.use(guardMiddleware({ ignoreRoutes: ['/health', '/metrics', '/webhook'] }));
-
Middleware non-blocking guarantee: the middleware is defensive — any internal error, oversized payload, or stream-like body will be skipped and the response path will continue unblocked. Use
loggerordevModeto surface warnings.
🛠️ CLI
npx payload-guard init
Creates example files in your project:
-
shapes.ts— Example shape definitions -
server-example.ts— Express middleware setup
📄 License
MIT
Made with ❤️ for safer APIs
Top comments (0)