@dudousxd/nestjs-notifications-webhook 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +41 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +41 -7
- package/dist/index.js.map +1 -1
- package/package.json +11 -2
package/dist/index.cjs
CHANGED
|
@@ -104,13 +104,22 @@ var WEBHOOK_OPTIONS_RESOLVER = /* @__PURE__ */ Symbol("WEBHOOK_OPTIONS_RESOLVER"
|
|
|
104
104
|
// src/webhook.channel.ts
|
|
105
105
|
function _ts_decorate(decorators, target, key, desc) {
|
|
106
106
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
107
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
108
|
-
|
|
107
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
108
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
109
|
+
} else {
|
|
110
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
111
|
+
if (d = decorators[i]) {
|
|
112
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
109
116
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
110
117
|
}
|
|
111
118
|
__name(_ts_decorate, "_ts_decorate");
|
|
112
|
-
function _ts_metadata(
|
|
113
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
119
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
120
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
121
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
122
|
+
}
|
|
114
123
|
}
|
|
115
124
|
__name(_ts_metadata, "_ts_metadata");
|
|
116
125
|
function _ts_param(paramIndex, decorator) {
|
|
@@ -152,7 +161,13 @@ var WebhookChannel = class extends import_nestjs_notifications_core.BaseChannel
|
|
|
152
161
|
await (0, import_nestjs_notifications_core.postJson)(url, request.body, {
|
|
153
162
|
label: "Webhook",
|
|
154
163
|
method: request.method,
|
|
155
|
-
headers
|
|
164
|
+
headers,
|
|
165
|
+
...options.timeoutMs !== void 0 ? {
|
|
166
|
+
timeoutMs: options.timeoutMs
|
|
167
|
+
} : {},
|
|
168
|
+
...options.redirect !== void 0 ? {
|
|
169
|
+
redirect: options.redirect
|
|
170
|
+
} : {}
|
|
156
171
|
});
|
|
157
172
|
}
|
|
158
173
|
};
|
|
@@ -173,8 +188,15 @@ var import_nestjs_notifications_core2 = require("@dudousxd/nestjs-notifications-
|
|
|
173
188
|
var import_common2 = require("@nestjs/common");
|
|
174
189
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
175
190
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
176
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
177
|
-
|
|
191
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
192
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
193
|
+
} else {
|
|
194
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
195
|
+
if (d = decorators[i]) {
|
|
196
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
178
200
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
179
201
|
}
|
|
180
202
|
__name(_ts_decorate2, "_ts_decorate");
|
|
@@ -191,6 +213,18 @@ var WebhookChannelModule = class _WebhookChannelModule {
|
|
|
191
213
|
} : {},
|
|
192
214
|
...options.headers !== void 0 ? {
|
|
193
215
|
headers: options.headers
|
|
216
|
+
} : {},
|
|
217
|
+
...options.secret !== void 0 ? {
|
|
218
|
+
secret: options.secret
|
|
219
|
+
} : {},
|
|
220
|
+
...options.signatureHeader !== void 0 ? {
|
|
221
|
+
signatureHeader: options.signatureHeader
|
|
222
|
+
} : {},
|
|
223
|
+
...options.timeoutMs !== void 0 ? {
|
|
224
|
+
timeoutMs: options.timeoutMs
|
|
225
|
+
} : {},
|
|
226
|
+
...options.redirect !== void 0 ? {
|
|
227
|
+
redirect: options.redirect
|
|
194
228
|
} : {}
|
|
195
229
|
};
|
|
196
230
|
return (0, import_nestjs_notifications_core2.defineChannelModule)({
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/webhook-message.ts","../src/webhook.channel.ts","../src/tokens.ts","../src/webhook.module.ts"],"sourcesContent":["export {\n WebhookMessage,\n type WebhookMethod,\n type WebhookRequest,\n} from './webhook-message';\nexport {\n Webhook,\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookNotification,\n type WebhookOptionsResolver,\n} from './webhook.channel';\nexport {\n WebhookChannelModule,\n type WebhookChannelModuleOptions,\n} from './webhook.module';\nexport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\n","/** The HTTP method used for a webhook request. */\nexport type WebhookMethod = 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'GET';\n\n/** The resolved request description produced by {@link WebhookMessage.toRequest}. */\nexport interface WebhookRequest {\n /** Target URL, when set on the message; otherwise resolved by the channel. */\n url?: string | undefined;\n method: WebhookMethod;\n headers: Record<string, string>;\n /** The JSON body to send (a plain object). */\n body: Record<string, unknown>;\n}\n\n/**\n * A fluent builder for a webhook request.\n *\n * ```ts\n * new WebhookMessage()\n * .url('https://example.com/hooks/orders')\n * .header('X-Signature', sign(payload))\n * .payload({ event: 'order.paid', id: 42 });\n * ```\n */\nexport class WebhookMessage {\n private _url?: string;\n private _method: WebhookMethod = 'POST';\n private _headers: Record<string, string> = {};\n private _payload: Record<string, unknown> = {};\n\n /** Set the target URL (overrides the route and configured default). */\n url(u: string): this {\n this._url = u;\n return this;\n }\n\n /** Set the JSON body to send. */\n payload(obj: Record<string, unknown>): this {\n this._payload = obj;\n return this;\n }\n\n /** Set a single request header. */\n header(key: string, value: string): this {\n this._headers[key] = value;\n return this;\n }\n\n /** Merge multiple request headers. */\n headers(obj: Record<string, string>): this {\n this._headers = { ...this._headers, ...obj };\n return this;\n }\n\n /** Set the HTTP method (default `POST`). */\n method(m: WebhookMethod): this {\n this._method = m;\n return this;\n }\n\n get urlValue(): string | undefined {\n return this._url;\n }\n\n get methodValue(): WebhookMethod {\n return this._method;\n }\n\n get headerValues(): Record<string, string> {\n return this._headers;\n }\n\n get payloadValue(): Record<string, unknown> {\n return this._payload;\n }\n\n /** Serialize to a {@link WebhookRequest}. */\n toRequest(): WebhookRequest {\n return {\n url: this._url,\n method: this._method,\n headers: { ...this._headers },\n body: this._payload,\n };\n }\n}\n","import { createHmac } from 'node:crypto';\nimport {\n BaseChannel,\n type ChannelContext,\n type DeliveryContext,\n type Notifiable,\n type Notification,\n createChannel,\n postJson,\n routeFor,\n} from '@dudousxd/nestjs-notifications-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport { WebhookMessage } from './webhook-message';\n\nconst DEFAULT_SIGNATURE_HEADER = 'X-Signature-256';\n\n/** Channel handle: use as `@Webhook()` on a payload method, or as a token in `via()`. */\nexport const Webhook = createChannel('webhook');\n\n/** Resolved runtime options for the webhook channel. */\nexport interface WebhookChannelOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 secret. When set, the request is signed: the header (default\n * `X-Signature-256`) is set to `sha256=<hex digest of the raw JSON body>`, so the receiver\n * can verify authenticity. Per-tenant secrets work via `resolveOptions`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n}\n\n/**\n * Implement this on a notification to define its webhook payload. Returning a plain\n * object is treated as the JSON body to POST; return a {@link WebhookMessage} for full\n * control over the url, method and headers.\n */\nexport interface WebhookNotification extends Notification {\n toWebhook(ctx: ChannelContext): WebhookMessage | Record<string, unknown>;\n}\n\n/** Resolves per-tenant {@link WebhookChannelOptions} from a tenant id. */\nexport type WebhookOptionsResolver = (tenant: string) => WebhookChannelOptions;\n\n/**\n * Delivers a notification by sending an HTTP request (JSON body) to a webhook endpoint.\n * The target URL comes from the {@link WebhookMessage}, else from\n * `routeNotificationFor('webhook')` (a URL string), else from the configured default.\n */\n@Injectable()\nexport class WebhookChannel extends BaseChannel {\n readonly channel = 'webhook';\n\n constructor(\n @Inject(WEBHOOK_OPTIONS)\n private readonly options: WebhookChannelOptions,\n @Optional()\n @Inject(WEBHOOK_OPTIONS_RESOLVER)\n private readonly resolveOptions?: WebhookOptionsResolver,\n ) {\n super();\n }\n\n async send(\n notifiable: Notifiable,\n notification: Notification,\n context?: DeliveryContext,\n ): Promise<void> {\n const options = this.forTenant(this.options, context, this.resolveOptions);\n const result = this.buildPayload<WebhookMessage | Record<string, unknown>>(\n notification,\n notifiable,\n 'toWebhook',\n context,\n );\n const message =\n result instanceof WebhookMessage ? result : new WebhookMessage().payload(result);\n const request = message.toRequest();\n\n const route = routeFor(notifiable, 'webhook', notification);\n const url = request.url ?? (typeof route === 'string' ? route : undefined) ?? options.url;\n\n if (!url) {\n throw new Error(\n 'The webhook channel needs a target URL. Set one on the WebhookMessage via .url(), ' +\n 'return one from routeNotificationFor(\"webhook\"), or set url in forRoot().',\n );\n }\n\n const headers: Record<string, string> = { ...options.headers, ...request.headers };\n if (options.secret) {\n const signature = createHmac('sha256', options.secret)\n .update(JSON.stringify(request.body))\n .digest('hex');\n headers[options.signatureHeader ?? DEFAULT_SIGNATURE_HEADER] = `sha256=${signature}`;\n }\n\n await postJson(url, request.body, { label: 'Webhook', method: request.method, headers });\n }\n}\n","/** DI token for the resolved {@link WebhookChannelOptions} (default url, headers). */\nexport const WEBHOOK_OPTIONS = Symbol('WEBHOOK_OPTIONS');\n\n/** DI token for the optional per-tenant {@link WebhookChannelOptions} resolver. */\nexport const WEBHOOK_OPTIONS_RESOLVER = Symbol('WEBHOOK_OPTIONS_RESOLVER');\n","import { defineChannelModule } from '@dudousxd/nestjs-notifications-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport {\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookOptionsResolver,\n} from './webhook.channel';\n\nexport interface WebhookChannelModuleOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * Optional per-tenant options resolver. When a notification is delivered with a\n * `context.tenant`, the returned options are used instead of the defaults.\n */\n resolveOptions?: WebhookOptionsResolver;\n /** Register globally so the channel is discoverable app-wide. Default true. */\n global?: boolean;\n}\n\n/**\n * Registers the webhook channel.\n *\n * ```ts\n * WebhookChannelModule.forRoot({ url: 'https://example.com/hooks/notifications' });\n * ```\n */\n@Module({})\nexport class WebhookChannelModule {\n static forRoot(options: WebhookChannelModuleOptions = {}): DynamicModule {\n const webhookOptions: WebhookChannelOptions = {\n // Set each field only when provided (exactOptionalPropertyTypes); the channel resolves a\n // per-notifiable URL and default headers when these are absent.\n ...(options.url !== undefined ? { url: options.url } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n };\n\n return defineChannelModule({\n module: WebhookChannelModule,\n channel: WebhookChannel,\n optionsToken: WEBHOOK_OPTIONS,\n options: webhookOptions,\n resolver: { token: WEBHOOK_OPTIONS_RESOLVER, value: options.resolveOptions },\n ...(options.global !== undefined ? { global: options.global } : {}),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;ACuBO,IAAMA,iBAAN,MAAMA;EAvBb,OAuBaA;;;EACHC;EACAC,UAAyB;EACzBC,WAAmC,CAAC;EACpCC,WAAoC,CAAC;;EAG7CC,IAAIC,GAAiB;AACnB,SAAKL,OAAOK;AACZ,WAAO;EACT;;EAGAC,QAAQC,KAAoC;AAC1C,SAAKJ,WAAWI;AAChB,WAAO;EACT;;EAGAC,OAAOC,KAAaC,OAAqB;AACvC,SAAKR,SAASO,GAAAA,IAAOC;AACrB,WAAO;EACT;;EAGAC,QAAQJ,KAAmC;AACzC,SAAKL,WAAW;MAAE,GAAG,KAAKA;MAAU,GAAGK;IAAI;AAC3C,WAAO;EACT;;EAGAK,OAAOC,GAAwB;AAC7B,SAAKZ,UAAUY;AACf,WAAO;EACT;EAEA,IAAIC,WAA+B;AACjC,WAAO,KAAKd;EACd;EAEA,IAAIe,cAA6B;AAC/B,WAAO,KAAKd;EACd;EAEA,IAAIe,eAAuC;AACzC,WAAO,KAAKd;EACd;EAEA,IAAIe,eAAwC;AAC1C,WAAO,KAAKd;EACd;;EAGAe,YAA4B;AAC1B,WAAO;MACLd,KAAK,KAAKJ;MACVY,QAAQ,KAAKX;MACbU,SAAS;QAAE,GAAG,KAAKT;MAAS;MAC5BiB,MAAM,KAAKhB;IACb;EACF;AACF;;;ACpFA,yBAA2B;AAC3B,uCASO;AACP,oBAA6C;;;ACVtC,IAAMiB,kBAAkBC,uBAAO,iBAAA;AAG/B,IAAMC,2BAA2BD,uBAAO,0BAAA;;;;;;;;;;;;;;;;;;;;ADW/C,IAAME,2BAA2B;AAG1B,IAAMC,cAAUC,gDAAc,SAAA;AAoC9B,IAAMC,iBAAN,cAA6BC,6CAAAA;SAAAA;;;;;EACzBC,UAAU;EAEnB,YAEmBC,SAGAC,gBACjB;AACA,UAAK,GAAA,KALYD,UAAAA,SAAAA,KAGAC,iBAAAA;EAGnB;EAEA,MAAMC,KACJC,YACAC,cACAC,SACe;AACf,UAAML,UAAU,KAAKM,UAAU,KAAKN,SAASK,SAAS,KAAKJ,cAAc;AACzE,UAAMM,SAAS,KAAKC,aAClBJ,cACAD,YACA,aACAE,OAAAA;AAEF,UAAMI,UACJF,kBAAkBG,iBAAiBH,SAAS,IAAIG,eAAAA,EAAiBC,QAAQJ,MAAAA;AAC3E,UAAMK,UAAUH,QAAQI,UAAS;AAEjC,UAAMC,YAAQC,2CAASZ,YAAY,WAAWC,YAAAA;AAC9C,UAAMY,MAAMJ,QAAQI,QAAQ,OAAOF,UAAU,WAAWA,QAAQG,WAAcjB,QAAQgB;AAEtF,QAAI,CAACA,KAAK;AACR,YAAM,IAAIE,MACR,6JACE;IAEN;AAEA,UAAMC,UAAkC;MAAE,GAAGnB,QAAQmB;MAAS,GAAGP,QAAQO;IAAQ;AACjF,QAAInB,QAAQoB,QAAQ;AAClB,YAAMC,gBAAYC,+BAAW,UAAUtB,QAAQoB,MAAM,EAClDG,OAAOC,KAAKC,UAAUb,QAAQc,IAAI,CAAA,EAClCC,OAAO,KAAA;AACVR,cAAQnB,QAAQ4B,mBAAmBlC,wBAAAA,IAA4B,UAAU2B,SAAAA;IAC3E;AAEA,cAAMQ,2CAASb,KAAKJ,QAAQc,MAAM;MAAEI,OAAO;MAAWC,QAAQnB,QAAQmB;MAAQZ;IAAQ,CAAA;EACxF;AACF;;;;;;;;;;;;;;AEvGA,IAAAa,oCAAoC;AACpC,IAAAC,iBAA2C;;;;;;;;AA8BpC,IAAMC,uBAAN,MAAMA,sBAAAA;SAAAA;;;EACX,OAAOC,QAAQC,UAAuC,CAAC,GAAkB;AACvE,UAAMC,iBAAwC;;;MAG5C,GAAID,QAAQE,QAAQC,SAAY;QAAED,KAAKF,QAAQE;MAAI,IAAI,CAAC;MACxD,GAAIF,QAAQI,YAAYD,SAAY;QAAEC,SAASJ,QAAQI;MAAQ,IAAI,CAAC;IACtE;AAEA,eAAOC,uDAAoB;MACzBC,QAAQR;MACRS,SAASC;MACTC,cAAcC;MACdV,SAASC;MACTU,UAAU;QAAEC,OAAOC;QAA0BC,OAAOd,QAAQe;MAAe;MAC3E,GAAIf,QAAQgB,WAAWb,SAAY;QAAEa,QAAQhB,QAAQgB;MAAO,IAAI,CAAC;IACnE,CAAA;EACF;AACF;;;;","names":["WebhookMessage","_url","_method","_headers","_payload","url","u","payload","obj","header","key","value","headers","method","m","urlValue","methodValue","headerValues","payloadValue","toRequest","body","WEBHOOK_OPTIONS","Symbol","WEBHOOK_OPTIONS_RESOLVER","DEFAULT_SIGNATURE_HEADER","Webhook","createChannel","WebhookChannel","BaseChannel","channel","options","resolveOptions","send","notifiable","notification","context","forTenant","result","buildPayload","message","WebhookMessage","payload","request","toRequest","route","routeFor","url","undefined","Error","headers","secret","signature","createHmac","update","JSON","stringify","body","digest","signatureHeader","postJson","label","method","import_nestjs_notifications_core","import_common","WebhookChannelModule","forRoot","options","webhookOptions","url","undefined","headers","defineChannelModule","module","channel","WebhookChannel","optionsToken","WEBHOOK_OPTIONS","resolver","token","WEBHOOK_OPTIONS_RESOLVER","value","resolveOptions","global"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/webhook-message.ts","../src/webhook.channel.ts","../src/tokens.ts","../src/webhook.module.ts"],"sourcesContent":["export {\n WebhookMessage,\n type WebhookMethod,\n type WebhookRequest,\n} from './webhook-message';\nexport {\n Webhook,\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookNotification,\n type WebhookOptionsResolver,\n} from './webhook.channel';\nexport {\n WebhookChannelModule,\n type WebhookChannelModuleOptions,\n} from './webhook.module';\nexport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\n","/** The HTTP method used for a webhook request. */\nexport type WebhookMethod = 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'GET';\n\n/** The resolved request description produced by {@link WebhookMessage.toRequest}. */\nexport interface WebhookRequest {\n /** Target URL, when set on the message; otherwise resolved by the channel. */\n url?: string | undefined;\n method: WebhookMethod;\n headers: Record<string, string>;\n /** The JSON body to send (a plain object). */\n body: Record<string, unknown>;\n}\n\n/**\n * A fluent builder for a webhook request.\n *\n * ```ts\n * new WebhookMessage()\n * .url('https://example.com/hooks/orders')\n * .header('X-Signature', sign(payload))\n * .payload({ event: 'order.paid', id: 42 });\n * ```\n */\nexport class WebhookMessage {\n private _url?: string;\n private _method: WebhookMethod = 'POST';\n private _headers: Record<string, string> = {};\n private _payload: Record<string, unknown> = {};\n\n /** Set the target URL (overrides the route and configured default). */\n url(u: string): this {\n this._url = u;\n return this;\n }\n\n /** Set the JSON body to send. */\n payload(obj: Record<string, unknown>): this {\n this._payload = obj;\n return this;\n }\n\n /** Set a single request header. */\n header(key: string, value: string): this {\n this._headers[key] = value;\n return this;\n }\n\n /** Merge multiple request headers. */\n headers(obj: Record<string, string>): this {\n this._headers = { ...this._headers, ...obj };\n return this;\n }\n\n /** Set the HTTP method (default `POST`). */\n method(m: WebhookMethod): this {\n this._method = m;\n return this;\n }\n\n get urlValue(): string | undefined {\n return this._url;\n }\n\n get methodValue(): WebhookMethod {\n return this._method;\n }\n\n get headerValues(): Record<string, string> {\n return this._headers;\n }\n\n get payloadValue(): Record<string, unknown> {\n return this._payload;\n }\n\n /** Serialize to a {@link WebhookRequest}. */\n toRequest(): WebhookRequest {\n return {\n url: this._url,\n method: this._method,\n headers: { ...this._headers },\n body: this._payload,\n };\n }\n}\n","import { createHmac } from 'node:crypto';\nimport {\n BaseChannel,\n type ChannelContext,\n type DeliveryContext,\n type Notifiable,\n type Notification,\n createChannel,\n postJson,\n routeFor,\n} from '@dudousxd/nestjs-notifications-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport { WebhookMessage } from './webhook-message';\n\nconst DEFAULT_SIGNATURE_HEADER = 'X-Signature-256';\n\n/** Channel handle: use as `@Webhook()` on a payload method, or as a token in `via()`. */\nexport const Webhook = createChannel('webhook');\n\n/** Resolved runtime options for the webhook channel. */\nexport interface WebhookChannelOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 secret. When set, the request is signed: the header (default\n * `X-Signature-256`) is set to `sha256=<hex digest of the raw JSON body>`, so the receiver\n * can verify authenticity. Per-tenant secrets work via `resolveOptions`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n /** Abort a request that takes longer than this (ms). Unset = no timeout. */\n timeoutMs?: number;\n /**\n * Redirect handling. Default `'follow'` (the `fetch` default). Use `'error'` when webhook URLs\n * are user-supplied, so a 3xx can't bounce the (possibly signed) request somewhere else.\n */\n redirect?: 'follow' | 'error' | 'manual';\n}\n\n/**\n * Implement this on a notification to define its webhook payload. Returning a plain\n * object is treated as the JSON body to POST; return a {@link WebhookMessage} for full\n * control over the url, method and headers.\n */\nexport interface WebhookNotification extends Notification {\n toWebhook(ctx: ChannelContext): WebhookMessage | Record<string, unknown>;\n}\n\n/** Resolves per-tenant {@link WebhookChannelOptions} from a tenant id. */\nexport type WebhookOptionsResolver = (tenant: string) => WebhookChannelOptions;\n\n/**\n * Delivers a notification by sending an HTTP request (JSON body) to a webhook endpoint.\n * The target URL comes from the {@link WebhookMessage}, else from\n * `routeNotificationFor('webhook')` (a URL string), else from the configured default.\n */\n@Injectable()\nexport class WebhookChannel extends BaseChannel {\n readonly channel = 'webhook';\n\n constructor(\n @Inject(WEBHOOK_OPTIONS)\n private readonly options: WebhookChannelOptions,\n @Optional()\n @Inject(WEBHOOK_OPTIONS_RESOLVER)\n private readonly resolveOptions?: WebhookOptionsResolver,\n ) {\n super();\n }\n\n async send(\n notifiable: Notifiable,\n notification: Notification,\n context?: DeliveryContext,\n ): Promise<void> {\n const options = this.forTenant(this.options, context, this.resolveOptions);\n const result = this.buildPayload<WebhookMessage | Record<string, unknown>>(\n notification,\n notifiable,\n 'toWebhook',\n context,\n );\n const message =\n result instanceof WebhookMessage ? result : new WebhookMessage().payload(result);\n const request = message.toRequest();\n\n const route = routeFor(notifiable, 'webhook', notification);\n const url = request.url ?? (typeof route === 'string' ? route : undefined) ?? options.url;\n\n if (!url) {\n throw new Error(\n 'The webhook channel needs a target URL. Set one on the WebhookMessage via .url(), ' +\n 'return one from routeNotificationFor(\"webhook\"), or set url in forRoot().',\n );\n }\n\n const headers: Record<string, string> = { ...options.headers, ...request.headers };\n if (options.secret) {\n const signature = createHmac('sha256', options.secret)\n .update(JSON.stringify(request.body))\n .digest('hex');\n headers[options.signatureHeader ?? DEFAULT_SIGNATURE_HEADER] = `sha256=${signature}`;\n }\n\n await postJson(url, request.body, {\n label: 'Webhook',\n method: request.method,\n headers,\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.redirect !== undefined ? { redirect: options.redirect } : {}),\n });\n }\n}\n","/** DI token for the resolved {@link WebhookChannelOptions} (default url, headers). */\nexport const WEBHOOK_OPTIONS = Symbol('WEBHOOK_OPTIONS');\n\n/** DI token for the optional per-tenant {@link WebhookChannelOptions} resolver. */\nexport const WEBHOOK_OPTIONS_RESOLVER = Symbol('WEBHOOK_OPTIONS_RESOLVER');\n","import { defineChannelModule } from '@dudousxd/nestjs-notifications-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport {\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookOptionsResolver,\n} from './webhook.channel';\n\nexport interface WebhookChannelModuleOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 signing secret. When set, every request carries\n * `<signatureHeader>: sha256=<hex digest of the JSON body>`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n /** Abort a request that takes longer than this (ms). Unset = no timeout. */\n timeoutMs?: number;\n /** Redirect handling: `'follow'` (default), `'error'` or `'manual'`. */\n redirect?: 'follow' | 'error' | 'manual';\n /**\n * Optional per-tenant options resolver. When a notification is delivered with a\n * `context.tenant`, the returned options are used instead of the defaults.\n */\n resolveOptions?: WebhookOptionsResolver;\n /** Register globally so the channel is discoverable app-wide. Default true. */\n global?: boolean;\n}\n\n/**\n * Registers the webhook channel.\n *\n * ```ts\n * WebhookChannelModule.forRoot({ url: 'https://example.com/hooks/notifications' });\n * ```\n */\n@Module({})\nexport class WebhookChannelModule {\n static forRoot(options: WebhookChannelModuleOptions = {}): DynamicModule {\n const webhookOptions: WebhookChannelOptions = {\n // Set each field only when provided (exactOptionalPropertyTypes); the channel resolves a\n // per-notifiable URL and default headers when these are absent.\n ...(options.url !== undefined ? { url: options.url } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n ...(options.secret !== undefined ? { secret: options.secret } : {}),\n ...(options.signatureHeader !== undefined\n ? { signatureHeader: options.signatureHeader }\n : {}),\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.redirect !== undefined ? { redirect: options.redirect } : {}),\n };\n\n return defineChannelModule({\n module: WebhookChannelModule,\n channel: WebhookChannel,\n optionsToken: WEBHOOK_OPTIONS,\n options: webhookOptions,\n resolver: { token: WEBHOOK_OPTIONS_RESOLVER, value: options.resolveOptions },\n ...(options.global !== undefined ? { global: options.global } : {}),\n });\n }\n}\n"],"mappings":"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","names":["WebhookMessage","_url","_method","_headers","_payload","url","u","payload","obj","header","key","value","headers","method","m","urlValue","methodValue","headerValues","payloadValue","toRequest","body","WEBHOOK_OPTIONS","Symbol","WEBHOOK_OPTIONS_RESOLVER","DEFAULT_SIGNATURE_HEADER","Webhook","createChannel","WebhookChannel","BaseChannel","channel","options","resolveOptions","send","notifiable","notification","context","forTenant","result","buildPayload","message","WebhookMessage","payload","request","toRequest","route","routeFor","url","undefined","Error","headers","secret","signature","createHmac","update","JSON","stringify","body","digest","signatureHeader","postJson","label","method","timeoutMs","redirect","import_nestjs_notifications_core","import_common","WebhookChannelModule","forRoot","options","webhookOptions","url","undefined","headers","secret","signatureHeader","timeoutMs","redirect","defineChannelModule","module","channel","WebhookChannel","optionsToken","WEBHOOK_OPTIONS","resolver","token","WEBHOOK_OPTIONS_RESOLVER","value","resolveOptions","global"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -62,6 +62,13 @@ interface WebhookChannelOptions {
|
|
|
62
62
|
secret?: string;
|
|
63
63
|
/** Header name for the signature. Default `X-Signature-256`. */
|
|
64
64
|
signatureHeader?: string;
|
|
65
|
+
/** Abort a request that takes longer than this (ms). Unset = no timeout. */
|
|
66
|
+
timeoutMs?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Redirect handling. Default `'follow'` (the `fetch` default). Use `'error'` when webhook URLs
|
|
69
|
+
* are user-supplied, so a 3xx can't bounce the (possibly signed) request somewhere else.
|
|
70
|
+
*/
|
|
71
|
+
redirect?: 'follow' | 'error' | 'manual';
|
|
65
72
|
}
|
|
66
73
|
/**
|
|
67
74
|
* Implement this on a notification to define its webhook payload. Returning a plain
|
|
@@ -91,6 +98,17 @@ interface WebhookChannelModuleOptions {
|
|
|
91
98
|
url?: string;
|
|
92
99
|
/** Default headers merged into every request. */
|
|
93
100
|
headers?: Record<string, string>;
|
|
101
|
+
/**
|
|
102
|
+
* HMAC-SHA256 signing secret. When set, every request carries
|
|
103
|
+
* `<signatureHeader>: sha256=<hex digest of the JSON body>`.
|
|
104
|
+
*/
|
|
105
|
+
secret?: string;
|
|
106
|
+
/** Header name for the signature. Default `X-Signature-256`. */
|
|
107
|
+
signatureHeader?: string;
|
|
108
|
+
/** Abort a request that takes longer than this (ms). Unset = no timeout. */
|
|
109
|
+
timeoutMs?: number;
|
|
110
|
+
/** Redirect handling: `'follow'` (default), `'error'` or `'manual'`. */
|
|
111
|
+
redirect?: 'follow' | 'error' | 'manual';
|
|
94
112
|
/**
|
|
95
113
|
* Optional per-tenant options resolver. When a notification is delivered with a
|
|
96
114
|
* `context.tenant`, the returned options are used instead of the defaults.
|
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,13 @@ interface WebhookChannelOptions {
|
|
|
62
62
|
secret?: string;
|
|
63
63
|
/** Header name for the signature. Default `X-Signature-256`. */
|
|
64
64
|
signatureHeader?: string;
|
|
65
|
+
/** Abort a request that takes longer than this (ms). Unset = no timeout. */
|
|
66
|
+
timeoutMs?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Redirect handling. Default `'follow'` (the `fetch` default). Use `'error'` when webhook URLs
|
|
69
|
+
* are user-supplied, so a 3xx can't bounce the (possibly signed) request somewhere else.
|
|
70
|
+
*/
|
|
71
|
+
redirect?: 'follow' | 'error' | 'manual';
|
|
65
72
|
}
|
|
66
73
|
/**
|
|
67
74
|
* Implement this on a notification to define its webhook payload. Returning a plain
|
|
@@ -91,6 +98,17 @@ interface WebhookChannelModuleOptions {
|
|
|
91
98
|
url?: string;
|
|
92
99
|
/** Default headers merged into every request. */
|
|
93
100
|
headers?: Record<string, string>;
|
|
101
|
+
/**
|
|
102
|
+
* HMAC-SHA256 signing secret. When set, every request carries
|
|
103
|
+
* `<signatureHeader>: sha256=<hex digest of the JSON body>`.
|
|
104
|
+
*/
|
|
105
|
+
secret?: string;
|
|
106
|
+
/** Header name for the signature. Default `X-Signature-256`. */
|
|
107
|
+
signatureHeader?: string;
|
|
108
|
+
/** Abort a request that takes longer than this (ms). Unset = no timeout. */
|
|
109
|
+
timeoutMs?: number;
|
|
110
|
+
/** Redirect handling: `'follow'` (default), `'error'` or `'manual'`. */
|
|
111
|
+
redirect?: 'follow' | 'error' | 'manual';
|
|
94
112
|
/**
|
|
95
113
|
* Optional per-tenant options resolver. When a notification is delivered with a
|
|
96
114
|
* `context.tenant`, the returned options are used instead of the defaults.
|
package/dist/index.js
CHANGED
|
@@ -75,13 +75,22 @@ var WEBHOOK_OPTIONS_RESOLVER = /* @__PURE__ */ Symbol("WEBHOOK_OPTIONS_RESOLVER"
|
|
|
75
75
|
// src/webhook.channel.ts
|
|
76
76
|
function _ts_decorate(decorators, target, key, desc) {
|
|
77
77
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
78
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
79
|
-
|
|
78
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
79
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
80
|
+
} else {
|
|
81
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
82
|
+
if (d = decorators[i]) {
|
|
83
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
80
87
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
81
88
|
}
|
|
82
89
|
__name(_ts_decorate, "_ts_decorate");
|
|
83
|
-
function _ts_metadata(
|
|
84
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
90
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
91
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
92
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
93
|
+
}
|
|
85
94
|
}
|
|
86
95
|
__name(_ts_metadata, "_ts_metadata");
|
|
87
96
|
function _ts_param(paramIndex, decorator) {
|
|
@@ -123,7 +132,13 @@ var WebhookChannel = class extends BaseChannel {
|
|
|
123
132
|
await postJson(url, request.body, {
|
|
124
133
|
label: "Webhook",
|
|
125
134
|
method: request.method,
|
|
126
|
-
headers
|
|
135
|
+
headers,
|
|
136
|
+
...options.timeoutMs !== void 0 ? {
|
|
137
|
+
timeoutMs: options.timeoutMs
|
|
138
|
+
} : {},
|
|
139
|
+
...options.redirect !== void 0 ? {
|
|
140
|
+
redirect: options.redirect
|
|
141
|
+
} : {}
|
|
127
142
|
});
|
|
128
143
|
}
|
|
129
144
|
};
|
|
@@ -144,8 +159,15 @@ import { defineChannelModule } from "@dudousxd/nestjs-notifications-core";
|
|
|
144
159
|
import { Module } from "@nestjs/common";
|
|
145
160
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
146
161
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
147
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
148
|
-
|
|
162
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
163
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
164
|
+
} else {
|
|
165
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
166
|
+
if (d = decorators[i]) {
|
|
167
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
149
171
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
150
172
|
}
|
|
151
173
|
__name(_ts_decorate2, "_ts_decorate");
|
|
@@ -162,6 +184,18 @@ var WebhookChannelModule = class _WebhookChannelModule {
|
|
|
162
184
|
} : {},
|
|
163
185
|
...options.headers !== void 0 ? {
|
|
164
186
|
headers: options.headers
|
|
187
|
+
} : {},
|
|
188
|
+
...options.secret !== void 0 ? {
|
|
189
|
+
secret: options.secret
|
|
190
|
+
} : {},
|
|
191
|
+
...options.signatureHeader !== void 0 ? {
|
|
192
|
+
signatureHeader: options.signatureHeader
|
|
193
|
+
} : {},
|
|
194
|
+
...options.timeoutMs !== void 0 ? {
|
|
195
|
+
timeoutMs: options.timeoutMs
|
|
196
|
+
} : {},
|
|
197
|
+
...options.redirect !== void 0 ? {
|
|
198
|
+
redirect: options.redirect
|
|
165
199
|
} : {}
|
|
166
200
|
};
|
|
167
201
|
return defineChannelModule({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhook-message.ts","../src/webhook.channel.ts","../src/tokens.ts","../src/webhook.module.ts"],"sourcesContent":["/** The HTTP method used for a webhook request. */\nexport type WebhookMethod = 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'GET';\n\n/** The resolved request description produced by {@link WebhookMessage.toRequest}. */\nexport interface WebhookRequest {\n /** Target URL, when set on the message; otherwise resolved by the channel. */\n url?: string | undefined;\n method: WebhookMethod;\n headers: Record<string, string>;\n /** The JSON body to send (a plain object). */\n body: Record<string, unknown>;\n}\n\n/**\n * A fluent builder for a webhook request.\n *\n * ```ts\n * new WebhookMessage()\n * .url('https://example.com/hooks/orders')\n * .header('X-Signature', sign(payload))\n * .payload({ event: 'order.paid', id: 42 });\n * ```\n */\nexport class WebhookMessage {\n private _url?: string;\n private _method: WebhookMethod = 'POST';\n private _headers: Record<string, string> = {};\n private _payload: Record<string, unknown> = {};\n\n /** Set the target URL (overrides the route and configured default). */\n url(u: string): this {\n this._url = u;\n return this;\n }\n\n /** Set the JSON body to send. */\n payload(obj: Record<string, unknown>): this {\n this._payload = obj;\n return this;\n }\n\n /** Set a single request header. */\n header(key: string, value: string): this {\n this._headers[key] = value;\n return this;\n }\n\n /** Merge multiple request headers. */\n headers(obj: Record<string, string>): this {\n this._headers = { ...this._headers, ...obj };\n return this;\n }\n\n /** Set the HTTP method (default `POST`). */\n method(m: WebhookMethod): this {\n this._method = m;\n return this;\n }\n\n get urlValue(): string | undefined {\n return this._url;\n }\n\n get methodValue(): WebhookMethod {\n return this._method;\n }\n\n get headerValues(): Record<string, string> {\n return this._headers;\n }\n\n get payloadValue(): Record<string, unknown> {\n return this._payload;\n }\n\n /** Serialize to a {@link WebhookRequest}. */\n toRequest(): WebhookRequest {\n return {\n url: this._url,\n method: this._method,\n headers: { ...this._headers },\n body: this._payload,\n };\n }\n}\n","import { createHmac } from 'node:crypto';\nimport {\n BaseChannel,\n type ChannelContext,\n type DeliveryContext,\n type Notifiable,\n type Notification,\n createChannel,\n postJson,\n routeFor,\n} from '@dudousxd/nestjs-notifications-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport { WebhookMessage } from './webhook-message';\n\nconst DEFAULT_SIGNATURE_HEADER = 'X-Signature-256';\n\n/** Channel handle: use as `@Webhook()` on a payload method, or as a token in `via()`. */\nexport const Webhook = createChannel('webhook');\n\n/** Resolved runtime options for the webhook channel. */\nexport interface WebhookChannelOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 secret. When set, the request is signed: the header (default\n * `X-Signature-256`) is set to `sha256=<hex digest of the raw JSON body>`, so the receiver\n * can verify authenticity. Per-tenant secrets work via `resolveOptions`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n}\n\n/**\n * Implement this on a notification to define its webhook payload. Returning a plain\n * object is treated as the JSON body to POST; return a {@link WebhookMessage} for full\n * control over the url, method and headers.\n */\nexport interface WebhookNotification extends Notification {\n toWebhook(ctx: ChannelContext): WebhookMessage | Record<string, unknown>;\n}\n\n/** Resolves per-tenant {@link WebhookChannelOptions} from a tenant id. */\nexport type WebhookOptionsResolver = (tenant: string) => WebhookChannelOptions;\n\n/**\n * Delivers a notification by sending an HTTP request (JSON body) to a webhook endpoint.\n * The target URL comes from the {@link WebhookMessage}, else from\n * `routeNotificationFor('webhook')` (a URL string), else from the configured default.\n */\n@Injectable()\nexport class WebhookChannel extends BaseChannel {\n readonly channel = 'webhook';\n\n constructor(\n @Inject(WEBHOOK_OPTIONS)\n private readonly options: WebhookChannelOptions,\n @Optional()\n @Inject(WEBHOOK_OPTIONS_RESOLVER)\n private readonly resolveOptions?: WebhookOptionsResolver,\n ) {\n super();\n }\n\n async send(\n notifiable: Notifiable,\n notification: Notification,\n context?: DeliveryContext,\n ): Promise<void> {\n const options = this.forTenant(this.options, context, this.resolveOptions);\n const result = this.buildPayload<WebhookMessage | Record<string, unknown>>(\n notification,\n notifiable,\n 'toWebhook',\n context,\n );\n const message =\n result instanceof WebhookMessage ? result : new WebhookMessage().payload(result);\n const request = message.toRequest();\n\n const route = routeFor(notifiable, 'webhook', notification);\n const url = request.url ?? (typeof route === 'string' ? route : undefined) ?? options.url;\n\n if (!url) {\n throw new Error(\n 'The webhook channel needs a target URL. Set one on the WebhookMessage via .url(), ' +\n 'return one from routeNotificationFor(\"webhook\"), or set url in forRoot().',\n );\n }\n\n const headers: Record<string, string> = { ...options.headers, ...request.headers };\n if (options.secret) {\n const signature = createHmac('sha256', options.secret)\n .update(JSON.stringify(request.body))\n .digest('hex');\n headers[options.signatureHeader ?? DEFAULT_SIGNATURE_HEADER] = `sha256=${signature}`;\n }\n\n await postJson(url, request.body, { label: 'Webhook', method: request.method, headers });\n }\n}\n","/** DI token for the resolved {@link WebhookChannelOptions} (default url, headers). */\nexport const WEBHOOK_OPTIONS = Symbol('WEBHOOK_OPTIONS');\n\n/** DI token for the optional per-tenant {@link WebhookChannelOptions} resolver. */\nexport const WEBHOOK_OPTIONS_RESOLVER = Symbol('WEBHOOK_OPTIONS_RESOLVER');\n","import { defineChannelModule } from '@dudousxd/nestjs-notifications-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport {\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookOptionsResolver,\n} from './webhook.channel';\n\nexport interface WebhookChannelModuleOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * Optional per-tenant options resolver. When a notification is delivered with a\n * `context.tenant`, the returned options are used instead of the defaults.\n */\n resolveOptions?: WebhookOptionsResolver;\n /** Register globally so the channel is discoverable app-wide. Default true. */\n global?: boolean;\n}\n\n/**\n * Registers the webhook channel.\n *\n * ```ts\n * WebhookChannelModule.forRoot({ url: 'https://example.com/hooks/notifications' });\n * ```\n */\n@Module({})\nexport class WebhookChannelModule {\n static forRoot(options: WebhookChannelModuleOptions = {}): DynamicModule {\n const webhookOptions: WebhookChannelOptions = {\n // Set each field only when provided (exactOptionalPropertyTypes); the channel resolves a\n // per-notifiable URL and default headers when these are absent.\n ...(options.url !== undefined ? { url: options.url } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n };\n\n return defineChannelModule({\n module: WebhookChannelModule,\n channel: WebhookChannel,\n optionsToken: WEBHOOK_OPTIONS,\n options: webhookOptions,\n resolver: { token: WEBHOOK_OPTIONS_RESOLVER, value: options.resolveOptions },\n ...(options.global !== undefined ? { global: options.global } : {}),\n });\n }\n}\n"],"mappings":"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","names":["WebhookMessage","_url","_method","_headers","_payload","url","u","payload","obj","header","key","value","headers","method","m","urlValue","methodValue","headerValues","payloadValue","toRequest","body","createHmac","BaseChannel","createChannel","postJson","routeFor","Inject","Injectable","Optional","WEBHOOK_OPTIONS","Symbol","WEBHOOK_OPTIONS_RESOLVER","DEFAULT_SIGNATURE_HEADER","Webhook","createChannel","WebhookChannel","BaseChannel","channel","options","resolveOptions","send","notifiable","notification","context","forTenant","result","buildPayload","message","WebhookMessage","payload","request","toRequest","route","routeFor","url","undefined","Error","headers","secret","signature","createHmac","update","JSON","stringify","body","digest","signatureHeader","postJson","label","method","defineChannelModule","Module","WebhookChannelModule","forRoot","options","webhookOptions","url","undefined","headers","defineChannelModule","module","channel","WebhookChannel","optionsToken","WEBHOOK_OPTIONS","resolver","token","WEBHOOK_OPTIONS_RESOLVER","value","resolveOptions","global"]}
|
|
1
|
+
{"version":3,"sources":["../src/webhook-message.ts","../src/webhook.channel.ts","../src/tokens.ts","../src/webhook.module.ts"],"sourcesContent":["/** The HTTP method used for a webhook request. */\nexport type WebhookMethod = 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'GET';\n\n/** The resolved request description produced by {@link WebhookMessage.toRequest}. */\nexport interface WebhookRequest {\n /** Target URL, when set on the message; otherwise resolved by the channel. */\n url?: string | undefined;\n method: WebhookMethod;\n headers: Record<string, string>;\n /** The JSON body to send (a plain object). */\n body: Record<string, unknown>;\n}\n\n/**\n * A fluent builder for a webhook request.\n *\n * ```ts\n * new WebhookMessage()\n * .url('https://example.com/hooks/orders')\n * .header('X-Signature', sign(payload))\n * .payload({ event: 'order.paid', id: 42 });\n * ```\n */\nexport class WebhookMessage {\n private _url?: string;\n private _method: WebhookMethod = 'POST';\n private _headers: Record<string, string> = {};\n private _payload: Record<string, unknown> = {};\n\n /** Set the target URL (overrides the route and configured default). */\n url(u: string): this {\n this._url = u;\n return this;\n }\n\n /** Set the JSON body to send. */\n payload(obj: Record<string, unknown>): this {\n this._payload = obj;\n return this;\n }\n\n /** Set a single request header. */\n header(key: string, value: string): this {\n this._headers[key] = value;\n return this;\n }\n\n /** Merge multiple request headers. */\n headers(obj: Record<string, string>): this {\n this._headers = { ...this._headers, ...obj };\n return this;\n }\n\n /** Set the HTTP method (default `POST`). */\n method(m: WebhookMethod): this {\n this._method = m;\n return this;\n }\n\n get urlValue(): string | undefined {\n return this._url;\n }\n\n get methodValue(): WebhookMethod {\n return this._method;\n }\n\n get headerValues(): Record<string, string> {\n return this._headers;\n }\n\n get payloadValue(): Record<string, unknown> {\n return this._payload;\n }\n\n /** Serialize to a {@link WebhookRequest}. */\n toRequest(): WebhookRequest {\n return {\n url: this._url,\n method: this._method,\n headers: { ...this._headers },\n body: this._payload,\n };\n }\n}\n","import { createHmac } from 'node:crypto';\nimport {\n BaseChannel,\n type ChannelContext,\n type DeliveryContext,\n type Notifiable,\n type Notification,\n createChannel,\n postJson,\n routeFor,\n} from '@dudousxd/nestjs-notifications-core';\nimport { Inject, Injectable, Optional } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport { WebhookMessage } from './webhook-message';\n\nconst DEFAULT_SIGNATURE_HEADER = 'X-Signature-256';\n\n/** Channel handle: use as `@Webhook()` on a payload method, or as a token in `via()`. */\nexport const Webhook = createChannel('webhook');\n\n/** Resolved runtime options for the webhook channel. */\nexport interface WebhookChannelOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 secret. When set, the request is signed: the header (default\n * `X-Signature-256`) is set to `sha256=<hex digest of the raw JSON body>`, so the receiver\n * can verify authenticity. Per-tenant secrets work via `resolveOptions`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n /** Abort a request that takes longer than this (ms). Unset = no timeout. */\n timeoutMs?: number;\n /**\n * Redirect handling. Default `'follow'` (the `fetch` default). Use `'error'` when webhook URLs\n * are user-supplied, so a 3xx can't bounce the (possibly signed) request somewhere else.\n */\n redirect?: 'follow' | 'error' | 'manual';\n}\n\n/**\n * Implement this on a notification to define its webhook payload. Returning a plain\n * object is treated as the JSON body to POST; return a {@link WebhookMessage} for full\n * control over the url, method and headers.\n */\nexport interface WebhookNotification extends Notification {\n toWebhook(ctx: ChannelContext): WebhookMessage | Record<string, unknown>;\n}\n\n/** Resolves per-tenant {@link WebhookChannelOptions} from a tenant id. */\nexport type WebhookOptionsResolver = (tenant: string) => WebhookChannelOptions;\n\n/**\n * Delivers a notification by sending an HTTP request (JSON body) to a webhook endpoint.\n * The target URL comes from the {@link WebhookMessage}, else from\n * `routeNotificationFor('webhook')` (a URL string), else from the configured default.\n */\n@Injectable()\nexport class WebhookChannel extends BaseChannel {\n readonly channel = 'webhook';\n\n constructor(\n @Inject(WEBHOOK_OPTIONS)\n private readonly options: WebhookChannelOptions,\n @Optional()\n @Inject(WEBHOOK_OPTIONS_RESOLVER)\n private readonly resolveOptions?: WebhookOptionsResolver,\n ) {\n super();\n }\n\n async send(\n notifiable: Notifiable,\n notification: Notification,\n context?: DeliveryContext,\n ): Promise<void> {\n const options = this.forTenant(this.options, context, this.resolveOptions);\n const result = this.buildPayload<WebhookMessage | Record<string, unknown>>(\n notification,\n notifiable,\n 'toWebhook',\n context,\n );\n const message =\n result instanceof WebhookMessage ? result : new WebhookMessage().payload(result);\n const request = message.toRequest();\n\n const route = routeFor(notifiable, 'webhook', notification);\n const url = request.url ?? (typeof route === 'string' ? route : undefined) ?? options.url;\n\n if (!url) {\n throw new Error(\n 'The webhook channel needs a target URL. Set one on the WebhookMessage via .url(), ' +\n 'return one from routeNotificationFor(\"webhook\"), or set url in forRoot().',\n );\n }\n\n const headers: Record<string, string> = { ...options.headers, ...request.headers };\n if (options.secret) {\n const signature = createHmac('sha256', options.secret)\n .update(JSON.stringify(request.body))\n .digest('hex');\n headers[options.signatureHeader ?? DEFAULT_SIGNATURE_HEADER] = `sha256=${signature}`;\n }\n\n await postJson(url, request.body, {\n label: 'Webhook',\n method: request.method,\n headers,\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.redirect !== undefined ? { redirect: options.redirect } : {}),\n });\n }\n}\n","/** DI token for the resolved {@link WebhookChannelOptions} (default url, headers). */\nexport const WEBHOOK_OPTIONS = Symbol('WEBHOOK_OPTIONS');\n\n/** DI token for the optional per-tenant {@link WebhookChannelOptions} resolver. */\nexport const WEBHOOK_OPTIONS_RESOLVER = Symbol('WEBHOOK_OPTIONS_RESOLVER');\n","import { defineChannelModule } from '@dudousxd/nestjs-notifications-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { WEBHOOK_OPTIONS, WEBHOOK_OPTIONS_RESOLVER } from './tokens';\nimport {\n WebhookChannel,\n type WebhookChannelOptions,\n type WebhookOptionsResolver,\n} from './webhook.channel';\n\nexport interface WebhookChannelModuleOptions {\n /** Default URL used when neither the message nor the route supplies one. */\n url?: string;\n /** Default headers merged into every request. */\n headers?: Record<string, string>;\n /**\n * HMAC-SHA256 signing secret. When set, every request carries\n * `<signatureHeader>: sha256=<hex digest of the JSON body>`.\n */\n secret?: string;\n /** Header name for the signature. Default `X-Signature-256`. */\n signatureHeader?: string;\n /** Abort a request that takes longer than this (ms). Unset = no timeout. */\n timeoutMs?: number;\n /** Redirect handling: `'follow'` (default), `'error'` or `'manual'`. */\n redirect?: 'follow' | 'error' | 'manual';\n /**\n * Optional per-tenant options resolver. When a notification is delivered with a\n * `context.tenant`, the returned options are used instead of the defaults.\n */\n resolveOptions?: WebhookOptionsResolver;\n /** Register globally so the channel is discoverable app-wide. Default true. */\n global?: boolean;\n}\n\n/**\n * Registers the webhook channel.\n *\n * ```ts\n * WebhookChannelModule.forRoot({ url: 'https://example.com/hooks/notifications' });\n * ```\n */\n@Module({})\nexport class WebhookChannelModule {\n static forRoot(options: WebhookChannelModuleOptions = {}): DynamicModule {\n const webhookOptions: WebhookChannelOptions = {\n // Set each field only when provided (exactOptionalPropertyTypes); the channel resolves a\n // per-notifiable URL and default headers when these are absent.\n ...(options.url !== undefined ? { url: options.url } : {}),\n ...(options.headers !== undefined ? { headers: options.headers } : {}),\n ...(options.secret !== undefined ? { secret: options.secret } : {}),\n ...(options.signatureHeader !== undefined\n ? { signatureHeader: options.signatureHeader }\n : {}),\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.redirect !== undefined ? { redirect: options.redirect } : {}),\n };\n\n return defineChannelModule({\n module: WebhookChannelModule,\n channel: WebhookChannel,\n optionsToken: WEBHOOK_OPTIONS,\n options: webhookOptions,\n resolver: { token: WEBHOOK_OPTIONS_RESOLVER, value: options.resolveOptions },\n ...(options.global !== undefined ? { global: options.global } : {}),\n });\n }\n}\n"],"mappings":"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","names":["WebhookMessage","_url","_method","_headers","_payload","url","u","payload","obj","header","key","value","headers","method","m","urlValue","methodValue","headerValues","payloadValue","toRequest","body","createHmac","BaseChannel","createChannel","postJson","routeFor","Inject","Injectable","Optional","WEBHOOK_OPTIONS","Symbol","WEBHOOK_OPTIONS_RESOLVER","DEFAULT_SIGNATURE_HEADER","Webhook","createChannel","WebhookChannel","BaseChannel","channel","options","resolveOptions","send","notifiable","notification","context","forTenant","result","buildPayload","message","WebhookMessage","payload","request","toRequest","route","routeFor","url","undefined","Error","headers","secret","signature","createHmac","update","JSON","stringify","body","digest","signatureHeader","postJson","label","method","timeoutMs","redirect","defineChannelModule","Module","WebhookChannelModule","forRoot","options","webhookOptions","url","undefined","headers","secret","signatureHeader","timeoutMs","redirect","defineChannelModule","module","channel","WebhookChannel","optionsToken","WEBHOOK_OPTIONS","resolver","token","WEBHOOK_OPTIONS_RESOLVER","value","resolveOptions","global"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-notifications-webhook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Webhook channel for nestjs-notifications — deliver notifications by POSTing JSON to an HTTP endpoint",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Davide Carvalho",
|
|
@@ -9,6 +9,15 @@
|
|
|
9
9
|
"url": "https://github.com/DavideCarvalho/nestjs-notifications.git",
|
|
10
10
|
"directory": "packages/webhook"
|
|
11
11
|
},
|
|
12
|
+
"homepage": "https://davidecarvalho.github.io/aviary/docs/notifications",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/DavideCarvalho/nestjs-notifications/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"nestjs",
|
|
18
|
+
"notifications",
|
|
19
|
+
"webhook"
|
|
20
|
+
],
|
|
12
21
|
"type": "module",
|
|
13
22
|
"main": "./dist/index.cjs",
|
|
14
23
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +32,7 @@
|
|
|
23
32
|
"@nestjs/common": "12.0.1",
|
|
24
33
|
"reflect-metadata": "0.2.2",
|
|
25
34
|
"typescript": "5.9.3",
|
|
26
|
-
"@dudousxd/nestjs-notifications-core": "^0.
|
|
35
|
+
"@dudousxd/nestjs-notifications-core": "^0.10.0"
|
|
27
36
|
},
|
|
28
37
|
"module": "./dist/index.js",
|
|
29
38
|
"exports": {
|