{"_id":"@bernierllc/webhook-sender","_rev":"10-56aa94e91137b5165cb23657ecb9a9db","name":"@bernierllc/webhook-sender","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.1":{"name":"@bernierllc/webhook-sender","version":"0.1.1","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.1.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"59ad0f698378a2d77a2e0e19fe107d57adfd60e3","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.1.1.tgz","fileCount":30,"integrity":"sha512-vDFFzXmZxwKiG6HTcAe9ml6ug6cENumr9c1SLqH/P299Dg+PDBshPr/yWBz0z+5OUdy6AWBJic89G4VP/em69g==","signatures":[{"sig":"MEQCIFl3tWloxhRmc7hxRRR8eZhmoqUUazYufjymulbTNkYKAiALROT4a/1F9dRBUOIrID/dj9pwjgxjBjoyOMRvKSYm0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88581},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d4dcb94e2c876caa4d830e956f0d84c2433c4f1d","scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"11.4.2","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"24.4.1","dependencies":{},"publishConfig":{"access":"restricted"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.1.1_1756585916444_0.7755926800360131","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bernierllc/webhook-sender","version":"0.1.3","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.1.3","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"470a95aec6430ff495f35b8cd3f5e65746086ecb","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.1.3.tgz","fileCount":30,"integrity":"sha512-PtcM3KiV3fWVOSdpBfJMyPYr/go5I2voPwQtdJbKzPWAD6BOsAcnsv2XqM3xcNvYpd6ozaVZcKuYTTiiVbUiAg==","signatures":[{"sig":"MEUCIQCaiFC5Sl+7Uv7NpxCk/K87f7TQ4hjYH0T3cMeJPCPurQIgLdQLUgjjWEtzD0YZd8rp+iPvCENLr/20+qOFyBBULJs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88663},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"683786f5b043d9a96c9f49ed1f04f9dccd79eed3","scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"lerna/9.0.3/node@v20.19.6+x64 (linux)","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"restricted","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.1.3_1767644250347_0.6796210586578642","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@bernierllc/webhook-sender","version":"0.1.4","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.1.4","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"18a1df5168cb7adeb0e8f6bb9c707e800042d843","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.1.4.tgz","fileCount":30,"integrity":"sha512-/oBLiTTy/d8I8Ii4NYbq7jPbfni9eF+eDchJbr/wYQJOySHt9S7GxGc+bhOGtLvN1v6hbG3V4a4aNIuBice68A==","signatures":[{"sig":"MEYCIQDpmr8L8evkV8qclpRR2dzUINxK9WGbbP74LPeDgWPT5QIhALT1bPnXG4edd06YLkURo2yMlIhMEIk1wsdF8Tkd6buH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88545},"main":"dist/index.js","type":"module","_from":"file:bernierllc-webhook-sender-0.1.4.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"_resolved":"/tmp/eaca9842e6f7677b180ada1be4ed466a/bernierllc-webhook-sender-0.1.4.tgz","_integrity":"sha512-/oBLiTTy/d8I8Ii4NYbq7jPbfni9eF+eDchJbr/wYQJOySHt9S7GxGc+bhOGtLvN1v6hbG3V4a4aNIuBice68A==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"11.11.0","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.1.4_1773078090187_0.44938207652574436","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@bernierllc/webhook-sender","version":"0.1.5","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.1.5","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"b71b3924cdcc1411c93ce855bbc15293c6c92808","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.1.5.tgz","fileCount":30,"integrity":"sha512-AqwHVcbCSMMELwqUv3fAyRGn/G0MIGmlzi7MuEqhvjhZ365QcGMuZzLVZz/cG5ClzqcsX6jlsC3HP2+8OHvWGg==","signatures":[{"sig":"MEYCIQDY6EweovU4A+UfhcjkIVAHruy9Ey/cQEfQ+H357qqgtAIhAM/rvw744HObGhQzn5DwK1lQGPf4VdEVRoMNCmoHfmTA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88545},"main":"dist/index.js","type":"module","_from":"file:bernierllc-webhook-sender-0.1.5.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-sender/bernierllc-webhook-sender-0.1.5.tgz","_integrity":"sha512-AqwHVcbCSMMELwqUv3fAyRGn/G0MIGmlzi7MuEqhvjhZ365QcGMuZzLVZz/cG5ClzqcsX6jlsC3HP2+8OHvWGg==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"11.11.0","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.1.5_1773163358830_0.4887012974473648","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bernierllc/webhook-sender","version":"0.2.0","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"a0105ee7ecb5ce66683bf725a165f0c7378d3262","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.2.0.tgz","fileCount":30,"integrity":"sha512-/6WFGGapbp2k3X6ptdLNxw4MnATKj5tyMwwiJpMZsGeOKnUG5GjVAPeAGBtCB6O5xKY912ifhKcjJKQZPjwvag==","signatures":[{"sig":"MEYCIQDu7Im8qub0jM5rMQJlud/InM4MeWIzAicmsZXowbF8EQIhALzof+OPsfg84l+JI4VBgby4SYJVtkh5VW2VtIlFw+Xv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88545},"main":"dist/index.js","type":"module","_from":"file:bernierllc-webhook-sender-0.2.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-sender/bernierllc-webhook-sender-0.2.0.tgz","_integrity":"sha512-/6WFGGapbp2k3X6ptdLNxw4MnATKj5tyMwwiJpMZsGeOKnUG5GjVAPeAGBtCB6O5xKY912ifhKcjJKQZPjwvag==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"11.14.1","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.2.0_1779241488944_0.8878462417747284","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bernierllc/webhook-sender","version":"0.3.0","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/webhook-sender@0.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"49a72715358cc40339ba33e608a522816f909a79","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.3.0.tgz","fileCount":23,"integrity":"sha512-jHFszDKN1S1tqj+5jCZjpsIvpzEtS9iQob/a8cE9OVGoJ610G/ZPLXPLHRh0nHbmXWrltysROJmZn8KBFW9RfA==","signatures":[{"sig":"MEUCIQD1PKH6k39EmxfvhVm+tXHuod1iz6I2R7ZYpiZGHfj6twIgRt/qDuewTl4Tu13gRvUeQPme/BN8mCZHyX5bOE0R0YU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56878},"main":"dist/index.js","type":"module","_from":"file:bernierllc-webhook-sender-0.3.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src/**/*.ts","test":"echo 'No tests configured'","build":"tsc","clean":"rm -rf dist","test:run":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"_resolved":"/home/runner/work/tools/tools/packages/core/webhook-sender/bernierllc-webhook-sender-0.3.0.tgz","_integrity":"sha512-jHFszDKN1S1tqj+5jCZjpsIvpzEtS9iQob/a8cE9OVGoJ610G/ZPLXPLHRh0nHbmXWrltysROJmZn8KBFW9RfA==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/webhook-sender"},"_npmVersion":"11.14.1","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.50.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/webhook-sender_0.3.0_1779243358765_0.5549587481431346","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bernierllc/webhook-sender","version":"0.4.0","description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","devDependencies":{"@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/eslint-plugin":"^6.7.2","@typescript-eslint/parser":"^6.7.2","eslint":"^8.50.0","jest":"^29.7.0","ts-jest":"^29.1.1","typescript":"^5.2.2"},"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/webhook-sender"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","test":"echo 'No tests configured'","test:coverage":"jest --coverage","test:watch":"jest --watch","test:run":"jest --passWithNoTests","lint":"eslint src/**/*.ts","clean":"rm -rf dist"},"_id":"@bernierllc/webhook-sender@0.4.0","_integrity":"sha512-fz+YG4sBBMdw75LqL2VzTJfWX5Vl9OXhaJpEGnxTQJQvIVmlSqgZQjXPWeMbblgAQgK8vPbVnTZrjmJHzpQvcw==","_resolved":"/home/runner/work/tools/tools/packages/core/webhook-sender/bernierllc-webhook-sender-0.4.0.tgz","_from":"file:bernierllc-webhook-sender-0.4.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-fz+YG4sBBMdw75LqL2VzTJfWX5Vl9OXhaJpEGnxTQJQvIVmlSqgZQjXPWeMbblgAQgK8vPbVnTZrjmJHzpQvcw==","shasum":"6efde2e8f22d69af1603b9a1fb24e62a21394c15","tarball":"https://registry.npmjs.org/@bernierllc/webhook-sender/-/webhook-sender-0.4.0.tgz","fileCount":23,"unpackedSize":56878,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDqWAkvbhoUFfPysB1fxeHgMifq4LBMUCtSLhSug3ffrAIhAMqO/9sDQFR4ptB22sRN+OdRoyR36T8eHi5ygTRBKe44"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6935d82e-d94a-4ad7-a3e4-5a6d9f722351"}},"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-sender_0.4.0_1779250235354_0.9875504150529804"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-30T20:31:56.017Z","modified":"2026-05-20T04:10:35.654Z","0.1.1":"2025-08-30T20:31:56.618Z","0.1.3":"2026-01-05T20:17:30.495Z","0.1.4":"2026-03-09T17:41:30.326Z","0.1.5":"2026-03-10T17:22:38.982Z","0.2.0":"2026-05-20T01:44:49.088Z","0.3.0":"2026-05-20T02:15:58.950Z","0.4.0":"2026-05-20T04:10:35.504Z"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/bernierllc/tools/tree/main/packages/core/webhook-sender","keywords":["webhook","sender","http","delivery","retry","signature","hmac","jwt","circuit-breaker"],"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/webhook-sender"},"description":"HTTP webhook delivery with retry logic, signature generation, and delivery tracking","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/webhook-sender\n\nHTTP webhook delivery with retry logic, signature generation, and delivery tracking.\n\n## Overview\n\nReliable webhook delivery system with exponential backoff, signature generation, timeout handling, and delivery status tracking. Framework-agnostic core that handles the complexity of reliable webhook delivery.\n\n## Features\n\n- **Reliable Delivery**: Exponential backoff retry with configurable policies\n- **Signature Generation**: HMAC-SHA256, JWT, custom signature algorithms  \n- **Timeout Handling**: Configurable request and delivery timeouts\n- **Delivery Tracking**: Track delivery status, attempts, and response codes\n- **Batch Delivery**: Send multiple webhooks efficiently\n- **Circuit Breaker**: Disable failing endpoints temporarily\n- **Rate Limiting**: Control delivery rate for batch operations\n- **NeverHub Integration**: Optional event publishing for monitoring\n\n## Installation\n\n```bash\nnpm install @bernierllc/webhook-sender\n```\n\n## Quick Start\n\n### Basic Webhook Sending\n\n```typescript\nimport { WebhookSender } from '@bernierllc/webhook-sender';\n\nconst sender = new WebhookSender({\n  timeout: 30000,\n  retryPolicy: {\n    maxAttempts: 3,\n    initialDelayMs: 1000,\n    maxDelayMs: 10000,\n    backoffMultiplier: 2,\n    jitter: true,\n    retryableStatusCodes: [408, 429, 500, 502, 503, 504]\n  }\n});\n\nconst result = await sender.send({\n  url: 'https://api.example.com/webhooks',\n  body: {\n    event: 'user.created',\n    data: { userId: '123', email: 'user@example.com' }\n  },\n  signature: {\n    algorithm: 'hmac-sha256',\n    secret: process.env.WEBHOOK_SECRET!,\n    header: 'x-signature-256'\n  },\n  metadata: {\n    source: 'user-service',\n    event: 'user.created'\n  }\n});\n\nif (result.success) {\n  console.log(`Webhook delivered in ${result.duration}ms after ${result.attempts} attempts`);\n} else {\n  console.error(`Webhook failed: ${result.error}`);\n}\n```\n\n### Batch Webhook Delivery\n\n```typescript\nimport { WebhookSender } from '@bernierllc/webhook-sender';\n\nconst sender = new WebhookSender();\n\nconst webhooks = [\n  {\n    url: 'https://api.example.com/webhooks',\n    body: { event: 'order.created', orderId: '123' }\n  },\n  {\n    url: 'https://partner.example.com/notify',\n    body: { event: 'order.created', orderId: '123' }\n  }\n];\n\nconst results = await sender.sendBatch(webhooks);\n\nresults.forEach((result, index) => {\n  if (result.success) {\n    console.log(`Webhook ${index} delivered successfully`);\n  } else {\n    console.error(`Webhook ${index} failed: ${result.error}`);\n  }\n});\n```\n\n### GitHub-Style Webhooks\n\n```typescript\nimport { WebhookSender, generateHmacSignature } from '@bernierllc/webhook-sender';\n\nconst sender = new WebhookSender({\n  retryPolicy: {\n    maxAttempts: 3,\n    initialDelayMs: 1000,\n    maxDelayMs: 30000,\n    backoffMultiplier: 2,\n    jitter: true,\n    retryableStatusCodes: [408, 429, 500, 502, 503, 504]\n  }\n});\n\nawait sender.send({\n  url: webhookUrl,\n  headers: {\n    'content-type': 'application/json',\n    'user-agent': 'MyApp-Hookshot/1.0',\n    'x-github-event': 'push',\n    'x-github-delivery': generateWebhookId()\n  },\n  body: pushEventData,\n  signature: {\n    algorithm: 'hmac-sha256',\n    secret: webhookSecret,\n    header: 'x-hub-signature-256'\n  }\n});\n```\n\n## API Reference\n\n### WebhookSender\n\nMain class for sending webhooks.\n\n#### Constructor\n\n```typescript\nnew WebhookSender(options?: DeliveryOptions)\n```\n\n#### Methods\n\n- `send(payload: WebhookPayload): Promise<DeliveryResult>` - Send a single webhook\n- `sendBatch(payloads: WebhookPayload[]): Promise<DeliveryResult[]>` - Send multiple webhooks\n- `generateSignature(payload: string, secret: string, algorithm: string): string` - Generate signature\n- `validateDelivery(result: DeliveryResult): boolean` - Validate delivery result\n- `getDeliveryStats()` - Get delivery statistics\n- `resetCircuitBreaker()` - Reset circuit breaker state\n\n### WebhookPayload\n\n```typescript\ninterface WebhookPayload {\n  url: string;                    // Webhook endpoint URL\n  method?: string;                // HTTP method (default: POST)\n  headers?: Record<string, string>; // Custom headers\n  body: any;                      // Request body\n  signature?: {                    // Optional signature configuration\n    algorithm: 'hmac-sha256' | 'hmac-sha1' | 'jwt' | 'custom';\n    secret: string;\n    header?: string;\n  };\n  metadata?: {                     // Optional metadata\n    id?: string;\n    source?: string;\n    event?: string;\n    timestamp?: string;\n  };\n}\n```\n\n### DeliveryOptions\n\n```typescript\ninterface DeliveryOptions {\n  timeout?: number;                // Request timeout (default: 30s)\n  retryPolicy?: RetryPolicy;       // Retry configuration\n  circuitBreaker?: CircuitBreakerOptions; // Circuit breaker config\n  validateResponse?: (response: Response) => boolean; // Custom response validation\n  transformPayload?: (payload: any) => any; // Payload transformation\n}\n```\n\n### RetryPolicy\n\n```typescript\ninterface RetryPolicy {\n  maxAttempts: number;             // Maximum retry attempts\n  initialDelayMs: number;          // Initial delay between retries\n  maxDelayMs: number;              // Maximum delay between retries\n  backoffMultiplier: number;       // Exponential backoff multiplier\n  jitter: boolean;                 // Add random jitter to delays\n  retryableStatusCodes: number[];  // HTTP status codes to retry\n}\n```\n\n### CircuitBreakerOptions\n\n```typescript\ninterface CircuitBreakerOptions {\n  failureThreshold: number;        // Failures before opening circuit\n  recoveryTimeout: number;         // Time to wait before recovery\n  monitorInterval: number;         // Circuit state check interval\n}\n```\n\n## Configuration\n\n### Default Options\n\n```typescript\nimport { DEFAULT_OPTIONS } from '@bernierllc/webhook-sender';\n\n// Default configuration\nconst defaultConfig = {\n  timeout: 30000, // 30 seconds\n  retryPolicy: {\n    maxAttempts: 3,\n    initialDelayMs: 1000,\n    maxDelayMs: 10000,\n    backoffMultiplier: 2,\n    jitter: true,\n    retryableStatusCodes: [408, 429, 500, 502, 503, 504]\n  },\n  circuitBreaker: {\n    failureThreshold: 5,\n    recoveryTimeout: 60000, // 1 minute\n    monitorInterval: 10000  // 10 seconds\n  }\n};\n```\n\n### Custom Response Validation\n\n```typescript\nconst sender = new WebhookSender({\n  validateResponse: (response) => {\n    // Custom validation logic\n    return response.status >= 200 && response.status < 300 && \n           response.headers.get('x-custom-header') === 'expected-value';\n  }\n});\n```\n\n### Payload Transformation\n\n```typescript\nconst sender = new WebhookSender({\n  transformPayload: (payload) => {\n    // Transform payload before sending\n    return {\n      ...payload,\n      timestamp: new Date().toISOString(),\n      version: '1.0'\n    };\n  }\n});\n```\n\n## Signature Generation\n\n### HMAC Signatures\n\n```typescript\nimport { generateHmacSignature } from '@bernierllc/webhook-sender';\n\nconst signature = generateHmacSignature(\n  JSON.stringify(payload),\n  secret,\n  'sha256'\n);\n```\n\n### JWT Signatures\n\n```typescript\nimport { generateJwtSignature } from '@bernierllc/webhook-sender';\n\nconst signature = generateJwtSignature(\n  payload,\n  secret,\n  { expiresIn: '1h', issuer: 'my-app' }\n);\n```\n\n### Custom Signatures\n\n```typescript\nimport { generateCustomSignature } from '@bernierllc/webhook-sender';\n\nconst signature = generateCustomSignature(\n  JSON.stringify(payload),\n  secret,\n  (payload, secret) => {\n    // Custom signature generation logic\n    return customHashFunction(payload + secret);\n  }\n);\n```\n\n## Batch Delivery\n\n### Concurrency Control\n\n```typescript\nconst batchSender = new BatchWebhookSender(sender, {\n  maxConcurrency: 10,\n  rateLimit: {\n    requestsPerSecond: 5,\n    burstSize: 20\n  }\n});\n\nconst results = await batchSender.sendBatch(webhooks);\n```\n\n### Batch Statistics\n\n```typescript\nconst stats = batchSender.getBatchStats(results);\nconsole.log(`Success rate: ${stats.successRate}%`);\nconsole.log(`Average delivery time: ${stats.averageDeliveryTime}ms`);\n```\n\n## Delivery Tracking\n\n### Get Delivery Statistics\n\n```typescript\nconst stats = sender.getDeliveryStats();\nconsole.log(`Total sent: ${stats.totalSent}`);\nconsole.log(`Success rate: ${(stats.totalSuccessful / stats.totalSent) * 100}%`);\nconsole.log(`Circuit breaker state: ${stats.circuitBreakerState}`);\n```\n\n### Track Specific Deliveries\n\n```typescript\nconst delivery = sender.getDelivery(webhookId);\nif (delivery) {\n  console.log(`Delivery ${webhookId}: ${delivery.success ? 'Success' : 'Failed'}`);\n}\n```\n\n## NeverHub Integration\n\n### Initialize Integration\n\n```typescript\nimport { initializeNeverHubIntegration } from '@bernierllc/webhook-sender';\n\nawait initializeNeverHubIntegration();\n```\n\n### Publish Events\n\n```typescript\nimport { publishDeliverySuccess, publishDeliveryFailure } from '@bernierllc/webhook-sender';\n\nconst result = await sender.send(webhook);\n\nif (result.success) {\n  await publishDeliverySuccess(result);\n} else {\n  await publishDeliveryFailure(result);\n}\n```\n\n## Error Handling\n\n### WebhookError\n\n```typescript\nimport { WebhookError } from '@bernierllc/webhook-sender';\n\ntry {\n  const result = await sender.send(webhook);\n  if (!result.success) {\n    throw new WebhookError(\n      result.error || 'Delivery failed',\n      'DELIVERY_FAILED',\n      result.statusCode,\n      result.attempts\n    );\n  }\n} catch (error) {\n  if (error instanceof WebhookError) {\n    console.error(`Webhook delivery failed after ${error.attempts} attempts`);\n  }\n}\n```\n\n### Error Codes\n\n```typescript\nimport { ERROR_CODES } from '@bernierllc/webhook-sender';\n\n// Available error codes\nconst codes = {\n  DELIVERY_FAILED: 'DELIVERY_FAILED',\n  TIMEOUT: 'TIMEOUT',\n  CIRCUIT_OPEN: 'CIRCUIT_OPEN',\n  INVALID_URL: 'INVALID_URL',\n  SIGNATURE_GENERATION_FAILED: 'SIGNATURE_GENERATION_FAILED',\n  RATE_LIMITED: 'RATE_LIMITED',\n  NETWORK_ERROR: 'NETWORK_ERROR'\n};\n```\n\n## Performance\n\n### Batch Processing\n\n- **Concurrency**: Control parallel webhook delivery\n- **Rate Limiting**: Respect API rate limits\n- **Connection Reuse**: Efficient HTTP connection handling\n- **Memory Management**: Minimal memory footprint\n\n### Monitoring\n\n- **Delivery Metrics**: Track success/failure rates\n- **Performance Metrics**: Monitor delivery times\n- **Circuit Breaker**: Automatic failure detection\n- **Retry Analytics**: Understand retry patterns\n\n## Testing\n\n### Mock Responses\n\n```typescript\n// Mock fetch for testing\nglobal.fetch = jest.fn(() =>\n  Promise.resolve({\n    ok: true,\n    status: 200,\n    text: () => Promise.resolve('OK'),\n    url: 'https://example.com/webhook'\n  } as Response)\n);\n```\n\n### Test Delivery Results\n\n```typescript\nconst result = await sender.send(webhook);\n\nexpect(result.success).toBe(true);\nexpect(result.statusCode).toBe(200);\nexpect(result.attempts).toBe(1);\nexpect(result.duration).toBeGreaterThan(0);\n```\n\n## Dependencies\n\n- `@bernierllc/retry-policy` - Retry logic and policies\n- `@bernierllc/retry-state` - Retry state management\n- `@bernierllc/retry-metrics` - Retry metrics collection\n- `@bernierllc/crypto-utils` - Cryptographic utilities\n- `@bernierllc/logger` - Logging functionality\n- `@bernierllc/neverhub-adapter` - NeverHub integration (optional)\n\n## License\n\nCopyright (c) 2025 Bernier LLC\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","readmeFilename":"README.md"}