Module: Axn::Webhooks
- Extended by:
- Configurable
- Defined in:
- lib/axn/webhooks.rb,
lib/axn/webhooks/errors.rb,
lib/axn/webhooks/verify.rb,
lib/axn/webhooks/handler.rb,
lib/axn/webhooks/inbound.rb,
lib/axn/webhooks/request.rb,
lib/axn/webhooks/respond.rb,
lib/axn/webhooks/version.rb,
lib/axn/webhooks/dispatch.rb,
lib/axn/webhooks/outbound.rb,
lib/axn/webhooks/response.rb,
lib/axn/webhooks/resolvers.rb,
lib/axn/webhooks/signature.rb,
lib/axn/webhooks/verifiers.rb,
lib/axn/webhooks/inbound/dsl.rb,
lib/axn/webhooks/header_value.rb,
lib/axn/webhooks/outbound/dsl.rb,
lib/axn/webhooks/vendor_facet.rb,
lib/axn/webhooks/outbound/emit.rb,
lib/axn/webhooks/inbound/router.rb,
lib/axn/webhooks/static_respond.rb,
lib/axn/webhooks/verifiers/hmac.rb,
lib/axn/webhooks/inbound/parsers.rb,
lib/axn/webhooks/outbound/config.rb,
lib/axn/webhooks/outbound/signer.rb,
lib/axn/webhooks/inbound/endpoint.rb,
lib/axn/webhooks/outbound/deliver.rb,
lib/axn/webhooks/inbound/challenge.rb,
lib/axn/webhooks/outbound/envelope.rb,
lib/axn/webhooks/outbound/transport.rb,
lib/axn/webhooks/outbound/subscriber.rb,
lib/axn/webhooks/verifiers/basic_auth.rb,
lib/axn/webhooks/inbound/build_request.rb,
lib/axn/webhooks/outbound/target_policy.rb,
lib/axn/webhooks/inbound/respond_context.rb,
lib/axn/webhooks/outbound/callable_arity.rb,
lib/axn/webhooks/inbound/challenge_required.rb,
lib/axn/webhooks/verifiers/standard_webhooks.rb
Defined Under Namespace
Modules: Handler, HeaderValue, Inbound, Outbound, Parsers, Resolvers, Signature, VendorFacet, Verifiers Classes: Dispatch, Error, InvalidTarget, Request, Resolver, Respond, Response, RetryLater, StaticRespond, UnparseableBody, Verify
Constant Summary collapse
- VERSION =
"0.1.0"
Class Method Summary collapse
-
.deprecator ⇒ Object
A dedicated deprecator instance, so a consuming Rails app can register it (Rails.application.deprecators = Axn::Webhooks.deprecator) and govern its behavior (silence in test, raise in CI, etc.).
-
.emit(event, data: {}, to: nil, async: nil) ⇒ Object
Emit an outbound webhook event.
-
.inbound(name, &block) ⇒ Object
Declare an inbound webhook endpoint.
-
.outbound(&block) ⇒ Object
Declare outbound emission.
- .retry_later!(after: nil) ⇒ Object
Class Method Details
.deprecator ⇒ Object
A dedicated deprecator instance, so a consuming Rails app can register it (Rails.application.deprecators = Axn::Webhooks.deprecator) and govern its behavior (silence in test, raise in CI, etc.).
57 58 59 |
# File 'lib/axn/webhooks.rb', line 57 def self.deprecator @deprecator ||= ActiveSupport::Deprecation.new("1.0", "axn-webhooks") end |
.emit(event, data: {}, to: nil, async: nil) ⇒ Object
Emit an outbound webhook event. Fans out one signed, self-retrying delivery per subscriber. Raises loudly (Axn::Webhooks::Error) on an unknown event.
vendor: is deliberately NOT resolved here: Config#vendor_for raises the same unknown-event
error that Emit itself already raises internally (via config.wire_type), but resolving it
ahead of call! would raise before axn's executor ever runs -- bypassing on_exception
reporting for what should be a loud, REPORTED failure (Codex P2 finding). Emit resolves its
own vendor once it's running inside that boundary.
to: and async: are per-call overrides. to: REPLACES the event's declared targets for
this call only (never merges) — the event must still be declared, since it supplies the wire
type and vendor. async: true requires a configured adapter and raises without one;
async: false forces the inline path. Omitted means today's :auto.
rubocop:disable-next Naming/MethodParameterName
69 70 71 |
# File 'lib/axn/webhooks/outbound.rb', line 69 def self.emit(event, data: {}, to: nil, async: nil) Outbound::Emit.call!(event:, data:, to:, async:) end |
.inbound(name, &block) ⇒ Object
Declare an inbound webhook endpoint. Evaluated at boot (e.g. a Rails initializer) so registration is deterministic, in or out of Rails.
With one or more nested endpoint blocks, this registers one endpoint per child, named
:"#name_#child", and does NOT register name itself — see Inbound::DSL#endpoint.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/axn/webhooks/inbound.rb', line 79 def self.inbound(name, &block) raise ArgumentError, "Axn::Webhooks.inbound requires a block" unless block dsl = Inbound::DSL.new dsl.instance_exec(&block) children = dsl.__children__ return Inbound.replace_declaration(name, { name.to_sym => build_endpoint(name, dsl) }) if children.empty? # A parent with children is a container, not an endpoint. A top-level `dispatch` is what # would make it look like one, and registering both it and the children would leave an extra # endpoint nobody mounted, silently — so that combination is a declaration mistake, caught at # boot. A parent `respond`/`static_respond` is NOT: it renders nothing on its own, and # sharing one renderer across a vendor's endpoints is precisely what nesting is for, so it # inherits like every other declaration (Codex review). if dsl.__dispatch_declared? raise ArgumentError, "inbound #{name.inspect} declares `endpoint` blocks AND its own `dispatch` — a parent " \ "with endpoints registers nothing itself; move the dispatch into an endpoint" end # Build and validate EVERY child before publishing any: the registry is process-global, so # registering as we go left earlier children live when a later one raised — a rescued # declaration failure or a reload would mix endpoints from different declarations # (Codex review). built = children.map { |child, child_block| [:"#{name}_#{child}", build_endpoint(:"#{name}_#{child}", dsl.__child_dsl__(child_block))] } Inbound.replace_declaration(name, built.to_h) end |
.outbound(&block) ⇒ Object
Declare outbound emission. Evaluated at boot (e.g. a Rails initializer).
47 48 49 50 51 52 53 |
# File 'lib/axn/webhooks/outbound.rb', line 47 def self.outbound(&block) raise ArgumentError, "Axn::Webhooks.outbound requires a block" unless block dsl = Outbound::DSL.new dsl.instance_exec(&block) Outbound.install(dsl.__config__) end |
.retry_later!(after: nil) ⇒ Object
44 45 46 |
# File 'lib/axn/webhooks/errors.rb', line 44 def self.retry_later!(after: nil) raise RetryLater.new(retry_after: after) end |