payload-guard-filter 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +14 -304
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # payload-guard
2
+
2
3
  > Part of the [Professional Node.js Backend Toolkit](https://github.com/sannuk79/PROJECTS-AND-NPM-PACKAGES-)
4
+
3
5
  <p align="center">
4
6
  <strong>🛡️ Lightweight, zero-dependency shape-based payload filtering and sanitization</strong>
5
7
  </p>
6
8
 
7
-
8
9
  <p align="center">
9
10
  <img src="https://img.shields.io/badge/bundle%20size-%3C8KB-brightgreen" alt="Bundle Size">
10
11
  <img src="https://img.shields.io/badge/dependencies-0-blue" alt="Zero Dependencies">
@@ -45,10 +46,6 @@ graph LR
45
46
 
46
47
  ```bash
47
48
  npm install payload-guard
48
- # or
49
- yarn add payload-guard
50
- # or
51
- pnpm add payload-guard
52
49
  ```
53
50
 
54
51
  ---
@@ -80,318 +77,31 @@ const safeData = userShape(rawData);
80
77
  // Result: { id: 1, name: 'John Doe', email: 'john@example.com' }
81
78
  ```
82
79
 
83
- ### Express Middleware
84
-
85
- ```typescript
86
- import express from 'express';
87
- import { guard, guardMiddleware } from 'payload-guard';
88
-
89
- const app = express();
90
- app.use(express.json());
91
-
92
- // Apply middleware
93
- app.use(guardMiddleware({
94
- sanitizeBody: true,
95
- sensitiveFields: ['password', 'token'],
96
- devMode: process.env.NODE_ENV === 'development',
97
- }));
98
-
99
- const userShape = guard.shape({
100
- id: 'number',
101
- name: 'string',
102
- email: 'string',
103
- });
104
-
105
- app.post('/users', (req, res) => {
106
- const user = createUser(req.body);
107
- res.guardJson(userShape, user); // ✅ Filtered response
108
- });
109
-
110
- app.listen(3000);
111
- ```
112
-
113
- ### Frontend Usage
114
-
115
- ```typescript
116
- import { validateShape } from 'payload-guard/client';
117
-
118
- const userShape = { id: 'number', name: 'string', email: 'string' };
119
- const validateUser = validateShape(userShape, { devMode: true });
120
-
121
- // Fetch and validate
122
- const user = await fetch('/api/user')
123
- .then(r => r.json())
124
- .then(validateUser);
125
-
126
- // Dev mode warnings:
127
- // ⚠️ Unexpected field "createdAt" in response
128
- // ⚠️ Missing field "email" in response
129
- ```
130
-
131
- ---
132
-
133
- ## 📖 API Reference
134
-
135
- ### `guard.shape(descriptor, options?)`
136
-
137
- Create a filter function from a shape descriptor.
138
-
139
- ```typescript
140
- const userShape = guard.shape({
141
- id: 'number',
142
- name: 'string',
143
- email: 'string',
144
- role: { type: 'string', default: 'user' },
145
- });
146
- ```
147
-
148
- **Supported types:**
149
- - `'string'` — String values (auto-trimmed)
150
- - `'number'` — Numeric values
151
- - `'boolean'` — Boolean values
152
- - `'any'` — Any value (no transformation)
153
-
154
- **Field config options:**
155
- ```typescript
156
- {
157
- type: 'string',
158
- required: false, // Optional field
159
- default: 'value', // Default value if missing
160
- }
161
- ```
162
-
163
- ### `guard.array(itemShape)`
164
-
165
- Create an array filter.
166
-
167
- ```typescript
168
- const postsShape = guard.shape({
169
- posts: guard.array({
170
- id: 'number',
171
- title: 'string',
172
- }),
173
- });
174
- ```
175
-
176
- ### `guardMiddleware(options)`
177
-
178
- Express middleware for automatic sanitization.
179
-
180
- ```typescript
181
- app.use(guardMiddleware({
182
- sanitizeBody: true, // Filter req.body
183
- requestShape: userShape, // Shape for request body
184
- filterResponse: true, // Auto-filter all res.json()
185
- sensitiveFields: [], // Extra sensitive field names
186
- devMode: false, // Enable dev warnings
187
- }));
188
- ```
189
-
190
- ### `res.guardJson(shape, data)`
191
-
192
- Added by middleware — send filtered JSON response.
193
-
194
- ```typescript
195
- app.get('/user', (req, res) => {
196
- res.guardJson(userShape, userData);
197
- });
198
- ```
199
-
200
- ### `validateShape(shape, options?)` (Client)
201
-
202
- Create a validator for frontend use.
203
-
204
- ```typescript
205
- import { validateShape } from 'payload-guard/client';
206
-
207
- const validate = validateShape(userShape, {
208
- devMode: true, // Log warnings
209
- strict: false, // Throw on errors
210
- });
211
- ```
212
-
213
- ---
214
-
215
- ## 🔒 Security
216
-
217
- ### Default Sensitive Fields
218
-
219
- These fields are **automatically removed** from all outputs:
220
-
221
- - `password`, `password_hash`, `password_reset_token`, `pwd`
222
- - `token`, `access_token`, `refresh_token`, `auth_token`
223
- - `secret`, `api_key`, `private_key`, `encryption_key`
224
- - `authorization`, `auth`, `session_id`
225
- - `ssn`, `credit_card`, `cvv`, `card_number`
226
-
227
- ### Add Custom Sensitive Fields
228
-
229
- ```typescript
230
- guard.config({
231
- sensitiveFields: ['internal_id', 'admin_notes', 'salary'],
232
- });
233
- ```
234
-
235
- ---
236
-
237
- ## 🏗️ Nested Objects & Arrays
238
-
239
- ```typescript
240
- const postShape = guard.shape({
241
- id: 'number',
242
- title: 'string',
243
- author: guard.shape({
244
- id: 'number',
245
- name: 'string',
246
- // author.password, author.token auto-removed!
247
- }),
248
- tags: guard.array({
249
- id: 'number',
250
- name: 'string',
251
- }),
252
- comments: guard.array(
253
- guard.shape({
254
- id: 'number',
255
- text: 'string',
256
- user: guard.shape({
257
- id: 'number',
258
- name: 'string',
259
- }),
260
- })
261
- ),
262
- });
263
- ```
264
-
265
80
  ---
266
81
 
267
82
  ## ⚡ Performance
268
83
 
269
- | Operation | payload-guard | Zod | JOI |
270
- |-----------|---------------|-----|-----|
271
- | Simple filter | 0.05ms | 0.8ms | 1.2ms |
272
- | Nested (3 levels) | 0.15ms | 2.5ms | 3.8ms |
273
- | Array (100 items) | 1.2ms | 15ms | 22ms |
274
- | Bundle size | <8KB | 50KB+ | 70KB+ |
275
- | Dependencies | 0 | 5+ | 10+ |
276
-
277
- ---
278
-
279
- ## 🏢 Enterprise Features (v1.2.0+)
280
-
281
- Designed for high-performance production systems, Payload Guard includes enterprise-grade features for security, observability, and performance.
282
-
283
- ### 🛡️ 1. Header Sanitization
284
- Automatically remove sensitive headers like `Authorization` or `Cookie` before your business logic handles the request.
285
- ```ts
286
- app.use(guardMiddleware({
287
- sanitizeHeaders: true,
288
- sensitiveHeaders: ['x-api-key', 'session-id'] // optional extras
289
- }));
290
- ```
291
-
292
- ### 🧠 2. Memory Safety (`maxArrayLength`)
293
- Prevent DoS attacks via extremely large arrays by automatically truncating them to a safe limit.
294
- ```ts
295
- const shape = guard.shape({ items: guard.array('string') }, { maxArrayLength: 1000 });
296
- ```
297
-
298
- ### ⚡ 3. Async Safety (`maxPayloadSize`)
299
- Avoid processing massive JSON payloads that could block the event loop.
300
- ```ts
301
- app.use(guardMiddleware({
302
- maxPayloadSize: 1024 * 512, // 512KB
303
- skipLargePayload: true // Skips filtering if too large
304
- }));
305
- ```
306
-
307
- ### ⏱️ 4. Middleware Timing Stats
308
- Track exactly how much time Payload Guard adds to your request cycle.
309
- ```
310
- [payload-guard] [POST] /api/data: reduced 15KB -> 4KB (73%) in 0.12ms
311
- ```
312
-
313
- ### 📊 5. Human-Readable Metrics
314
- Visibility into bandwidth savings with formatted byte sizes and percentages.
315
-
316
- ### 🛠️ 6. CLI Type Sync
317
- Generate frontend TypeScript types from your backend shapes with one command.
318
- ```bash
319
- npx payload-guard sync
320
- ```
321
-
322
- ### ⚠️ 7. Route-Aware Dev Warnings
323
- Dev mode warnings now include the full method, path, and nested field locations (e.g., `user.profile.password`) for faster debugging.
324
-
325
- ### 🛣️ 8. Ignore Routes
326
- Skip processing for high-volume or incompatible routes like file uploads or health checks.
327
- ```ts
328
- app.use(guardMiddleware({ ignoreRoutes: ['/health', '/upload'] }));
329
- ```
330
-
331
- ### 🏗️ 9. Shared Schemas & Examples
332
- Built-in support for reusable schemas across your monorepo and a `examples/real-world` project for reference.
333
-
334
- ### 🚀 10. Performance Benchmarks
335
- A dedicated benchmark suite to verify sub-millisecond overhead. `npm run benchmark`.
336
-
337
- ---
338
-
339
- ## 🏗️ Production Hardening
340
-
341
- ### 🛡️ Fail-Safe Mode (`failOpen`)
342
- In production, we prioritize availability. If filtering fails for any reason, `failOpen: true` (default) ensures the original data is sent instead of breaking the request.
343
-
344
- ### 🚫 Non-Serializable Protection
345
- Payload Guard automatically detects and skips `Buffer`, `Stream`, `File`, and `Blob` objects to prevent crashes and performance bottlenecks.
84
+ | Benchmark | ops/sec | avg (ms) |
85
+ |-----------|---------|----------|
86
+ | **Small payload** (5 fields) | 449,365 | **0.0022ms** |
87
+ | **Medium payload** (50 posts) | 7,791 | **0.1284ms** |
88
+ | **Large payload** (1000 users) | 246 | **4.0724ms** |
346
89
 
347
- ### 🔍 Detailed Debug Logs
348
- Enable `logRemovedFields: true` to see exactly which fields were stripped from your payloads:
349
- `[payload-guard] /api/user Removed fields: password, token, internal_id`
90
+ > **Memory Usage**: ~121 MB Heap Used (Stable)
350
91
 
351
92
  ---
352
93
 
353
- ## 🌐 Multi-Framework Support
94
+ ## 🛡️ Fail-Safe Design
354
95
 
355
- The core is zero-dependency and framework-agnostic. Use it anywhere:
356
-
357
- ### Hono / Cloudflare Workers
358
- ```ts
359
- app.post('/user', async (c) => {
360
- const body = await c.req.json();
361
- return c.json(userShape(body));
362
- });
363
- ```
364
-
365
- ### Fastify
366
- ```ts
367
- fastify.post('/user', (req, reply) => {
368
- reply.send(userShape(req.body));
369
- });
370
- ```
371
-
372
- ---
373
-
374
- ## 🛑 When NOT to use
375
-
376
- Payload Guard is optimized for JSON APIs. It is **not** suitable for:
377
- 1. **Binary Data**: PDFs, Images, or raw Buffers.
378
- 2. **File Streams**: Use `multer` or similar for multipart data.
379
- 3. **Heavy Computation**: Don't use it on payloads > 10MB without adjusting `maxPayloadSize`.
96
+ Built for production reliability:
97
+ - **Isolation**: Monitoring failures **never** break your API responses. If a storage adapter or plugin crashes, the error is caught and logged, while the user's request continues normally.
98
+ - **Async-Only**: All processing is non-blocking to ensure zero impact on event loop latency.
380
99
 
381
100
  ---
382
-
383
- ## 🛠️ CLI
384
-
385
- ```bash
386
- npx payload-guard init
387
- ```
388
-
389
- Creates example files in your project:
390
- - `shapes.ts` — Example shape definitions
391
- - `server-example.ts` — Express middleware setup
101
+ ### ⛑️ Maintained actively.
102
+ **Bug fixes usually within 24–48 hours.**
392
103
 
393
104
  ---
394
-
395
105
  ## 📄 License
396
106
 
397
107
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-guard-filter",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Lightweight, zero-dependency shape-based payload filtering and sanitization for Node.js and browser",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",