{"_id":"@bernierllc/contentful-webhook-handler","_rev":"13-590ff56fa409b80175ac3fa5705417fc","name":"@bernierllc/contentful-webhook-handler","dist-tags":{"latest":"1.3.1"},"versions":{"1.0.3":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.3","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.3","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"3f154685edecf43a1925366eeae7e5e382e7ccfa","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.3.tgz","fileCount":18,"integrity":"sha512-qWmFtZi8KIC8L3H2GM312V0YoRYgTv7YC+TQoTbJX/C22CSfbbgBvfnFNmVRio0kt/wsFnL77m5jZwr2naNUzQ==","signatures":[{"sig":"MEUCIHjNJ/gmTw/DDsGvgE/+dv84sFwklwJHQos3wHz4kgokAiEA90yK9nFa5w5g2VxVI3iTCfbFWaCPf4Tfqwv4OWKSmN8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86289},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"6d983930db7bf61408ab2f33f9d7293ade7a76ff","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch","prepublishOnly":"npm run build && npm run lint && npm test"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.6.2","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@bernierllc/logger":"^1.0.1","@bernierllc/contentful-types":"workspace:*"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.3_1764703369367_0.8124750755548695","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.4","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.4","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"1b99b41dce8b33dd726bc407db95f2e4cf630117","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.4.tgz","fileCount":31,"integrity":"sha512-6Nn/iALq0VnsM+dY09aPRQ9HFbgesww/JIVyGLDKlbOdT7PzwCx66Up93HqykcQXPqsBi5/MKdd9CaWZVb4J6Q==","signatures":[{"sig":"MEYCIQCC319jVsByS8L6pFhqgd6N9yzYRBPSy9JHAxDqn0nZrQIhAILfQ20YCAkLmDkGUL4JB8nEe6xqs5sEaUMZvvAyXe4e","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":180883},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.4.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_resolved":"/private/var/folders/r0/wspnzd1s18sfjy10ffyv2qxw0000gn/T/b0200c1c5341020adae3dbab64107df3/bernierllc-contentful-webhook-handler-1.0.4.tgz","_integrity":"sha512-6Nn/iALq0VnsM+dY09aPRQ9HFbgesww/JIVyGLDKlbOdT7PzwCx66Up93HqykcQXPqsBi5/MKdd9CaWZVb4J6Q==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.6.2","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@bernierllc/logger":"^1.0.1","@bernierllc/contentful-types":"1.0.4"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.4_1764703608115_0.6749727427765859","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.5","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.5","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"0a8b7c8a59f0f0e00a907120ff3e0e3886c5039a","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.5.tgz","fileCount":19,"integrity":"sha512-cybAzU1h4QqnrToBcbWer7BNBAGtRIAa9Kg7gQ751v72vbY7MTFV62F4vRqCbuKOJLZmRXgt3ObNnVcnvoz6zg==","signatures":[{"sig":"MEUCIGs9ylFtwblxrtmNSafCLvLl0YbpbYNtStnsVWbWT/sGAiEA+Hj5hXZd0s2U7S1t9y9uJZmCBBv9qeQTIu+hB+Judq0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86533},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.5.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/tmp/20108e1e9880a48b1874a458fee21e62/bernierllc-contentful-webhook-handler-1.0.5.tgz","_integrity":"sha512-cybAzU1h4QqnrToBcbWer7BNBAGtRIAa9Kg7gQ751v72vbY7MTFV62F4vRqCbuKOJLZmRXgt3ObNnVcnvoz6zg==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.7.0","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.19.6","dependencies":{"@bernierllc/logger":"1.0.4","@bernierllc/contentful-types":"1.0.4"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.5_1766437806969_0.30270729061062873","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.6","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.6","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"a1b202ecfd68cdf06a4a9aef4dde3d1f84580a71","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.6.tgz","fileCount":19,"integrity":"sha512-L5WKPAw0YkmCGaKnMiD732BZ8OwEY+RGjJ0vETwDw/vynUPE+x+i40vb1cBiS4d6CpNwyJIv+G0GvmMnZ4GWoA==","signatures":[{"sig":"MEQCIFPZ1+d6u55UrZXUXL7q1/z5UH8Xold+4zhNkbH9NtjhAiADpiZSw8G23CGDKN2+afmGD6xKzYv3pmaGC1tEaWBl5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86715},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.6.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/tmp/1cbb97df2da7ae42317e2d350b1842ce/bernierllc-contentful-webhook-handler-1.0.6.tgz","_integrity":"sha512-L5WKPAw0YkmCGaKnMiD732BZ8OwEY+RGjJ0vETwDw/vynUPE+x+i40vb1cBiS4d6CpNwyJIv+G0GvmMnZ4GWoA==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.7.0","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.19.6","dependencies":{"@bernierllc/logger":"1.1.0","@bernierllc/contentful-types":"1.0.4"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.6_1766454443662_0.11671686538405046","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.8","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.8","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"d5f83b1e2eb3c4c17fa7ac26a0ed8c9771919e36","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.8.tgz","fileCount":19,"integrity":"sha512-j5oO1AYYq/UeuyD5bcKqO6qDzJSiGrnH8i2mZYOHaDPBIxsIBm+QRc32B/yCKag/+xeEnFknM3uxgMQi1wkSzg==","signatures":[{"sig":"MEQCID9S7s6pqI2cSMbezHYudwVj+68zfG7sZj2ZrZVvM18dAiBBT6wO3qH6o70LKd+ohiHFiviJDCAqhU/K9+aU4Cd/zQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87896},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"af7e74b3715d56d3a193e1bb6743b337c2b0df6d","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch","prepublishOnly":"npm run build && npm run lint && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"lerna/9.0.3/node@v20.19.6+x64 (linux)","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.19.6","dependencies":{"@bernierllc/logger":"1.3.0","@bernierllc/contentful-types":"1.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.8_1767642435959_0.03339472158853751","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.9","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.9","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"928a0e8dc12484fa9b5a0a57196e86b465458519","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.9.tgz","fileCount":19,"integrity":"sha512-SiQfkZM0Ibdz/7BBo9Q8z7GvvEQ5SNr0ABMaaWunC2PUR57vA9Vn1VX3jnP/0wKHp5wy/HUfUrs+HMzvMECaWg==","signatures":[{"sig":"MEUCIAgk1fW3r4sM0Bf/2qjK2U+WAxw9ZadpzmiAS23FrxIhAiEAugeLGJ7t8EOYMx3NcSqgF2JDuoJc385YiV/jSlAwSNY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88017},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.9.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/tmp/1f1bd1e4c81984f7e119abd7b608ad9f/bernierllc-contentful-webhook-handler-1.0.9.tgz","_integrity":"sha512-SiQfkZM0Ibdz/7BBo9Q8z7GvvEQ5SNr0ABMaaWunC2PUR57vA9Vn1VX3jnP/0wKHp5wy/HUfUrs+HMzvMECaWg==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.11.0","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@bernierllc/logger":"1.3.1","@bernierllc/contentful-types":"1.2.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.9_1773078432889_0.04372944754357144","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.10","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.10","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"0a222dfa9946e0f4213d3b688f5a098a20d741c7","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.10.tgz","fileCount":19,"integrity":"sha512-ijp+aiTB9l6nSohkN+tlTe7WKUA7Iuzn+B3k0FFLnATbXLpR4QpLQm0k/Z6H6oF/VtFTMEH7L0EamWN1xJGeow==","signatures":[{"sig":"MEYCIQD/GYKj12CEXi1fkvKAytqsLlwq3J+UtWl6H02ZzIlTbwIhAONf1DoHLBVmKxRz3UlVNhhDHGI1usOegDXxrFoWGE6U","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88266},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.10.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.0.10.tgz","_integrity":"sha512-ijp+aiTB9l6nSohkN+tlTe7WKUA7Iuzn+B3k0FFLnATbXLpR4QpLQm0k/Z6H6oF/VtFTMEH7L0EamWN1xJGeow==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.11.0","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@bernierllc/logger":"1.3.2","@bernierllc/contentful-types":"1.2.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.10_1773163128754_0.48248824680043834","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.11","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.11","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"49abbaddb9cf44ff09530cd1be476f8d39e02816","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.11.tgz","fileCount":19,"integrity":"sha512-UXgP0xl6lsmionIzQS3e8DKRLWx6IZYYtPeCpo/H+KpMZlO/Et3vhW00OVdqrcdXv3jyNii37VtKkeupygBtMQ==","signatures":[{"sig":"MEQCIGkBvZ3rW7XhO+gTRGd+t1v+B2r5DapqmvIyGcZQ9JCnAiA28EkArcg14CkPLRkZy5vtI3cVJwW/NZoV+pV0AXYHuw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88515},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.11.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.0.11.tgz","_integrity":"sha512-UXgP0xl6lsmionIzQS3e8DKRLWx6IZYYtPeCpo/H+KpMZlO/Et3vhW00OVdqrcdXv3jyNii37VtKkeupygBtMQ==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.14.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/logger":"1.4.0","@bernierllc/contentful-types":"1.2.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.11_1779133415773_0.4463554099853926","host":"s3://npm-registry-packages-npm-production"}},"1.0.12":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.12","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.12","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"65c2d4b2ac011856e4b0f5c3d73e46c6e1f7be45","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.12.tgz","fileCount":19,"integrity":"sha512-cf8FsPYShgVrJYkV5LaDNQVxtIDJDhxYfj2Vm1PK5Bgb3mltDwcUc++ZgN8fLvNvZZ23QD5aIPBdLC8THVUyBw==","signatures":[{"sig":"MEQCIFYAYnFZFd+iZANmBiUMjAWln6QuZp3wugrnm8MFwyerAiB+rrfQYn7gUyg5Ii1aK6w4/t7QCcvAECTn0GQCDWF3XQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88764},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.12.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.0.12.tgz","_integrity":"sha512-cf8FsPYShgVrJYkV5LaDNQVxtIDJDhxYfj2Vm1PK5Bgb3mltDwcUc++ZgN8fLvNvZZ23QD5aIPBdLC8THVUyBw==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.14.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/logger":"1.4.2","@bernierllc/contentful-types":"1.2.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.12_1779157167318_0.5552183826118648","host":"s3://npm-registry-packages-npm-production"}},"1.0.13":{"name":"@bernierllc/contentful-webhook-handler","version":"1.0.13","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.0.13","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"31e4448d8729efee38b651eea208d2a40a2ed4dd","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.0.13.tgz","fileCount":19,"integrity":"sha512-gbtt9TgpsKkZGKyND8msKDCUop/mYCiuHwoEpsu2HaQf+5XI/HTaKVQVZwWaD2kQCjSNJfSH7LG7on553p1hug==","signatures":[{"sig":"MEYCIQDnHP1OgKa4tjEPD/TgWHydI4frRMIZ34TsEQj+kNEbRQIhAOzdnp2MTAE1mhot1PuzSjcl7I6I4FgBWamxChNKWUd9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89013},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.0.13.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.0.13.tgz","_integrity":"sha512-gbtt9TgpsKkZGKyND8msKDCUop/mYCiuHwoEpsu2HaQf+5XI/HTaKVQVZwWaD2kQCjSNJfSH7LG7on553p1hug==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.14.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/logger":"1.4.3","@bernierllc/contentful-types":"1.2.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.0.13_1779221269665_0.25223782573887576","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bernierllc/contentful-webhook-handler","version":"1.2.0","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"832bd98d4bd968df9a61994bc1fff791787f0ea4","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.2.0.tgz","fileCount":15,"integrity":"sha512-TjIJB//MXrfnyYgdiBdZZkBwmlgl8uc5oM+kiJHt5Kzwk/e0J6pqq20CS0TsCBp+omVTV/XF3aFF/uRFbVrsGQ==","signatures":[{"sig":"MEUCICC4/jjrOiNeFka5F2JMnvO8DEOXkYJvVnC6LoxP4afNAiEAxgfUHybkYyIY6Nlqikj2MoVAq7Kb5idiG+zKrLPZu4M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55153},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.2.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.2.0.tgz","_integrity":"sha512-TjIJB//MXrfnyYgdiBdZZkBwmlgl8uc5oM+kiJHt5Kzwk/e0J6pqq20CS0TsCBp+omVTV/XF3aFF/uRFbVrsGQ==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.14.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/logger":"1.6.0","@bernierllc/contentful-types":"1.4.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.2.0_1779241066592_0.4589111861697879","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@bernierllc/contentful-webhook-handler","version":"1.3.0","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","_id":"@bernierllc/contentful-webhook-handler@1.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"4c753b9a8122787cc74d2f5c22ef35c93b8b53a0","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.3.0.tgz","fileCount":15,"integrity":"sha512-IxsC1qH7vEGJkTYudeYC6m59itJ8T6weGIc98gfScyZU4Ws+E+YWij3V28QXwj6BYgnyPeH0DrUsTyC/CHd8Ag==","signatures":[{"sig":"MEQCIHAp9CJZjklkPfV0yeWabrNyUNMRSPmLOferkoynfR0ZAiAnK/CFT8WdGtlq51GliurCZgbl88RcjdQaVtQwEkGLYA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55153},"main":"dist/index.js","_from":"file:bernierllc-contentful-webhook-handler-1.3.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest --no-watch","build":"tsc","lint:fix":"eslint src --ext .ts --fix","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.3.0.tgz","_integrity":"sha512-IxsC1qH7vEGJkTYudeYC6m59itJ8T6weGIc98gfScyZU4Ws+E+YWij3V28QXwj6BYgnyPeH0DrUsTyC/CHd8Ag==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/contentful-webhook-handler"},"_npmVersion":"11.14.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/logger":"1.7.0","@bernierllc/contentful-types":"1.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","typescript":"^5.4.2","@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/parser":"^7.3.1","@typescript-eslint/eslint-plugin":"^7.3.1"},"_npmOperationalInternal":{"tmp":"tmp/contentful-webhook-handler_1.3.0_1779249809010_0.9516175145194403","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@bernierllc/contentful-webhook-handler","version":"1.3.1","description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","main":"dist/index.js","types":"dist/index.d.ts","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/contentful-webhook-handler"},"dependencies":{"@bernierllc/contentful-types":"1.5.0","@bernierllc/logger":"1.7.1"},"devDependencies":{"@types/jest":"^29.5.12","@types/node":"^20.11.30","@typescript-eslint/eslint-plugin":"^7.3.1","@typescript-eslint/parser":"^7.3.1","eslint":"^8.57.0","jest":"^29.7.0","ts-jest":"^29.1.2","typescript":"^5.4.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","test":"jest --no-watch","test:run":"jest --no-watch","test:watch":"jest --watch","test:coverage":"jest --coverage --no-watch","lint":"eslint src --ext .ts","lint:fix":"eslint src --ext .ts --fix"},"_id":"@bernierllc/contentful-webhook-handler@1.3.1","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"homepage":"https://github.com/bernierllc/tools#readme","_integrity":"sha512-CHgDi5F3326atn4n67ukWXaHJOxYxD21PlOe4i7w7RAn/sgAHiec4EF2NS7CaduT1q5vLrdk/WTpPIbn/8mVyg==","_resolved":"/home/runner/work/tools/tools/packages/core/contentful-webhook-handler/bernierllc-contentful-webhook-handler-1.3.1.tgz","_from":"file:bernierllc-contentful-webhook-handler-1.3.1.tgz","_nodeVersion":"24.18.0","_npmVersion":"12.0.1","dist":{"integrity":"sha512-CHgDi5F3326atn4n67ukWXaHJOxYxD21PlOe4i7w7RAn/sgAHiec4EF2NS7CaduT1q5vLrdk/WTpPIbn/8mVyg==","shasum":"eedcc5f42316bd0366f4b9805c433040a2b486a0","tarball":"https://registry.npmjs.org/@bernierllc/contentful-webhook-handler/-/contentful-webhook-handler-1.3.1.tgz","fileCount":15,"unpackedSize":55153,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIApbeAXDFh5Y/7j5r6o0vb4U8hNhEzpYn05o/OhhOdpwAiEA0IOwiUPKjy4JnDAyybNwfjziaIf3JClF8iuceBX7b90="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4fa850b4-6ea6-4b8d-9b3b-98293ce465af"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/contentful-webhook-handler_1.3.1_1784015568711_0.3089766793735085"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-02T19:22:49.287Z","modified":"2026-07-14T07:52:48.972Z","1.0.3":"2025-12-02T19:22:49.578Z","1.0.4":"2025-12-02T19:26:48.323Z","1.0.5":"2025-12-22T21:10:07.129Z","1.0.6":"2025-12-23T01:47:23.801Z","1.0.8":"2026-01-05T19:47:16.101Z","1.0.9":"2026-03-09T17:47:13.042Z","1.0.10":"2026-03-10T17:18:48.906Z","1.0.11":"2026-05-18T19:43:35.916Z","1.0.12":"2026-05-19T02:19:27.494Z","1.0.13":"2026-05-19T20:07:49.806Z","1.2.0":"2026-05-20T01:37:46.747Z","1.3.0":"2026-05-20T04:03:29.161Z","1.3.1":"2026-07-14T07:52:48.847Z"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE.md","homepage":"https://github.com/bernierllc/tools#readme","keywords":["contentful","webhook","signature-validation","hmac","sha256"],"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/contentful-webhook-handler"},"description":"Validates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/contentful-webhook-handler\n\nValidates Contentful webhook signatures using HMAC-SHA256, parses webhook payloads, and provides type-safe interfaces for all webhook event types.\n\n## Features\n\n- **HMAC-SHA256 Signature Validation**: Securely verify webhook authenticity\n- **Type-Safe Payload Parsing**: Full TypeScript support for all Contentful webhook events\n- **Event Type Detection**: Extract resource type and action from webhook topics\n- **Replay Attack Prevention**: Optional timestamp validation\n- **Timing-Safe Comparison**: Prevents timing attacks during signature validation\n- **Comprehensive Error Handling**: Detailed error messages for debugging\n\n## Installation\n\n```bash\nnpm install @bernierllc/contentful-webhook-handler\n```\n\n## Usage\n\n### Basic Setup\n\n```typescript\nimport { ContentfulWebhookHandler } from '@bernierllc/contentful-webhook-handler';\n\nconst handler = new ContentfulWebhookHandler({\n  webhookSecret: process.env.CONTENTFUL_WEBHOOK_SECRET!\n});\n```\n\n### Validate and Parse Webhook\n\n```typescript\n// In your webhook endpoint handler\napp.post('/webhooks/contentful', (req, res) => {\n  const body = JSON.stringify(req.body);\n  const headers = {\n    'x-contentful-signature': req.headers['x-contentful-signature'],\n    'x-contentful-topic': req.headers['x-contentful-topic']\n  };\n\n  const result = handler.parseWebhook(body, headers);\n\n  if (!result.valid) {\n    console.error('Invalid webhook:', result.error);\n    return res.status(401).json({ error: result.error });\n  }\n\n  // Process valid webhook\n  const { payload, topic } = result;\n  console.log(`Received ${topic} for ${payload.sys.type} ${payload.sys.id}`);\n\n  res.status(200).json({ success: true });\n});\n```\n\n### Extract Event Type\n\n```typescript\nconst result = handler.parseWebhook(body, headers);\n\nif (result.valid && result.topic) {\n  const eventType = handler.getEventType(result.topic);\n\n  console.log(`Resource: ${eventType.resource}`); // 'Entry' | 'Asset' | 'ContentType'\n  console.log(`Action: ${eventType.action}`);     // 'create' | 'publish' | 'delete' | etc.\n\n  // Route based on event type\n  if (eventType.resource === 'Entry' && eventType.action === 'publish') {\n    await handleEntryPublish(result.payload);\n  }\n}\n```\n\n### Enable Replay Attack Prevention\n\n```typescript\nconst handler = new ContentfulWebhookHandler({\n  webhookSecret: process.env.CONTENTFUL_WEBHOOK_SECRET!,\n  enableTimestampValidation: true,\n  maxTimestampDeltaSeconds: 300 // 5 minutes\n});\n```\n\n### Update Webhook Secret\n\n```typescript\n// When rotating secrets\nhandler.updateSecret(newWebhookSecret);\n```\n\n## API\n\n### `ContentfulWebhookHandler`\n\n#### Constructor Options\n\n```typescript\ninterface ContentfulWebhookHandlerOptions {\n  webhookSecret: string;                // Required: Your Contentful webhook secret\n  logger?: Logger;                      // Optional: Custom logger instance\n  enableTimestampValidation?: boolean;  // Optional: Enable replay attack prevention (default: false)\n  maxTimestampDeltaSeconds?: number;    // Optional: Max timestamp age in seconds (default: 300)\n}\n```\n\n#### Methods\n\n##### `parseWebhook(body: string, headers: Partial<ContentfulWebhookHeaders>): WebhookValidationResult`\n\nValidates signature and parses webhook payload.\n\n**Parameters:**\n- `body`: Raw webhook body as string (must be unparsed JSON)\n- `headers`: Webhook headers (must include `x-contentful-signature` and `x-contentful-topic`)\n\n**Returns:**\n```typescript\ninterface WebhookValidationResult {\n  valid: boolean;                        // True if webhook is valid\n  error?: string;                        // Error message if invalid\n  payload?: ContentfulWebhookPayload;    // Parsed payload if valid\n  topic?: ContentfulWebhookTopic;        // Webhook topic if valid\n}\n```\n\n##### `validateSignature(body: string, signature: string): boolean`\n\nValidates webhook signature using HMAC-SHA256.\n\n**Parameters:**\n- `body`: Raw webhook body as string\n- `signature`: Base64-encoded signature from `x-contentful-signature` header\n\n**Returns:** `true` if signature is valid, `false` otherwise\n\n##### `getEventType(topic: ContentfulWebhookTopic): EventType`\n\nExtracts resource type and action from webhook topic.\n\n**Parameters:**\n- `topic`: Contentful webhook topic (e.g., \"Entry.publish\")\n\n**Returns:**\n```typescript\ninterface EventType {\n  resource: 'Entry' | 'Asset' | 'ContentType';\n  action: 'create' | 'save' | 'auto_save' | 'publish' | 'unpublish' | 'delete' | 'archive' | 'unarchive';\n}\n```\n\n##### `updateSecret(newSecret: string): void`\n\nUpdates the webhook secret (useful for secret rotation).\n\n**Parameters:**\n- `newSecret`: New webhook secret\n\n## Supported Webhook Topics\n\n### Entry Events\n- `Entry.create` - Entry created\n- `Entry.save` - Entry saved (draft)\n- `Entry.auto_save` - Entry auto-saved\n- `Entry.publish` - Entry published\n- `Entry.unpublish` - Entry unpublished\n- `Entry.archive` - Entry archived\n- `Entry.unarchive` - Entry unarchived\n- `Entry.delete` - Entry deleted\n\n### Asset Events\n- `Asset.create` - Asset created\n- `Asset.save` - Asset saved\n- `Asset.auto_save` - Asset auto-saved\n- `Asset.publish` - Asset published\n- `Asset.unpublish` - Asset unpublished\n- `Asset.archive` - Asset archived\n- `Asset.unarchive` - Asset unarchived\n- `Asset.delete` - Asset deleted\n\n### ContentType Events\n- `ContentType.create` - Content type created\n- `ContentType.save` - Content type saved\n- `ContentType.publish` - Content type published\n- `ContentType.unpublish` - Content type unpublished\n- `ContentType.delete` - Content type deleted\n\n## Express.js Integration Example\n\n```typescript\nimport express from 'express';\nimport { ContentfulWebhookHandler } from '@bernierllc/contentful-webhook-handler';\n\nconst app = express();\n\n// IMPORTANT: Use express.text() to preserve raw body for signature validation\napp.use('/webhooks/contentful', express.text({ type: 'application/json' }));\n\nconst handler = new ContentfulWebhookHandler({\n  webhookSecret: process.env.CONTENTFUL_WEBHOOK_SECRET!,\n  enableTimestampValidation: true\n});\n\napp.post('/webhooks/contentful', (req, res) => {\n  const result = handler.parseWebhook(req.body, {\n    'x-contentful-signature': req.headers['x-contentful-signature'] as string,\n    'x-contentful-topic': req.headers['x-contentful-topic'] as string\n  });\n\n  if (!result.valid) {\n    return res.status(401).json({ error: result.error });\n  }\n\n  // Process webhook\n  const eventType = handler.getEventType(result.topic!);\n\n  switch (eventType.resource) {\n    case 'Entry':\n      if (eventType.action === 'publish') {\n        console.log('Entry published:', result.payload!.sys.id);\n      }\n      break;\n    case 'Asset':\n      if (eventType.action === 'delete') {\n        console.log('Asset deleted:', result.payload!.sys.id);\n      }\n      break;\n  }\n\n  res.status(200).json({ success: true });\n});\n\napp.listen(3000, () => {\n  console.log('Webhook server running on port 3000');\n});\n```\n\n## Security Best Practices\n\n1. **Always validate signatures**: Never trust webhook data without signature validation\n2. **Use raw body**: Ensure you pass the unparsed JSON string to `parseWebhook()`\n3. **Enable timestamp validation**: Prevent replay attacks by validating webhook timestamps\n4. **Rotate secrets regularly**: Use `updateSecret()` to rotate your webhook secrets\n5. **Use HTTPS**: Always use HTTPS endpoints for webhooks in production\n6. **Rate limiting**: Implement rate limiting on webhook endpoints\n\n## Error Handling\n\n```typescript\nconst result = handler.parseWebhook(body, headers);\n\nif (!result.valid) {\n  switch (result.error) {\n    case 'Missing signature header (x-contentful-signature)':\n      // Handle missing signature\n      break;\n    case 'Missing topic header (x-contentful-topic)':\n      // Handle missing topic\n      break;\n    case 'Invalid signature':\n      // Handle signature validation failure\n      break;\n    case 'Invalid timestamp (possible replay attack)':\n      // Handle replay attack attempt\n      break;\n    default:\n      // Handle other errors (e.g., JSON parsing)\n      console.error('Webhook error:', result.error);\n  }\n}\n```\n\n## MECE Architecture\n\nThis package follows MECE (Mutually Exclusive, Collectively Exhaustive) principles:\n\n**Includes:**\n- HMAC-SHA256 signature validation\n- Webhook payload parsing and typing\n- Event type detection and routing\n- Header validation\n- Replay attack prevention\n\n**Excludes:**\n- ❌ Webhook receiving/HTTP server (use `@bernierllc/webhook-receiver`)\n- ❌ Webhook queueing (use `@bernierllc/message-queue`)\n- ❌ Webhook processing logic (use `@bernierllc/contentful-webhook-service`)\n\n## Integration Documentation\n\n### Logger Integration\n\nThis package integrates with `@bernierllc/logger` for structured logging of webhook validation events. The logger provides:\n\n- Structured JSON output for all validation events\n- Configurable log levels (info, warn, error)\n- Context-aware logging with service metadata\n- Optional custom logger injection via constructor\n\n```typescript\nimport { Logger } from '@bernierllc/logger';\n\nconst customLogger = new Logger({\n  service: 'my-webhook-service',\n  level: 'debug'\n});\n\nconst handler = new ContentfulWebhookHandler({\n  webhookSecret: process.env.CONTENTFUL_WEBHOOK_SECRET!,\n  logger: customLogger\n});\n```\n\nThe integration uses graceful degradation - if no custom logger is provided, a default logger instance is created automatically.\n\n### NeverHub Integration\n\nThis package is designed for NeverHub integration when used in service-layer packages like `@bernierllc/contentful-webhook-service`. While the core handler itself doesn't directly integrate with NeverHub, it provides the building blocks for NeverHub-aware webhook processing:\n\n- Type-safe webhook payloads for NeverHub event routing\n- Signature validation for secure webhook ingestion\n- Event type extraction for NeverHub event classification\n\nWhen building a service layer with NeverHub integration, use this pattern:\n\n```typescript\nimport { ContentfulWebhookHandler } from '@bernierllc/contentful-webhook-handler';\nimport { NeverHubAdapter } from '@bernierllc/neverhub-adapter';\n\nclass ContentfulWebhookService {\n  private handler: ContentfulWebhookHandler;\n  private neverhub?: NeverHubAdapter;\n\n  async initialize() {\n    this.handler = new ContentfulWebhookHandler({\n      webhookSecret: process.env.CONTENTFUL_WEBHOOK_SECRET!\n    });\n\n    // Auto-detect NeverHub\n    if (await NeverHubAdapter.detect()) {\n      this.neverhub = new NeverHubAdapter();\n      await this.neverhub.register({\n        type: 'contentful-webhook-service',\n        capabilities: ['webhook-processing', 'signature-validation']\n      });\n    }\n  }\n\n  async processWebhook(body: string, headers: any) {\n    const result = this.handler.parseWebhook(body, headers);\n\n    if (result.valid && this.neverhub) {\n      // Route validated webhooks to NeverHub\n      await this.neverhub.emit('contentful.webhook', {\n        topic: result.topic,\n        payload: result.payload\n      });\n    }\n\n    return result;\n  }\n}\n```\n\nThis architecture ensures graceful degradation - the webhook handler works with or without NeverHub, allowing for flexible deployment scenarios.\n\n## Dependencies\n\n- `@bernierllc/contentful-types` - Contentful type definitions\n- `@bernierllc/logger` - Logging utilities\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\n## Related Packages\n\n- [@bernierllc/contentful-types](../contentful-types) - Contentful TypeScript types\n- [@bernierllc/contentful-webhook-service](../../service/contentful-webhook-service) - Webhook processing service\n- [@bernierllc/webhook-receiver](../webhook-receiver) - Generic webhook receiver\n","readmeFilename":"README.md"}