Sloane F. 판매

Hook-Engine is a production-ready webhook processing library supporting 7 providers (Stripe, GitHub, Shopify, and more) with signature verification, structured logging, rate limiting, circuit breakers, and CLI tooling.
Hook-Engine is a TypeScript library for receiving, verifying, and processing webhooks from providers such as Stripe, GitHub, Discord, Shopify, PayPal, Twilio, and SendGrid. It ships with signature verification, retry logic, rate limiting, circuit breakers, structured logging, and a CLI. The typical buyer is a Node.js/Express backend developer who needs production-grade webhook handling without building all supporting infrastructure from scratch.
adapters/ - Per-provider webhook adapters (signature verification, normalization)cli/ - CLI commands: test, init, migrate, monitor, benchmark, validateconfig/ - Configuration loading, defaults, and template presetscore/ - Engine, receiver, retry, router, idempotency, multi-tenant, reliabilityerrors/ - Typed error classes and a global error handlerobservability/ - Structured logger and base logger instanceplugins/ - Express plugin integration helpersecurity/ - Security manager with rate limiting and request validationstorage/ - Storage adapters (memory, SQLite) for idempotency and statetypes/ - All TypeScript interface and type definitionsutils/ - Timer, sleep, backoff, and timeout utilitiesindex.ts - Main barrel export for the entire librarynpm install better-sqlite3 commander dotenv express node-fetch uuid
npm install --save-dev @types/better-sqlite3 @types/express @types/node
better-sqlite3 compiles a native addon. If the build fails, ensure you have Python and a C++ compiler available:
# On Debian/Ubuntu
sudo apt-get install python3 build-essential
# On macOS (Xcode CLI tools)
xcode-select --install
After installing on a machine without a matching pre-built binary, run:
npm rebuild better-sqlite3
Copy the source/ directory into your project, e.g. as src/hook-engine/.
In tsconfig.json, ensure moduleResolution is node or bundler and is enabled:
격리된 샌드박스를 띄워 서버에서 바로 실행하세요 — 로컬 설정 불필요.
이 버전에 대한 Tetrees AI Review
This TypeScript cli / script completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
파이프라인 avcp-2026-08-04.1 · SHA-256 11f7076420f3fe2b…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
검토일 2026년 8월 4일
이 제품을 AI IDE, 웹 빌더 또는 클라우드 IDE로 바로 가져오세요.
Tetrees를 호환 AI IDE에 연결해 보유 제품을 불러오고, 판매자 업로드 권한을 노출하지 않은 채 검증된 ZIP을 받으세요.
아직 리뷰가 없습니다.
토론을 불러오는 중…
esModuleInterop{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"hook-engine": ["src/hook-engine/index.ts"],
"hook-engine/*": ["src/hook-engine/*"]
}
}
}
.env:STRIPE_WEBHOOK_SECRET=whsec_...
GITHUB_WEBHOOK_SECRET=ghwhs_...
SHOPIFY_WEBHOOK_SECRET=shpwhs_...
DISCORD_PUBLIC_KEY=...
DATABASE_PATH=./webhooks.db # optional, for SQLite storage
LOG_LEVEL=info
import 'dotenv/config';
app.use('/webhooks', express.raw({ type: 'application/json' }));
receiveWebhookfunction receiveWebhook(
req: IncomingMessage,
options: { source: string; secret?: string; [key: string]: unknown }
): Promise<WebhookEvent>
The primary entry point. Parses the raw request body, selects the matching adapter by source, verifies the provider signature using secret, and returns a normalized WebhookEvent. Throws a typed webhook error on verification failure or unknown provider.
HookEngineclass HookEngine {
constructor(config?: Partial<HookEngineConfig>): HookEngine
}
The central orchestrator. Wraps the receiver, retry engine, reliability manager, and security manager into one configured instance. Use this when you need coordinated retry logic, circuit breaking, and observability rather than calling receiveWebhook directly.
loadConfigfunction loadConfig(userConfig?: Partial<HookEngineConfig>): HookEngineConfig
Deep-merges user-supplied config over the built-in defaults (retry, security, observability, storage). Validates the result and throws if the configuration is invalid. Call once at startup and pass the result to HookEngine.
StructuredLoggerclass StructuredLogger {
info(message: string, meta?: Record<string, unknown>): void
warn(message: string, meta?: Record<string, unknown>): void
error(message: string, meta?: Record<string, unknown>): void
}
Emits JSON-structured log lines. Use when you need to attach correlation IDs, webhook IDs, or tenant context to every log statement and ship them to a log aggregator.
SecurityManagerclass SecurityManager { /* rate limiting, request validation */ }
class MemoryRateLimitStore { /* in-process rate limit state */ }
Wraps incoming requests with rate limiting and request-level security checks before the webhook adapter runs. Pair with MemoryRateLimitStore for single-process deployments or supply a custom store for Redis-backed multi-process deployments.
getAdapterfunction getAdapter(source: string): WebhookAdapter | undefined
Returns the named adapter or undefined if the provider is not registered. Useful for inspecting which providers are available or building a custom routing layer.
A minimal route that verifies a Stripe webhook signature and acts on the event type.
import 'dotenv/config';
import express from 'express';
import { receiveWebhook } from './hook-engine/index';
const app = express();
app.use('/webhooks', express.raw({ type: 'application/json' }));
app.post('/webhooks/stripe', async (req, res) => {
try {
const event = await receiveWebhook(req, {
source: 'stripe',
secret: process.env.STRIPE_WEBHOOK_SECRET,
});
switch (event.type) {
case 'invoice.payment_succeeded':
console.log('Payment succeeded', event.id);
break;
case 'customer.subscription.deleted':
console.log('Subscription cancelled', event.id);
break;
}
res.status(200).json({ received: true });
} catch (err) {
console.error('Webhook error:', (err as Error).message);
res.status(400).json({ error: 'Verification failed' });
}
});
app.listen(3000);
Handle Stripe, GitHub, and Shopify from a single endpoint using the engine and validated config.
import 'dotenv/config';
import express from 'express';
import { HookEngine, loadConfig, receiveWebhook } from './hook-engine/index';
const config = loadConfig({
retry: { maxAttempts: 3, baseDelay: 500 },
observability: { logLevel: 'info' },
});
const engine = new HookEngine(config);
const app = express();
app.use('/webhooks', express.raw({ type: 'application/json' }));
const secrets: Record<string, string | undefined> = {
stripe: process.env.STRIPE_WEBHOOK_SECRET,
github: process.env.GITHUB_WEBHOOK_SECRET,
shopify: process.env.SHOPIFY_WEBHOOK_SECRET,
};
app.post('/webhooks/:provider', async (req, res) => {
const provider = req.params.provider;
const secret = secrets[provider];
if (!secret) {
return res.status(400).json({ error: 'Unknown provider' });
}
try {
const event = await receiveWebhook(req, { source: provider, secret });
console.log(`[${provider}] Event received:`, event.type, event.id);
res.status(200).json({ ok: true });
} catch (err) {
console.error(`[${provider}] Failed:`, (err as Error).message);
res.status(400).json({ error: 'Processing failed' });
}
});
app.listen(4000);
Attach a webhook event ID to every log line using StructuredLogger.
import { StructuredLogger, receiveWebhook } from './hook-engine/index';
import type { IncomingMessage, ServerResponse } from 'http';
const log = new StructuredLogger();
async function handleWebhook(req: IncomingMessage, res: ServerResponse) {
let eventId = 'unknown';
try {
const event = await receiveWebhook(req, {
source: 'github',
secret: process.env.GITHUB_WEBHOOK_SECRET,
});
eventId = event.id;
log.info('Webhook received', { eventId, type: event.type, source: 'github' });
// business logic ...
log.info('Webhook processed', { eventId, durationMs: 42 });
res.writeHead(200);
res.end(JSON.stringify({ ok: true }));
} catch (err) {
log.error('Webhook failed', { eventId, error: (err as Error).message });
res.writeHead(400);
res.end(JSON.stringify({ error: 'Failed' }));
}
}
index.ts - Barrel export; re-exports all public symbols from every sub-module.adapters/ - One file per provider. Each exports a WebhookAdapter with verify and parse logic. index.ts registers all adapters in the adapters map and exports getAdapter.adapters/base-advanced.ts - Abstract base class for adapters that need richer event normalization.adapters/github-advanced.ts - GitHub adapter extending BaseAdvancedAdapter with extra event metadata.cli/ - Commander-based CLI. index.ts wires sub-commands; commands/ holds individual command implementations (test, init, migrate, monitor, benchmark, validate).config/ - defaults.ts holds the base config object; validation.ts enforces constraints; template files export preset config objects for common deployment profiles.core/engine.ts - Top-level HookEngine class; composes all sub-systems.core/receiver.ts - Exports receiveWebhook; handles raw body extraction, adapter dispatch, and error wrapping.core/retry.ts - RetryEngine with exponential backoff and jitter.core/idempotency.ts - isDuplicate check backed by the configured storage adapter.core/multi-tenant-handler.ts - MultiTenantHandler routes events by tenant context.core/reliability-manager.ts - ReliabilityManager wraps circuit-breaker and health probe logic.core/event-processor.ts - EventProcessor applies middleware-style transforms to normalized events.core/router.ts - Internal routing table mapping event types to handler functions.errors/ - base.ts defines the root error class; webhook-errors.ts has provider-specific errors; error-handler.ts exports ErrorHandler, initializeErrorHandler, and getGlobalErrorHandler.observability/logger.ts - Singleton logger instance ready for import.observability/structured-logger.ts - StructuredLogger class with JSON output and configurable transports.plugins/express.ts - Express middleware factory that wires receiveWebhook into the request lifecycle.security/crypto.ts - Low-level HMAC, Ed25519, and ECDSA helpers used by adapters.security/security-manager.ts - SecurityManager and MemoryRateLimitStore.storage/ - index.ts exports createStorageAdapter; memory.ts and sqlite.ts are the two built-in backends.types/ - Pure TypeScript interfaces: WebhookAdapter, HookEngineConfig, WebhookEvent, storage, security, reliability, logging, and error types.utils/timing.ts - Timer, sleep, calculateBackoffDelay, withTimeout.express.raw({ type: 'application/json' }) before express.json() on webhook routes; express.json() replaces req.body with a parsed object and discards the buffer.better-sqlite3 native build failure on CI - Pin to a Node.js version that has a pre-built binary in the better-sqlite3 release assets, or add npm rebuild better-sqlite3 to your CI build step.node-fetch - node-fetch v3 is ESM-only. The CLI dynamically imports it (await import('node-fetch')). If you bundle with esbuild or Webpack, ensure your bundler handles dynamic ESM imports or pin node-fetch to ^2.secret is undefined, some adapters skip verification rather than throwing. Always assert that process.env.YOUR_SECRET is defined before passing it to receiveWebhook.DATABASE_PATH directory must be writable by the process user; mount a volume or chown the directory in your Dockerfile.tsconfig paths only affect the compiler. Add tsconfig-paths or configure your bundler's alias map so hook-engine resolves to src/hook-engine/index.ts at runtime in development.I have a Node.js/TypeScript Express project and I have dropped the Hook-Engine
source library into `src/hook-engine/` (upstream package: user@example.com).
A USAGE.md file is in the same directory describing all exports and setup steps.
Please help me integrate Hook-Engine into my project step by step:
1. Read `src/hook-engine/index.ts` to understand all available exports.
2. Read USAGE.md for setup instructions, working examples, and pitfalls.
3. Add the required npm dependencies listed in USAGE.md § "Required dependencies".
4. Update `tsconfig.json` with the path alias so `hook-engine` resolves to
`src/hook-engine/index.ts`.
5. Create a webhook route file using `receiveWebhook` from `src/hook-engine/index`
that handles [PROVIDER] events with signature verification.
6. Wire `HookEngine` with `loadConfig` so retry and reliability settings come
from environment variables.
7. Add `StructuredLogger` to emit JSON logs with a `webhookId` field on every
log line inside the webhook handler.
8. Point out any issues with raw body parsing, missing secrets, or ESM interop
that could cause verification failures.
My entry file is [src/index.ts]. My webhook secret is stored in [ENV_VAR_NAME].
The providers I need to support are: [stripe, github, ...].
The upstream library does not include an explicit LICENSE file in the distributed package; see source/LICENSE if present in this block, or contact the upstream author. The source is published as user@example.com on npm.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
전체 설치 가이드와 연동 프롬프트는 구매 후 열람할 수 있습니다.
Automation, Utilities & Developer Tools
무료