{"_id":"@bernierllc/webhook-manager-core","_rev":"6-85be45234d8fbb0a13785dbda22d431d","name":"@bernierllc/webhook-manager-core","dist-tags":{"latest":"1.5.0"},"versions":{"1.0.0":{"name":"@bernierllc/webhook-manager-core","version":"1.0.0","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/webhook-manager-core@1.0.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"2af9c9c5d05de81d5098dc6c53f4014f6e851fe7","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.0.0.tgz","fileCount":61,"integrity":"sha512-wj39BwgVO4tz9OD0FhyNNtiD8+TNF0ehuYcKJacqSSx83my0lZxzJE1Ov9arq1mHD9kBYp8+lFA9G92XGZD1UQ==","signatures":[{"sig":"MEQCIEM8Y4Ga1m3WrASJr/bjCIzWEwGoo9sExfJmREDDGnZvAiBncafR+pmpGNBJXO70FprWWRpg1tLtWw8QduuXGnf6sA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":203286},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"9c038309b7ea6db642bc610e6d625122879021ad","scripts":{"lint":"eslint 'src/**/*.ts'","test":"jest --watch","build":"tsc","clean":"rm -rf dist coverage","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"bernierllc":{"integration":{"neverhub":"optional"}},"_npmVersion":"11.4.2","description":"Generic webhook registration, validation, and management primitives","directories":{},"_nodeVersion":"24.4.1","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/webhook-manager-core_1.0.0_1760372489359_0.9794127066979743","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bernierllc/webhook-manager-core","version":"1.2.0","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/webhook-manager-core@1.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"b7739c738038d941813ebcd4412ab3fba6c181af","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.2.0.tgz","fileCount":62,"integrity":"sha512-iNvpN6sJRoW4iuJTuH+DKNHYwcI8kDpDkE07QqZwK0Ay1D0Qx8lVSISt3XW+bFKRQbrtvti1oQ7Q3wt0clPT3A==","signatures":[{"sig":"MEUCIQCExN5Lej6SFJFwUXO9ZbRGKmgng3Q5SFXMQUbPwgjcqQIgVRFYBpz88DuztyPr4w55eIsvmlh0DWAt/N5kQMUyLbw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":205178},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"af7e74b3715d56d3a193e1bb6743b337c2b0df6d","scripts":{"lint":"eslint 'src/**/*.ts'","test":"jest --watch","build":"tsc","clean":"rm -rf dist coverage","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:acf6c163-7600-4443-836f-73923ad75c5f"}},"bernierllc":{"integration":{"neverhub":"optional"}},"_npmVersion":"lerna/9.0.3/node@v20.19.6+x64 (linux)","description":"Generic webhook registration, validation, and management primitives","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/webhook-manager-core_1.2.0_1767642334360_0.9929483369492416","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@bernierllc/webhook-manager-core","version":"1.2.2","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/webhook-manager-core@1.2.2","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"ef0d5d17b0b9a3569676b07b0e592076d3090661","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.2.2.tgz","fileCount":62,"integrity":"sha512-XgR2B6GTY2PGP1HKLAjFoI+Nl+d3PaZDql1gxMyp6cdzJnphFSPLGZih6oqVYkomU/K2DozOqdyt6pRrtNrx/A==","signatures":[{"sig":"MEYCIQCVW6Kevlao0ZbYNG9TuAxVxDVrTG1q1cHbLBgQsqas/AIhANQK59K5syjHyJaVpBmhIbSvugVn8MB7pREfoJ4tCH+H","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":205576},"main":"dist/index.js","_from":"file:bernierllc-webhook-manager-core-1.2.2.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint 'src/**/*.ts'","test":"jest --watch","build":"tsc","clean":"rm -rf dist coverage","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:acf6c163-7600-4443-836f-73923ad75c5f"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-manager-core/bernierllc-webhook-manager-core-1.2.2.tgz","_integrity":"sha512-XgR2B6GTY2PGP1HKLAjFoI+Nl+d3PaZDql1gxMyp6cdzJnphFSPLGZih6oqVYkomU/K2DozOqdyt6pRrtNrx/A==","bernierllc":{"integration":{"neverhub":"optional"}},"_npmVersion":"11.11.0","description":"Generic webhook registration, validation, and management primitives","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/webhook-manager-core_1.2.2_1773163353564_0.8650789836529724","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@bernierllc/webhook-manager-core","version":"1.3.0","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/webhook-manager-core@1.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"0cc775fa646bd51ca2110c91a30123d0f73c8597","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.3.0.tgz","fileCount":62,"integrity":"sha512-f1ozINB55hCajURqknR/5hFKTLVUp5sz2a4g8qzHLzk8vMUlFnEnvGufZJY39D4qMLLP5RYjtK/8whhCusjN7g==","signatures":[{"sig":"MEUCIQCYfAS1ky805lo/EBcsUPCb8SA9GmgWEtYw2nx8CVMuAwIgQwb9C0ozWLxHFTWkI0kX8eJxfFQVwEDuLazySjBeRRY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":205774},"main":"dist/index.js","_from":"file:bernierllc-webhook-manager-core-1.3.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint 'src/**/*.ts'","test":"jest --watch","build":"tsc","clean":"rm -rf dist coverage","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:acf6c163-7600-4443-836f-73923ad75c5f"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-manager-core/bernierllc-webhook-manager-core-1.3.0.tgz","_integrity":"sha512-f1ozINB55hCajURqknR/5hFKTLVUp5sz2a4g8qzHLzk8vMUlFnEnvGufZJY39D4qMLLP5RYjtK/8whhCusjN7g==","bernierllc":{"integration":{"neverhub":"optional"}},"_npmVersion":"11.14.1","description":"Generic webhook registration, validation, and management primitives","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/webhook-manager-core_1.3.0_1779241480452_0.6480166039424016","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@bernierllc/webhook-manager-core","version":"1.4.0","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","_id":"@bernierllc/webhook-manager-core@1.4.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"297159dcae828c4baa18c392fda74cd5f10565be","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.4.0.tgz","fileCount":36,"integrity":"sha512-ViWHaDBNbFy3gpbKOFIts4wbnSvYtavzaLXD6SduoPDkRSUGJJ90XfRnKnO97xYeMwne2fTQS2LOj997l4Tfkg==","signatures":[{"sig":"MEUCIGCBLSyguhqdS4hQ3HW5WEXEk7pj9q0K0mDLSs2cLjhEAiEA0gLAYDfby1uTb9sO7ewWhxaMA5gkcUV66cf65q36JEA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":81102},"main":"dist/index.js","_from":"file:bernierllc-webhook-manager-core-1.4.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint 'src/**/*.ts'","test":"jest --watch","build":"tsc","clean":"rm -rf dist coverage","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:acf6c163-7600-4443-836f-73923ad75c5f"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-manager-core/bernierllc-webhook-manager-core-1.4.0.tgz","_integrity":"sha512-ViWHaDBNbFy3gpbKOFIts4wbnSvYtavzaLXD6SduoPDkRSUGJJ90XfRnKnO97xYeMwne2fTQS2LOj997l4Tfkg==","bernierllc":{"integration":{"neverhub":"optional"}},"_npmVersion":"11.14.1","description":"Generic webhook registration, validation, and management primitives","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/webhook-manager-core_1.4.0_1779243353949_0.8311807067654149","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@bernierllc/webhook-manager-core","version":"1.5.0","description":"Generic webhook registration, validation, and management primitives","main":"dist/index.js","types":"dist/index.d.ts","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"author":{"name":"Bernier LLC"},"license":"UNLICENSED","devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"peerDependencies":{"@bernierllc/logger":"^1.0.0","@bernierllc/neverhub-adapter":"^0.1.0"},"peerDependenciesMeta":{"@bernierllc/logger":{"optional":true},"@bernierllc/neverhub-adapter":{"optional":true}},"bernierllc":{"integration":{"neverhub":"optional"}},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","test":"jest --watch","test:run":"jest","test:coverage":"jest --coverage","lint":"eslint 'src/**/*.ts'","clean":"rm -rf dist coverage"},"_id":"@bernierllc/webhook-manager-core@1.5.0","_integrity":"sha512-TjeNijnYBf2T+1PTEiyHCBn20pfybj/hANBjUqWUbv+SrzYy847xv98L5wMr2J1UvLplGwi4QwhRN3PYnqXcvw==","_resolved":"/home/runner/work/tools/tools/packages/core/webhook-manager-core/bernierllc-webhook-manager-core-1.5.0.tgz","_from":"file:bernierllc-webhook-manager-core-1.5.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-TjeNijnYBf2T+1PTEiyHCBn20pfybj/hANBjUqWUbv+SrzYy847xv98L5wMr2J1UvLplGwi4QwhRN3PYnqXcvw==","shasum":"46f5232b8a58f161db58bd8fa0a5f8cece19de3b","tarball":"https://registry.npmjs.org/@bernierllc/webhook-manager-core/-/webhook-manager-core-1.5.0.tgz","fileCount":36,"unpackedSize":81102,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCAgbycggVo/pqCys2ZeOHRbUejttOylX1/g/db3HjffwIhAIkVQy1drAqn1sqiRHIjjTJ1WUWd2SdTDFUEKNDmgEXD"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:acf6c163-7600-4443-836f-73923ad75c5f"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/webhook-manager-core_1.5.0_1779250226816_0.560181104718197"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-13T16:21:29.226Z","modified":"2026-05-20T04:10:27.083Z","1.0.0":"2025-10-13T16:21:29.571Z","1.2.0":"2026-01-05T19:45:34.535Z","1.2.2":"2026-03-10T17:22:33.697Z","1.3.0":"2026-05-20T01:44:40.634Z","1.4.0":"2026-05-20T02:15:54.081Z","1.5.0":"2026-05-20T04:10:26.959Z"},"author":{"name":"Bernier LLC"},"license":"UNLICENSED","keywords":["webhook","validation","hmac","signature","replay-attack","deduplication","event-matching"],"description":"Generic webhook registration, validation, and management primitives","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/webhook-manager-core\n\n**Generic webhook registration, validation, and management primitives**\n\nCore-layer package providing atomic utilities for webhook registration, event matching, signature validation infrastructure, and replay attack prevention. Pure functions with zero dependencies on specific webhook providers.\n\n## Installation\n\n```bash\nnpm install @bernierllc/webhook-manager-core\n```\n\n## Features\n\n- **Webhook Endpoint Registration** - Register and manage webhook endpoints with CRUD operations\n- **HMAC Signature Validation** - Generate and validate HMAC signatures (SHA1/256/512)\n- **Constant-Time Comparison** - Prevent timing attacks with constant-time signature comparison\n- **Replay Attack Prevention** - Detect and prevent replay attacks with configurable windows\n- **Event Deduplication** - Prevent duplicate event processing with time-based caching\n- **Event Matching & Filtering** - Match events to endpoints with flexible filter operators\n- **JSON Path Resolution** - Support for complex nested payload filtering\n- **Zero Provider Dependencies** - Generic core primitives, no provider-specific logic\n\n## Usage\n\n### Basic Webhook Management\n\n```typescript\nimport { WebhookManager } from '@bernierllc/webhook-manager-core';\n\n// Initialize manager\nconst manager = new WebhookManager({\n  replayWindowMs: 300000,              // 5 minutes\n  enableDeduplication: true,\n  deduplicationWindowMs: 60000,        // 1 minute\n  defaultAlgorithm: 'sha256',\n});\n\n// Register an endpoint\nconst result = manager.registerEndpoint({\n  id: 'endpoint-1',\n  name: 'Production Webhook',\n  url: 'https://api.example.com/webhooks',\n  secret: 'webhook-secret-key',\n  events: ['push', 'pull_request'],\n  active: true,\n  createdAt: new Date(),\n  updatedAt: new Date(),\n});\n\n// Get endpoint\nconst endpoint = manager.getEndpoint('endpoint-1');\n\n// List all active endpoints\nconst activeEndpoints = manager.listEndpoints({ active: true });\n\n// Update endpoint\nmanager.updateEndpoint('endpoint-1', { active: false });\n\n// Remove endpoint\nmanager.unregisterEndpoint('endpoint-1');\n```\n\n### Signature Validation\n\n```typescript\n// Generate HMAC signature\nconst payload = JSON.stringify({ event: 'push', data: {...} });\nconst signature = manager.generateSignature(payload, 'secret-key', 'sha256');\n// Returns: 'sha256=a1b2c3d4...'\n\n// Validate incoming signature\nconst validation = manager.validateSignature(\n  payload,\n  receivedSignature,\n  'secret-key',\n  'sha256'\n);\n\nif (validation.valid) {\n  // Process webhook\n  console.log('Signature valid!');\n} else {\n  // Reject webhook\n  console.error('Invalid signature:', validation.error);\n}\n\n// Constant-time comparison (prevents timing attacks)\nconst match = manager.compareSignatures(signature1, signature2);\n```\n\n### Replay Attack Prevention\n\n```typescript\nconst event = {\n  id: 'evt-123',\n  type: 'push',\n  source: 'github',\n  payload: {...},\n  timestamp: new Date(),\n};\n\n// Check for replay attack\nconst replayCheck = manager.checkReplayAttack(event);\n\nif (replayCheck.isReplay) {\n  throw new Error(`Replay attack detected: ${replayCheck.reason}`);\n}\n\n// Record successful delivery\nmanager.recordEventDelivery(event.id, new Date());\n\n// Cleanup old events (run periodically)\nconst removed = manager.cleanupOldEvents(\n  new Date(Date.now() - 24 * 60 * 60 * 1000)\n);\nconsole.log(`Cleaned up ${removed} old events`);\n```\n\n### Event Matching & Filtering\n\n```typescript\n// Register endpoint with filters\nmanager.registerEndpoint({\n  id: 'filtered-endpoint',\n  name: 'Main Branch Only',\n  url: 'https://api.example.com/webhooks/main',\n  secret: 'secret',\n  events: ['push'],\n  active: true,\n  filters: [\n    {\n      field: 'payload.branch',\n      operator: 'equals',\n      value: 'main',\n    },\n    {\n      field: 'payload.repository.name',\n      operator: 'equals',\n      value: 'my-app',\n    },\n  ],\n  createdAt: new Date(),\n  updatedAt: new Date(),\n});\n\n// Match event to endpoints\nconst matchedEndpoints = manager.matchEndpoints(event);\nconsole.log(`Matched ${matchedEndpoints.length} endpoints`);\n\n// Apply individual filters\nconst passes = manager.applyFilter(event, {\n  field: 'payload.branch',\n  operator: 'equals',\n  value: 'main',\n});\n\n// Apply multiple filters (AND logic)\nconst passesAll = manager.applyFilters(event, [\n  { field: 'payload.branch', operator: 'equals', value: 'main' },\n  { field: 'payload.repository.name', operator: 'contains', value: 'app' },\n]);\n```\n\n### Event Deduplication\n\n```typescript\n// Check if event is a duplicate\nif (manager.isDuplicate(event)) {\n  console.log('Duplicate event detected, skipping');\n  return;\n}\n\n// Record event for deduplication tracking\nmanager.recordEvent(event);\n\n// Clear deduplication cache (run periodically)\nmanager.clearDuplicateCache();\n```\n\n## API Reference\n\n### WebhookManager\n\nMain class that orchestrates all webhook operations.\n\n#### Constructor\n\n```typescript\nnew WebhookManager(config?: WebhookManagerConfig)\n```\n\n**Configuration Options:**\n\n```typescript\ninterface WebhookManagerConfig {\n  replayWindowMs?: number;              // Default: 300000 (5 minutes)\n  maxStoredEvents?: number;             // Default: 10000\n  enableDeduplication?: boolean;        // Default: true\n  deduplicationWindowMs?: number;       // Default: 60000 (1 minute)\n  defaultAlgorithm?: SignatureAlgorithm; // Default: 'sha256'\n  neverhubConfig?: NeverhubConfig;\n  loggerConfig?: LoggerConfig;\n}\n```\n\n#### Registration Methods\n\n- `registerEndpoint(endpoint: WebhookEndpoint): WebhookRegistrationResult`\n- `unregisterEndpoint(endpointId: string): boolean`\n- `getEndpoint(endpointId: string): WebhookEndpoint | null`\n- `listEndpoints(filter?: EndpointFilter): WebhookEndpoint[]`\n- `updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): WebhookRegistrationResult`\n\n#### Signature Methods\n\n- `generateSignature(payload: string, secret: string, algorithm: SignatureAlgorithm): string`\n- `validateSignature(payload: string, signature: string, secret: string, algorithm: SignatureAlgorithm): SignatureValidationResult`\n- `compareSignatures(signature1: string, signature2: string): boolean`\n\n#### Replay Prevention Methods\n\n- `checkReplayAttack(event: WebhookEvent, windowMs?: number): ReplayCheckResult`\n- `recordEventDelivery(eventId: string, timestamp: Date): void`\n- `cleanupOldEvents(olderThan: Date): number`\n\n#### Deduplication Methods\n\n- `isDuplicate(event: WebhookEvent): boolean`\n- `recordEvent(event: WebhookEvent): void`\n- `clearDuplicateCache(): void`\n\n#### Event Matching Methods\n\n- `matchEndpoints(event: WebhookEvent): WebhookEndpoint[]`\n- `validateEventType(eventType: string, allowedTypes: string[]): boolean`\n- `applyFilter(event: WebhookEvent, filter: WebhookFilter): boolean`\n- `applyFilters(event: WebhookEvent, filters: WebhookFilter[]): boolean`\n\n#### Configuration Methods\n\n- `getConfig(): WebhookManagerConfig`\n- `updateConfig(updates: Partial<WebhookManagerConfig>): void`\n\n## Filter Operators\n\nSupported filter operators for event matching:\n\n- **equals** - Exact match\n- **notEquals** - Not equal to value\n- **contains** - String or array contains value\n- **notContains** - String or array does not contain value\n- **matches** - Regex pattern match\n- **in** - Value is in array\n- **notIn** - Value is not in array\n- **exists** - Field exists (or not exists if value is false)\n- **greaterThan** - Numeric comparison\n- **lessThan** - Numeric comparison\n\n## Signature Algorithms\n\nSupported HMAC algorithms:\n\n- **sha1** - Legacy support (not recommended)\n- **sha256** - Default, recommended for most use cases\n- **sha512** - Maximum security for sensitive webhooks\n\n## Security Considerations\n\n- **Constant-Time Comparison** - Always uses constant-time comparison to prevent timing attacks\n- **Replay Window** - Keep replay window short (5-15 minutes recommended)\n- **Event Cache Cleanup** - Run periodic cleanup to prevent memory exhaustion\n- **Secret Storage** - Always use environment variables for secrets, never hardcode\n\n## Integration Status\n\n- **Logger**: not-applicable - Core package, no logging requirements\n- **Docs-Suite**: ready - Complete API documentation with examples\n- **NeverHub**: not-applicable - Core package, no service discovery needed\n\n## Testing\n\n```bash\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Run tests once\nnpm run test:run\n```\n\n## Development\n\n```bash\n# Build package\nnpm run build\n\n# Lint code\nnpm run lint\n\n# Clean build artifacts\nnpm run clean\n```\n\n## License\n\nCopyright (c) 2025 Bernier LLC. All rights reserved.\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n\n## Related Packages\n\n- [@bernierllc/webhook-signature-validator](../webhook-signature-validator) - Provider-specific signature validation\n- [@bernierllc/webhook-github-service](../../service/webhook-github-service) - GitHub webhook handler\n- [@bernierllc/webhook-routing-service](../../service/webhook-routing-service) - Webhook routing logic\n- [@bernierllc/webhook-service](../../service/webhook-service) - Complete webhook service\n\n## See Also\n\nFor complete webhook solutions, see:\n- [@bernierllc/webhook-automation-suite](../../suite/webhook-automation-suite) - Complete webhook automation\n- [@bernierllc/content-management-suite](../../suite/content-management-suite) - Content management with webhooks\n","readmeFilename":"README.md"}