@novu/framework 2.1.1 → 2.2.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/{handler-_mH7Q42O.d.ts → handler-TDgxEYp-.d.ts} +8 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/servers/express.d.ts +1 -1
- package/dist/servers/express.js +6 -6
- package/dist/servers/h3.d.ts +1 -1
- package/dist/servers/h3.js +4 -4
- package/dist/servers/lambda.d.ts +1 -1
- package/dist/servers/lambda.js +5 -5
- package/dist/servers/nest.d.ts +115 -0
- package/dist/servers/nest.js +34 -0
- package/dist/servers/next.d.ts +1 -1
- package/dist/servers/next.js +3 -3
- package/dist/servers/nuxt.d.ts +1 -1
- package/dist/servers/nuxt.js +2 -2
- package/dist/servers/remix.d.ts +1 -1
- package/dist/servers/remix.js +2 -2
- package/dist/servers/sveltekit.d.ts +1 -1
- package/dist/servers/sveltekit.js +2 -2
- package/package.json +11 -1
|
@@ -4244,6 +4244,12 @@ options?: StepOptions<T_ControlSchema, T_Controls> & {
|
|
|
4244
4244
|
* The providers for the step. Used to override the behaviour of the providers for the step.
|
|
4245
4245
|
*/
|
|
4246
4246
|
providers?: Prettify<Providers<T_StepType, T_Controls, T_Outputs>>;
|
|
4247
|
+
/**
|
|
4248
|
+
* A flag to disable output sanitization for the step.
|
|
4249
|
+
*
|
|
4250
|
+
* @default false
|
|
4251
|
+
*/
|
|
4252
|
+
disableOutputSanitization?: boolean;
|
|
4247
4253
|
}) => StepOutput<T_Result>;
|
|
4248
4254
|
type EmailOutput = FromSchema<(typeof channelStepSchemas)[ChannelStepEnum.EMAIL]['output']>;
|
|
4249
4255
|
type EmailOutputUnvalidated = FromSchemaUnvalidated<(typeof channelStepSchemas)[ChannelStepEnum.EMAIL]['output']>;
|
|
@@ -4651,7 +4657,7 @@ type HealthCheck = {
|
|
|
4651
4657
|
};
|
|
4652
4658
|
};
|
|
4653
4659
|
|
|
4654
|
-
type SupportedFrameworkName = 'next' | 'express' | 'nuxt' | 'h3' | 'sveltekit' | 'remix' | 'lambda';
|
|
4660
|
+
type SupportedFrameworkName = 'next' | 'express' | 'nuxt' | 'h3' | 'sveltekit' | 'remix' | 'lambda' | 'nest';
|
|
4655
4661
|
|
|
4656
4662
|
declare class Client {
|
|
4657
4663
|
private discoveredWorkflows;
|
|
@@ -4752,4 +4758,4 @@ declare class NovuRequestHandler<Input extends any[] = any[], Output = any> {
|
|
|
4752
4758
|
private hashHmac;
|
|
4753
4759
|
}
|
|
4754
4760
|
|
|
4755
|
-
export { type ChatOutputUnvalidated as $, ActionStepEnum as A, type StepContext as B, Client as C, type DiscoverProviderOutput as D, type Execute as E, type FromSchemaUnvalidated as F, GetActionEnum as G, type HealthCheck as H, type StepOutput as I, type JsonSchema as J, type ActionStep as K, type CustomStep as L, type ChannelStep as M, NovuRequestHandler as N, type EmailOutput as O, PostActionEnum as P, type EmailOutputUnvalidated as Q, type EmailResult as R, type Schema as S, type SmsOutput as T, type SmsOutputUnvalidated as U, type SmsResult as V, type WorkflowOptions as W, type PushOutput as X, type PushOutputUnvalidated as Y, type PushResult as Z, type ChatOutput as _, type FromSchema as a, type ChatResult as a0, type InAppOutput as a1, type InAppOutputUnvalidated as a2, type InAppResult as a3, type DelayOutput as a4, type DelayOutputUnvalidated as a5, type DelayResult as a6, type DigestRegularOutput as a7, type DigestRegularOutputUnvalidated as a8, type DigestTimedOutput as a9, type DigestTimedOutputUnvalidated as aa, type DigestOutput as ab, type DigestOutputUnvalidated as ac, type DigestResult as ad, type Step as ae, type Subscriber as af, type Either as ag, type Awaitable as ah, type Prettify as ai, type ConditionalPartial as aj, type Indexable as ak, type PickOptional as al, type PickRequired as am, type PickRequiredKeys as an, type PickOptionalKeys as ao, type DeepPartial as ap, type ExecuteInput as aq, type WorkflowPreference as ar, type ChannelPreference as as, type WorkflowPreferences as at, type Workflow as b, type ServeHandlerOptions as c, actionStepSchemas as d, channelStepSchemas as e, ChannelStepEnum as f, WorkflowChannelEnum as g, type CodeResult as h, type ClientOptions as i, type StepType as j, type DiscoverStepOutput as k, type DiscoverWorkflowOutput as l, type DiscoverOutput as m, type EventTriggerResult as n, type EventTriggerParams as o, type EventTriggerResponse as p, type CancelEventTriggerResponse as q, type Event as r, type State as s, type ExecuteOutputMetadata as t, type ExecuteOutputOptions as u, type ExecuteOutput as v, type SupportedFrameworkName as w, type Skip as x, type StepOptions as y, JobStatusEnum as z };
|
|
4761
|
+
export { type ChatOutputUnvalidated as $, ActionStepEnum as A, type StepContext as B, Client as C, type DiscoverProviderOutput as D, type Execute as E, type FromSchemaUnvalidated as F, GetActionEnum as G, type HealthCheck as H, type StepOutput as I, type JsonSchema as J, type ActionStep as K, type CustomStep as L, type ChannelStep as M, NovuRequestHandler as N, type EmailOutput as O, PostActionEnum as P, type EmailOutputUnvalidated as Q, type EmailResult as R, type Schema as S, type SmsOutput as T, type SmsOutputUnvalidated as U, type SmsResult as V, type WorkflowOptions as W, type PushOutput as X, type PushOutputUnvalidated as Y, type PushResult as Z, type ChatOutput as _, type FromSchema as a, type ChatResult as a0, type InAppOutput as a1, type InAppOutputUnvalidated as a2, type InAppResult as a3, type DelayOutput as a4, type DelayOutputUnvalidated as a5, type DelayResult as a6, type DigestRegularOutput as a7, type DigestRegularOutputUnvalidated as a8, type DigestTimedOutput as a9, type DigestTimedOutputUnvalidated as aa, type DigestOutput as ab, type DigestOutputUnvalidated as ac, type DigestResult as ad, type Step as ae, type Subscriber as af, type Either as ag, type Awaitable as ah, type Prettify as ai, type ConditionalPartial as aj, type Indexable as ak, type PickOptional as al, type PickRequired as am, type PickRequiredKeys as an, type PickOptionalKeys as ao, type DeepPartial as ap, type ExecuteInput as aq, type WorkflowPreference as ar, type ChannelPreference as as, type WorkflowPreferences as at, type INovuRequestHandlerOptions as au, type Workflow as b, type ServeHandlerOptions as c, actionStepSchemas as d, channelStepSchemas as e, ChannelStepEnum as f, WorkflowChannelEnum as g, type CodeResult as h, type ClientOptions as i, type StepType as j, type DiscoverStepOutput as k, type DiscoverWorkflowOutput as l, type DiscoverOutput as m, type EventTriggerResult as n, type EventTriggerParams as o, type EventTriggerResponse as p, type CancelEventTriggerResponse as q, type Event as r, type State as s, type ExecuteOutputMetadata as t, type ExecuteOutputOptions as u, type ExecuteOutput as v, type SupportedFrameworkName as w, type Skip as x, type StepOptions as y, JobStatusEnum as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as Schema, F as FromSchemaUnvalidated, a as FromSchema, J as JsonSchema, E as Execute, W as WorkflowOptions, b as Workflow } from './handler-
|
|
2
|
-
export { K as ActionStep, A as ActionStepEnum, ah as Awaitable, q as CancelEventTriggerResponse, as as ChannelPreference, M as ChannelStep, f as ChannelStepEnum, _ as ChatOutput, $ as ChatOutputUnvalidated, a0 as ChatResult, C as Client, i as ClientOptions, h as CodeResult, aj as ConditionalPartial, L as CustomStep, ap as DeepPartial, a4 as DelayOutput, a5 as DelayOutputUnvalidated, a6 as DelayResult, ab as DigestOutput, ac as DigestOutputUnvalidated, a7 as DigestRegularOutput, a8 as DigestRegularOutputUnvalidated, ad as DigestResult, a9 as DigestTimedOutput, aa as DigestTimedOutputUnvalidated, m as DiscoverOutput, D as DiscoverProviderOutput, k as DiscoverStepOutput, l as DiscoverWorkflowOutput, ag as Either, O as EmailOutput, Q as EmailOutputUnvalidated, R as EmailResult, r as Event, o as EventTriggerParams, p as EventTriggerResponse, n as EventTriggerResult, aq as ExecuteInput, v as ExecuteOutput, t as ExecuteOutputMetadata, u as ExecuteOutputOptions, G as GetActionEnum, H as HealthCheck, a1 as InAppOutput, a2 as InAppOutputUnvalidated, a3 as InAppResult, ak as Indexable, z as JobStatusEnum, N as NovuRequestHandler, al as PickOptional, ao as PickOptionalKeys, am as PickRequired, an as PickRequiredKeys, P as PostActionEnum, ai as Prettify, X as PushOutput, Y as PushOutputUnvalidated, Z as PushResult, c as ServeHandlerOptions, x as Skip, T as SmsOutput, U as SmsOutputUnvalidated, V as SmsResult, s as State, ae as Step, B as StepContext, y as StepOptions, I as StepOutput, j as StepType, af as Subscriber, w as SupportedFrameworkName, g as WorkflowChannelEnum, ar as WorkflowPreference, at as WorkflowPreferences, d as actionStepSchemas, e as channelStepSchemas } from './handler-
|
|
1
|
+
import { S as Schema, F as FromSchemaUnvalidated, a as FromSchema, J as JsonSchema, E as Execute, W as WorkflowOptions, b as Workflow } from './handler-TDgxEYp-.js';
|
|
2
|
+
export { K as ActionStep, A as ActionStepEnum, ah as Awaitable, q as CancelEventTriggerResponse, as as ChannelPreference, M as ChannelStep, f as ChannelStepEnum, _ as ChatOutput, $ as ChatOutputUnvalidated, a0 as ChatResult, C as Client, i as ClientOptions, h as CodeResult, aj as ConditionalPartial, L as CustomStep, ap as DeepPartial, a4 as DelayOutput, a5 as DelayOutputUnvalidated, a6 as DelayResult, ab as DigestOutput, ac as DigestOutputUnvalidated, a7 as DigestRegularOutput, a8 as DigestRegularOutputUnvalidated, ad as DigestResult, a9 as DigestTimedOutput, aa as DigestTimedOutputUnvalidated, m as DiscoverOutput, D as DiscoverProviderOutput, k as DiscoverStepOutput, l as DiscoverWorkflowOutput, ag as Either, O as EmailOutput, Q as EmailOutputUnvalidated, R as EmailResult, r as Event, o as EventTriggerParams, p as EventTriggerResponse, n as EventTriggerResult, aq as ExecuteInput, v as ExecuteOutput, t as ExecuteOutputMetadata, u as ExecuteOutputOptions, G as GetActionEnum, H as HealthCheck, a1 as InAppOutput, a2 as InAppOutputUnvalidated, a3 as InAppResult, ak as Indexable, z as JobStatusEnum, N as NovuRequestHandler, al as PickOptional, ao as PickOptionalKeys, am as PickRequired, an as PickRequiredKeys, P as PostActionEnum, ai as Prettify, X as PushOutput, Y as PushOutputUnvalidated, Z as PushResult, c as ServeHandlerOptions, x as Skip, T as SmsOutput, U as SmsOutputUnvalidated, V as SmsResult, s as State, ae as Step, B as StepContext, y as StepOptions, I as StepOutput, j as StepType, af as Subscriber, w as SupportedFrameworkName, g as WorkflowChannelEnum, ar as WorkflowPreference, at as WorkflowPreferences, d as actionStepSchemas, e as channelStepSchemas } from './handler-TDgxEYp-.js';
|
|
3
3
|
import { ValidateFunction as ValidateFunction$1 } from 'ajv';
|
|
4
4
|
import { ParseReturnType } from 'zod';
|
|
5
5
|
import '@novu/shared';
|
package/dist/index.js
CHANGED
|
@@ -20,11 +20,11 @@ var Ze__default = /*#__PURE__*/_interopDefault(Ze);
|
|
|
20
20
|
var Lt__default = /*#__PURE__*/_interopDefault(Lt);
|
|
21
21
|
var jt__default = /*#__PURE__*/_interopDefault(jt);
|
|
22
22
|
|
|
23
|
-
var q=(i=>(i.TRIGGER="trigger",i.EXECUTE="execute",i.PREVIEW="preview",i))(q||{}),ee=(i=>(i.DISCOVER="discover",i.HEALTH_CHECK="health-check",i.CODE="code",i))(ee||{});var Ct=(t=>(t.SYNC="/v1/bridge/sync",t.DIFF="/v1/bridge/diff",t))(Ct||{}),$e=5,qe=1500;var Dt=(s=>(s.EVERY_SECOND="* * * * * *",s.EVERY_5_SECONDS="*/5 * * * * *",s.EVERY_10_SECONDS="*/10 * * * * *",s.EVERY_30_SECONDS="*/30 * * * * *",s.EVERY_MINUTE="*/1 * * * *",s.EVERY_5_MINUTES="0 */5 * * * *",s.EVERY_10_MINUTES="0 */10 * * * *",s.EVERY_30_MINUTES="0 */30 * * * *",s.EVERY_HOUR="0 0-23/1 * * *",s.EVERY_2_HOURS="0 0-23/2 * * *",s.EVERY_3_HOURS="0 0-23/3 * * *",s.EVERY_4_HOURS="0 0-23/4 * * *",s.EVERY_5_HOURS="0 0-23/5 * * *",s.EVERY_6_HOURS="0 0-23/6 * * *",s.EVERY_7_HOURS="0 0-23/7 * * *",s.EVERY_8_HOURS="0 0-23/8 * * *",s.EVERY_9_HOURS="0 0-23/9 * * *",s.EVERY_10_HOURS="0 0-23/10 * * *",s.EVERY_11_HOURS="0 0-23/11 * * *",s.EVERY_12_HOURS="0 0-23/12 * * *",s.EVERY_DAY_AT_1AM="0 01 * * *",s.EVERY_DAY_AT_2AM="0 02 * * *",s.EVERY_DAY_AT_3AM="0 03 * * *",s.EVERY_DAY_AT_4AM="0 04 * * *",s.EVERY_DAY_AT_5AM="0 05 * * *",s.EVERY_DAY_AT_6AM="0 06 * * *",s.EVERY_DAY_AT_7AM="0 07 * * *",s.EVERY_DAY_AT_8AM="0 08 * * *",s.EVERY_DAY_AT_9AM="0 09 * * *",s.EVERY_DAY_AT_10AM="0 10 * * *",s.EVERY_DAY_AT_11AM="0 11 * * *",s.EVERY_DAY_AT_NOON="0 12 * * *",s.EVERY_DAY_AT_1PM="0 13 * * *",s.EVERY_DAY_AT_2PM="0 14 * * *",s.EVERY_DAY_AT_3PM="0 15 * * *",s.EVERY_DAY_AT_4PM="0 16 * * *",s.EVERY_DAY_AT_5PM="0 17 * * *",s.EVERY_DAY_AT_6PM="0 18 * * *",s.EVERY_DAY_AT_7PM="0 19 * * *",s.EVERY_DAY_AT_8PM="0 20 * * *",s.EVERY_DAY_AT_9PM="0 21 * * *",s.EVERY_DAY_AT_10PM="0 22 * * *",s.EVERY_DAY_AT_11PM="0 23 * * *",s.EVERY_DAY_AT_MIDNIGHT="0 0 * * *",s.EVERY_WEEK="0 0 * * 0",s.EVERY_WEEKDAY="0 0 * * 1-5",s.EVERY_WEEKEND="0 0 * * 6,0",s.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT="0 0 1 * *",s.EVERY_1ST_DAY_OF_MONTH_AT_NOON="0 12 1 * *",s.EVERY_2ND_HOUR="0 */2 * * *",s.EVERY_2ND_HOUR_FROM_1AM_THROUGH_11PM="0 1-23/2 * * *",s.EVERY_2ND_MONTH="0 0 1 */2 *",s.EVERY_QUARTER="0 0 1 */3 *",s.EVERY_6_MONTHS="0 0 1 */6 *",s.EVERY_YEAR="0 0 1 0 *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_5PM="0 */30 9-17 * * *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_6PM="0 */30 9-18 * * *",s.EVERY_30_MINUTES_BETWEEN_10AM_AND_7PM="0 */30 10-19 * * *",s.MONDAY_TO_FRIDAY_AT_1AM="0 0 01 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2AM="0 0 02 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3AM="0 0 03 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4AM="0 0 04 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5AM="0 0 05 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6AM="0 0 06 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7AM="0 0 07 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8AM="0 0 08 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9AM="0 0 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_09_30AM="0 30 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10AM="0 0 10 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11AM="0 0 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11_30AM="0 30 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_12PM="0 0 12 * * 1-5",s.MONDAY_TO_FRIDAY_AT_1PM="0 0 13 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2PM="0 0 14 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3PM="0 0 15 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4PM="0 0 16 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5PM="0 0 17 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6PM="0 0 18 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7PM="0 0 19 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8PM="0 0 20 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9PM="0 0 21 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10PM="0 0 22 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11PM="0 0 23 * * 1-5",s))(Dt||{});var E=(h=>(h.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",h.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",h.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",h.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",h.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",h.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",h.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",h.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",h.STEP_NOT_FOUND_ERROR="StepNotFoundError",h.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",h.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",h.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",h.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",h.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",h.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",h.STEP_CONTROL_COMPILATION_FAILED_ERROR="StepControlCompilationFailedError",h.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",h.INVALID_ACTION_ERROR="InvalidActionError",h.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",h.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",h.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",h.SIGNATURE_INVALID_ERROR="SignatureInvalidError",h.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",h.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",h.BRIDGE_ERROR="BridgeError",h.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",h.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",h))(E||{});var Le=(w=>(w.NOVU_SIGNATURE="novu-signature",w.NOVU_ANONYMOUS="novu-anonymous",w.NOVU_SIGNATURE_DEPRECATED="x-novu-signature",w.NOVU_ANONYMOUS_DEPRECATED="x-novu-anonymous",w.NOVU_FRAMEWORK_SDK="novu-framework-sdk",w.NOVU_FRAMEWORK_SERVER="novu-framework-server",w.NOVU_FRAMEWORK_VERSION="novu-framework-version",w.USER_AGENT="user-agent",w.CONTENT_TYPE="content-type",w.ACCESS_CONTROL_ALLOW_ORIGIN="access-control-allow-origin",w.ACCESS_CONTROL_ALLOW_METHODS="access-control-allow-methods",w.ACCESS_CONTROL_ALLOW_HEADERS="access-control-allow-headers",w.ACCESS_CONTROL_MAX_AGE="access-control-max-age",w))(Le||{});var te=(i=>(i.POST="POST",i.GET="GET",i.OPTIONS="OPTIONS",i))(te||{});var Be=(o=>(o.WORKFLOW_ID="workflowId",o.STEP_ID="stepId",o.ACTION="action",o.SOURCE="source",o))(Be||{});var ie=(r=>(r[r.CONTINUE=100]="CONTINUE",r[r.SWITCHING_PROTOCOLS=101]="SWITCHING_PROTOCOLS",r[r.PROCESSING=102]="PROCESSING",r[r.EARLYHINTS=103]="EARLYHINTS",r[r.OK=200]="OK",r[r.CREATED=201]="CREATED",r[r.ACCEPTED=202]="ACCEPTED",r[r.NON_AUTHORITATIVE_INFORMATION=203]="NON_AUTHORITATIVE_INFORMATION",r[r.NO_CONTENT=204]="NO_CONTENT",r[r.RESET_CONTENT=205]="RESET_CONTENT",r[r.PARTIAL_CONTENT=206]="PARTIAL_CONTENT",r[r.AMBIGUOUS=300]="AMBIGUOUS",r[r.MOVED_PERMANENTLY=301]="MOVED_PERMANENTLY",r[r.FOUND=302]="FOUND",r[r.SEE_OTHER=303]="SEE_OTHER",r[r.NOT_MODIFIED=304]="NOT_MODIFIED",r[r.TEMPORARY_REDIRECT=307]="TEMPORARY_REDIRECT",r[r.PERMANENT_REDIRECT=308]="PERMANENT_REDIRECT",r[r.BAD_REQUEST=400]="BAD_REQUEST",r[r.UNAUTHORIZED=401]="UNAUTHORIZED",r[r.PAYMENT_REQUIRED=402]="PAYMENT_REQUIRED",r[r.FORBIDDEN=403]="FORBIDDEN",r[r.NOT_FOUND=404]="NOT_FOUND",r[r.METHOD_NOT_ALLOWED=405]="METHOD_NOT_ALLOWED",r[r.NOT_ACCEPTABLE=406]="NOT_ACCEPTABLE",r[r.PROXY_AUTHENTICATION_REQUIRED=407]="PROXY_AUTHENTICATION_REQUIRED",r[r.REQUEST_TIMEOUT=408]="REQUEST_TIMEOUT",r[r.CONFLICT=409]="CONFLICT",r[r.GONE=410]="GONE",r[r.LENGTH_REQUIRED=411]="LENGTH_REQUIRED",r[r.PRECONDITION_FAILED=412]="PRECONDITION_FAILED",r[r.PAYLOAD_TOO_LARGE=413]="PAYLOAD_TOO_LARGE",r[r.URI_TOO_LONG=414]="URI_TOO_LONG",r[r.UNSUPPORTED_MEDIA_TYPE=415]="UNSUPPORTED_MEDIA_TYPE",r[r.REQUESTED_RANGE_NOT_SATISFIABLE=416]="REQUESTED_RANGE_NOT_SATISFIABLE",r[r.EXPECTATION_FAILED=417]="EXPECTATION_FAILED",r[r.I_AM_A_TEAPOT=418]="I_AM_A_TEAPOT",r[r.MISDIRECTED=421]="MISDIRECTED",r[r.UNPROCESSABLE_ENTITY=422]="UNPROCESSABLE_ENTITY",r[r.FAILED_DEPENDENCY=424]="FAILED_DEPENDENCY",r[r.PRECONDITION_REQUIRED=428]="PRECONDITION_REQUIRED",r[r.TOO_MANY_REQUESTS=429]="TOO_MANY_REQUESTS",r[r.INTERNAL_SERVER_ERROR=500]="INTERNAL_SERVER_ERROR",r[r.NOT_IMPLEMENTED=501]="NOT_IMPLEMENTED",r[r.BAD_GATEWAY=502]="BAD_GATEWAY",r[r.SERVICE_UNAVAILABLE=503]="SERVICE_UNAVAILABLE",r[r.GATEWAY_TIMEOUT=504]="GATEWAY_TIMEOUT",r[r.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED",r))(ie||{}),Ui=[500];var ne=(i=>(i.WORKFLOW="workflow",i.PROVIDER="provider",i.STEP="step",i))(ne||{});var F=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="in_app",a))(F||{}),ze=(i=>(i.DIGEST="digest",i.DELAY="delay",i.CUSTOM="custom",i))(ze||{});var Ke="2.1.1";var B=Ke,oe="2024-06-26";var He=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="inApp",a))(He||{});var R=class extends Error{data},re=class extends R{statusCode=404},v=class extends R{statusCode=400},C=class extends R{statusCode=401},L=class extends R{statusCode=500},se=class extends R{statusCode=409};var ae=class extends v{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},z=class extends v{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},ce=class extends v{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},le=class extends v{code="ExecutionStateControlInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=i;}},pe=class extends v{code="ExecutionStateOutputInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=i;}},de=class extends v{code="ExecutionStateResultInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=i;}},ue=class extends v{code="StepControlCompilationFailedError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has invalid controls syntax in step with id: \`${t}\`. Please correct step control syntax.`),this.data=i;}},he=class extends v{code="ExecutionProviderOutputInvalidError";constructor(e,t,i,o){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${i}\` has invalid output. Please provide the correct provider output.`),this.data=o;}},me=class extends v{code="WorkflowPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct payload.`),this.data=t;}},ye=class extends R{statusCode;data;code;constructor(e,t,i){super(),this.data={message:i},this.statusCode=e,this.code=t;}};var Xe=async()=>{if(process.env.NOVU_BRIDGE_ORIGIN)return `${process.env.NOVU_BRIDGE_ORIGIN}/api/novu`;if(process.env.NEXT_PUBLIC_VERCEL_ENV==="preview"&&process.env.NEXT_PUBLIC_VERCEL_URL)return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/api/novu`;try{if(process.env.NODE_ENV==="development"){let e=await(await fetch("http://localhost:2022/.well-known/novu")).json();return `${e.tunnelOrigin}${e.route}`}}catch(n){console.error(n);}return ""};var m={info:n=>j__default.default.blue(n),warning:n=>j__default.default.yellow(n),error:n=>j__default.default.red(n),success:n=>j__default.default.green(n),underline:n=>j__default.default.underline(n),bold:n=>j__default.default.bold(n)},S={SUCCESS:m.success("\u2714"),ERROR:m.error("\u2717"),WARNING:m.warning("\u26A0"),INFO:m.info("\u2139"),ARROW:m.bold("\u2192"),MOCK:m.info("\u25CB"),HYDRATED:m.bold(m.info("\u2192")),STEP:m.info("\u03C3"),ACTION:m.info("\u03B1"),DURATION:m.info("\u0394"),PROVIDER:m.info("\u2699"),OUTPUT:m.info("\u21E2"),INPUT:m.info("\u21E0"),WORKFLOW:m.info("\u03C9"),STATE:m.info("\u03C3"),EXECUTE:m.info("\u03B5"),PREVIEW:m.info("\u03C1")};var je=n=>Object.values(n).map(e=>`\`${e}\``).join(", "),fe=n=>n.replaceAll(/(\w)(\w*)/g,(e,t,i)=>t.toUpperCase()+i.toLowerCase()).replaceAll(/[\s-]+/g,"");var ge=(n,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(i,o)=>{let a=await fetch(`${t}/v1${i}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${n}`},body:JSON.stringify(o)}),c=await a.json();if(a.ok)return c;throw shared.checkIsResponseError(c)?new ye(c.statusCode,c.error,c.message):new V("Error processing API request to Novu Cloud from Bridge application.")},delete:async i=>(await fetch(`${t}/v1${i}`,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${n}`}})).json()}};var Ft={allowedTags:Ze__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Je=n=>{if(!n)return n;let e=/^<!DOCTYPE .*?>/,t=n.match(e),i=Ze__default.default(n,Ft);return t?t[0]+i:i},we=n=>Object.keys(n).reduce((e,t)=>{let i=n[t];return typeof i=="string"?e[t]=Je(i):Array.isArray(i)?e[t]=i.map(o=>typeof o=="string"?Je(o):typeof o=="object"?we(o):o):typeof i=="object"&&i!==null?e[t]=we(i):e[t]=i,e},{});var Se=class extends R{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${je(te)}`},K=class extends v{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${je(t)}`);}},be=class extends v{code="MissingSecretKeyError";constructor(){super("Missing secret key. Set the `NOVU_SECRET_KEY` environment variable or pass `secretKey` to the client options.");}};var V=class extends L{code="BridgeError";message="Something went wrong. Please try again later."};var W=class extends se{constructor(e,t){super(`${fe(e)} with id: \`${t}\` already exists. Please use a different id.`);}},D=class extends re{constructor(e,t){super(`${fe(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},Y=class extends L{constructor(e,t){super(`Failed to execute ${fe(e)} with id: \`${t}\`. Please try again later.`);}};var Te=class extends D{code="ProviderNotFoundError";constructor(e){super("provider",e);}},ve=class extends Y{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Oe=class extends C{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},Ae=class extends C{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},Ee=class extends C{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},Re=class extends C{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},_e=class extends C{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var xe=class extends D{code="StepNotFoundError";constructor(e){super("step",e);}},Ie=class extends W{code="StepAlreadyExistsError";constructor(e){super("step",e);}};var H=class extends D{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},Pe=class extends W{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var Qe=n=>typeof structuredClone=="function"?structuredClone(n):JSON.parse(JSON.stringify(n));var ke=class{ajv;compiledSchemas;constructor(){this.ajv=new Lt__default.default({useDefaults:!0,removeAdditional:"failing"}),jt__default.default(this.ajv),this.compiledSchemas=new Map;}canHandle(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.allOf||!!e.oneOf}async validate(e,t){let i=this.compiledSchemas.get(t);i||(i=this.ajv.compile(t),this.compiledSchemas.set(t,i));let o=Qe(e);return i(o)?{success:!0,data:o}:{success:!1,errors:i.errors.map(c=>({path:c.instancePath,message:c.message}))}}transformToJsonSchema(e){return e}};var Ne=class{canHandle(e){return e.safeParseAsync!==void 0}async validate(e,t){let i=t.safeParse(e);return i.success?{success:!0,data:i.data}:{success:!1,errors:i.error.errors.map(o=>({path:`/${o.path.join("/")}`,message:o.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var Ce=new Ne,De=new ke,Me=async(n,e)=>{if(Ce.canHandle(n))return Ce.validate(e,n);if(De.canHandle(n))return De.validate(e,n);throw new Error("Invalid schema")},y=n=>{if(Ce.canHandle(n))return Ce.transformToJsonSchema(n);if(De.canHandle(n))return De.transformToJsonSchema(n);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Yt(){return ["development",void 0].includes(process.env.NODE_ENV)}var X=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=B;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Yt()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(i=>i.workflowId===t.definition.workflowId))throw new Pe(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((i,o)=>i+o.steps.length,0);return {status:"ok",sdkVersion:B,frameworkVersion:oe,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(i=>i.workflowId===e);if(t)return t;throw new H(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(a=>a.stepId===t);if(o)return o;throw new xe(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(y(e))}async validate(e,t,i,o,a,c,p){let d=await Me(t,e);if(d.success)return d.data;switch(i){case"event":this.throwInvalidEvent(o,a,d.errors);case"step":this.throwInvalidStep(c,o,a,d.errors);case"provider":this.throwInvalidProvider(c,p,o,a,d.errors);default:throw new Error(`Invalid component: '${i}'`)}}throwInvalidProvider(e,t,i,o,a){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(i){case"output":throw new he(o,e,t,a);default:throw new Error(`Invalid payload type: '${i}'`)}}throwInvalidStep(e,t,i,o){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new pe(i,e,o);case"result":throw new de(i,e,o);case"controls":throw new le(i,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,i){switch(e){case"controls":throw new ce(t,i);case"payload":throw new z(t,i);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(i,o,a)=>{let c=this.getStep(e.workflowId,i),p=await this.createStepControls(c,e),d=e.action==="preview";if(!d&&await this.shouldSkip(a?.skip,p))return i===e.stepId&&t({options:{skip:!0},outputs:{},providers:{}}),{};let f=this.previewStep.bind(this),T=this.executeStep.bind(this),A=await(d?f:T)(e,{...c,providers:c.providers.map(w=>{let P=a?.providers?.[w.type];if(!P)throw new Te(w.type);return {...w,resolve:P}}),resolve:o});return Object.values(F).includes(c.type)&&(A={...A,outputs:we(A.outputs)}),i===e.stepId&&t({...A,options:{skip:!1}}),A.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action"} workflowId:`;console.log(`
|
|
23
|
+
var q=(i=>(i.TRIGGER="trigger",i.EXECUTE="execute",i.PREVIEW="preview",i))(q||{}),ee=(i=>(i.DISCOVER="discover",i.HEALTH_CHECK="health-check",i.CODE="code",i))(ee||{});var Ct=(t=>(t.SYNC="/v1/bridge/sync",t.DIFF="/v1/bridge/diff",t))(Ct||{}),$e=5,qe=1500;var Dt=(s=>(s.EVERY_SECOND="* * * * * *",s.EVERY_5_SECONDS="*/5 * * * * *",s.EVERY_10_SECONDS="*/10 * * * * *",s.EVERY_30_SECONDS="*/30 * * * * *",s.EVERY_MINUTE="*/1 * * * *",s.EVERY_5_MINUTES="0 */5 * * * *",s.EVERY_10_MINUTES="0 */10 * * * *",s.EVERY_30_MINUTES="0 */30 * * * *",s.EVERY_HOUR="0 0-23/1 * * *",s.EVERY_2_HOURS="0 0-23/2 * * *",s.EVERY_3_HOURS="0 0-23/3 * * *",s.EVERY_4_HOURS="0 0-23/4 * * *",s.EVERY_5_HOURS="0 0-23/5 * * *",s.EVERY_6_HOURS="0 0-23/6 * * *",s.EVERY_7_HOURS="0 0-23/7 * * *",s.EVERY_8_HOURS="0 0-23/8 * * *",s.EVERY_9_HOURS="0 0-23/9 * * *",s.EVERY_10_HOURS="0 0-23/10 * * *",s.EVERY_11_HOURS="0 0-23/11 * * *",s.EVERY_12_HOURS="0 0-23/12 * * *",s.EVERY_DAY_AT_1AM="0 01 * * *",s.EVERY_DAY_AT_2AM="0 02 * * *",s.EVERY_DAY_AT_3AM="0 03 * * *",s.EVERY_DAY_AT_4AM="0 04 * * *",s.EVERY_DAY_AT_5AM="0 05 * * *",s.EVERY_DAY_AT_6AM="0 06 * * *",s.EVERY_DAY_AT_7AM="0 07 * * *",s.EVERY_DAY_AT_8AM="0 08 * * *",s.EVERY_DAY_AT_9AM="0 09 * * *",s.EVERY_DAY_AT_10AM="0 10 * * *",s.EVERY_DAY_AT_11AM="0 11 * * *",s.EVERY_DAY_AT_NOON="0 12 * * *",s.EVERY_DAY_AT_1PM="0 13 * * *",s.EVERY_DAY_AT_2PM="0 14 * * *",s.EVERY_DAY_AT_3PM="0 15 * * *",s.EVERY_DAY_AT_4PM="0 16 * * *",s.EVERY_DAY_AT_5PM="0 17 * * *",s.EVERY_DAY_AT_6PM="0 18 * * *",s.EVERY_DAY_AT_7PM="0 19 * * *",s.EVERY_DAY_AT_8PM="0 20 * * *",s.EVERY_DAY_AT_9PM="0 21 * * *",s.EVERY_DAY_AT_10PM="0 22 * * *",s.EVERY_DAY_AT_11PM="0 23 * * *",s.EVERY_DAY_AT_MIDNIGHT="0 0 * * *",s.EVERY_WEEK="0 0 * * 0",s.EVERY_WEEKDAY="0 0 * * 1-5",s.EVERY_WEEKEND="0 0 * * 6,0",s.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT="0 0 1 * *",s.EVERY_1ST_DAY_OF_MONTH_AT_NOON="0 12 1 * *",s.EVERY_2ND_HOUR="0 */2 * * *",s.EVERY_2ND_HOUR_FROM_1AM_THROUGH_11PM="0 1-23/2 * * *",s.EVERY_2ND_MONTH="0 0 1 */2 *",s.EVERY_QUARTER="0 0 1 */3 *",s.EVERY_6_MONTHS="0 0 1 */6 *",s.EVERY_YEAR="0 0 1 0 *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_5PM="0 */30 9-17 * * *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_6PM="0 */30 9-18 * * *",s.EVERY_30_MINUTES_BETWEEN_10AM_AND_7PM="0 */30 10-19 * * *",s.MONDAY_TO_FRIDAY_AT_1AM="0 0 01 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2AM="0 0 02 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3AM="0 0 03 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4AM="0 0 04 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5AM="0 0 05 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6AM="0 0 06 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7AM="0 0 07 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8AM="0 0 08 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9AM="0 0 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_09_30AM="0 30 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10AM="0 0 10 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11AM="0 0 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11_30AM="0 30 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_12PM="0 0 12 * * 1-5",s.MONDAY_TO_FRIDAY_AT_1PM="0 0 13 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2PM="0 0 14 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3PM="0 0 15 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4PM="0 0 16 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5PM="0 0 17 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6PM="0 0 18 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7PM="0 0 19 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8PM="0 0 20 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9PM="0 0 21 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10PM="0 0 22 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11PM="0 0 23 * * 1-5",s))(Dt||{});var E=(h=>(h.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",h.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",h.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",h.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",h.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",h.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",h.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",h.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",h.STEP_NOT_FOUND_ERROR="StepNotFoundError",h.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",h.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",h.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",h.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",h.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",h.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",h.STEP_CONTROL_COMPILATION_FAILED_ERROR="StepControlCompilationFailedError",h.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",h.INVALID_ACTION_ERROR="InvalidActionError",h.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",h.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",h.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",h.SIGNATURE_INVALID_ERROR="SignatureInvalidError",h.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",h.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",h.BRIDGE_ERROR="BridgeError",h.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",h.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",h))(E||{});var Le=(w=>(w.NOVU_SIGNATURE="novu-signature",w.NOVU_ANONYMOUS="novu-anonymous",w.NOVU_SIGNATURE_DEPRECATED="x-novu-signature",w.NOVU_ANONYMOUS_DEPRECATED="x-novu-anonymous",w.NOVU_FRAMEWORK_SDK="novu-framework-sdk",w.NOVU_FRAMEWORK_SERVER="novu-framework-server",w.NOVU_FRAMEWORK_VERSION="novu-framework-version",w.USER_AGENT="user-agent",w.CONTENT_TYPE="content-type",w.ACCESS_CONTROL_ALLOW_ORIGIN="access-control-allow-origin",w.ACCESS_CONTROL_ALLOW_METHODS="access-control-allow-methods",w.ACCESS_CONTROL_ALLOW_HEADERS="access-control-allow-headers",w.ACCESS_CONTROL_MAX_AGE="access-control-max-age",w))(Le||{});var te=(i=>(i.POST="POST",i.GET="GET",i.OPTIONS="OPTIONS",i))(te||{});var Be=(o=>(o.WORKFLOW_ID="workflowId",o.STEP_ID="stepId",o.ACTION="action",o.SOURCE="source",o))(Be||{});var ie=(r=>(r[r.CONTINUE=100]="CONTINUE",r[r.SWITCHING_PROTOCOLS=101]="SWITCHING_PROTOCOLS",r[r.PROCESSING=102]="PROCESSING",r[r.EARLYHINTS=103]="EARLYHINTS",r[r.OK=200]="OK",r[r.CREATED=201]="CREATED",r[r.ACCEPTED=202]="ACCEPTED",r[r.NON_AUTHORITATIVE_INFORMATION=203]="NON_AUTHORITATIVE_INFORMATION",r[r.NO_CONTENT=204]="NO_CONTENT",r[r.RESET_CONTENT=205]="RESET_CONTENT",r[r.PARTIAL_CONTENT=206]="PARTIAL_CONTENT",r[r.AMBIGUOUS=300]="AMBIGUOUS",r[r.MOVED_PERMANENTLY=301]="MOVED_PERMANENTLY",r[r.FOUND=302]="FOUND",r[r.SEE_OTHER=303]="SEE_OTHER",r[r.NOT_MODIFIED=304]="NOT_MODIFIED",r[r.TEMPORARY_REDIRECT=307]="TEMPORARY_REDIRECT",r[r.PERMANENT_REDIRECT=308]="PERMANENT_REDIRECT",r[r.BAD_REQUEST=400]="BAD_REQUEST",r[r.UNAUTHORIZED=401]="UNAUTHORIZED",r[r.PAYMENT_REQUIRED=402]="PAYMENT_REQUIRED",r[r.FORBIDDEN=403]="FORBIDDEN",r[r.NOT_FOUND=404]="NOT_FOUND",r[r.METHOD_NOT_ALLOWED=405]="METHOD_NOT_ALLOWED",r[r.NOT_ACCEPTABLE=406]="NOT_ACCEPTABLE",r[r.PROXY_AUTHENTICATION_REQUIRED=407]="PROXY_AUTHENTICATION_REQUIRED",r[r.REQUEST_TIMEOUT=408]="REQUEST_TIMEOUT",r[r.CONFLICT=409]="CONFLICT",r[r.GONE=410]="GONE",r[r.LENGTH_REQUIRED=411]="LENGTH_REQUIRED",r[r.PRECONDITION_FAILED=412]="PRECONDITION_FAILED",r[r.PAYLOAD_TOO_LARGE=413]="PAYLOAD_TOO_LARGE",r[r.URI_TOO_LONG=414]="URI_TOO_LONG",r[r.UNSUPPORTED_MEDIA_TYPE=415]="UNSUPPORTED_MEDIA_TYPE",r[r.REQUESTED_RANGE_NOT_SATISFIABLE=416]="REQUESTED_RANGE_NOT_SATISFIABLE",r[r.EXPECTATION_FAILED=417]="EXPECTATION_FAILED",r[r.I_AM_A_TEAPOT=418]="I_AM_A_TEAPOT",r[r.MISDIRECTED=421]="MISDIRECTED",r[r.UNPROCESSABLE_ENTITY=422]="UNPROCESSABLE_ENTITY",r[r.FAILED_DEPENDENCY=424]="FAILED_DEPENDENCY",r[r.PRECONDITION_REQUIRED=428]="PRECONDITION_REQUIRED",r[r.TOO_MANY_REQUESTS=429]="TOO_MANY_REQUESTS",r[r.INTERNAL_SERVER_ERROR=500]="INTERNAL_SERVER_ERROR",r[r.NOT_IMPLEMENTED=501]="NOT_IMPLEMENTED",r[r.BAD_GATEWAY=502]="BAD_GATEWAY",r[r.SERVICE_UNAVAILABLE=503]="SERVICE_UNAVAILABLE",r[r.GATEWAY_TIMEOUT=504]="GATEWAY_TIMEOUT",r[r.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED",r))(ie||{}),Ui=[500];var ne=(i=>(i.WORKFLOW="workflow",i.PROVIDER="provider",i.STEP="step",i))(ne||{});var F=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="in_app",a))(F||{}),ze=(i=>(i.DIGEST="digest",i.DELAY="delay",i.CUSTOM="custom",i))(ze||{});var He="2.2.0";var B=He,oe="2024-06-26";var Ke=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="inApp",a))(Ke||{});var R=class extends Error{data},re=class extends R{statusCode=404},v=class extends R{statusCode=400},C=class extends R{statusCode=401},L=class extends R{statusCode=500},se=class extends R{statusCode=409};var ae=class extends v{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},z=class extends v{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},ce=class extends v{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},le=class extends v{code="ExecutionStateControlInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=i;}},pe=class extends v{code="ExecutionStateOutputInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=i;}},de=class extends v{code="ExecutionStateResultInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=i;}},ue=class extends v{code="StepControlCompilationFailedError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has invalid controls syntax in step with id: \`${t}\`. Please correct step control syntax.`),this.data=i;}},he=class extends v{code="ExecutionProviderOutputInvalidError";constructor(e,t,i,o){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${i}\` has invalid output. Please provide the correct provider output.`),this.data=o;}},me=class extends v{code="WorkflowPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct payload.`),this.data=t;}},ye=class extends R{statusCode;data;code;constructor(e,t,i){super(),this.data={message:i},this.statusCode=e,this.code=t;}};var Xe=async()=>{if(process.env.NOVU_BRIDGE_ORIGIN)return `${process.env.NOVU_BRIDGE_ORIGIN}/api/novu`;if(process.env.NEXT_PUBLIC_VERCEL_ENV==="preview"&&process.env.NEXT_PUBLIC_VERCEL_URL)return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/api/novu`;try{if(process.env.NODE_ENV==="development"){let e=await(await fetch("http://localhost:2022/.well-known/novu")).json();return `${e.tunnelOrigin}${e.route}`}}catch(n){console.error(n);}return ""};var m={info:n=>j__default.default.blue(n),warning:n=>j__default.default.yellow(n),error:n=>j__default.default.red(n),success:n=>j__default.default.green(n),underline:n=>j__default.default.underline(n),bold:n=>j__default.default.bold(n)},S={SUCCESS:m.success("\u2714"),ERROR:m.error("\u2717"),WARNING:m.warning("\u26A0"),INFO:m.info("\u2139"),ARROW:m.bold("\u2192"),MOCK:m.info("\u25CB"),HYDRATED:m.bold(m.info("\u2192")),STEP:m.info("\u03C3"),ACTION:m.info("\u03B1"),DURATION:m.info("\u0394"),PROVIDER:m.info("\u2699"),OUTPUT:m.info("\u21E2"),INPUT:m.info("\u21E0"),WORKFLOW:m.info("\u03C9"),STATE:m.info("\u03C3"),EXECUTE:m.info("\u03B5"),PREVIEW:m.info("\u03C1")};var je=n=>Object.values(n).map(e=>`\`${e}\``).join(", "),fe=n=>n.replaceAll(/(\w)(\w*)/g,(e,t,i)=>t.toUpperCase()+i.toLowerCase()).replaceAll(/[\s-]+/g,"");var ge=(n,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(i,o)=>{let a=await fetch(`${t}/v1${i}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${n}`},body:JSON.stringify(o)}),c=await a.json();if(a.ok)return c;throw shared.checkIsResponseError(c)?new ye(c.statusCode,c.error,c.message):new V("Error processing API request to Novu Cloud from Bridge application.")},delete:async i=>(await fetch(`${t}/v1${i}`,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${n}`}})).json()}};var Ft={allowedTags:Ze__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Je=n=>{if(!n)return n;let e=/^<!DOCTYPE .*?>/,t=n.match(e),i=Ze__default.default(n,Ft);return t?t[0]+i:i},we=n=>Object.keys(n).reduce((e,t)=>{let i=n[t];return typeof i=="string"?e[t]=Je(i):Array.isArray(i)?e[t]=i.map(o=>typeof o=="string"?Je(o):typeof o=="object"?we(o):o):typeof i=="object"&&i!==null?e[t]=we(i):e[t]=i,e},{});var Se=class extends R{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${je(te)}`},H=class extends v{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${je(t)}`);}},be=class extends v{code="MissingSecretKeyError";constructor(){super("Missing secret key. Set the `NOVU_SECRET_KEY` environment variable or pass `secretKey` to the client options.");}};var V=class extends L{code="BridgeError";message="Something went wrong. Please try again later."};var W=class extends se{constructor(e,t){super(`${fe(e)} with id: \`${t}\` already exists. Please use a different id.`);}},D=class extends re{constructor(e,t){super(`${fe(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},Y=class extends L{constructor(e,t){super(`Failed to execute ${fe(e)} with id: \`${t}\`. Please try again later.`);}};var Te=class extends D{code="ProviderNotFoundError";constructor(e){super("provider",e);}},ve=class extends Y{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Oe=class extends C{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},Ae=class extends C{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},Ee=class extends C{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},Re=class extends C{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},_e=class extends C{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var xe=class extends D{code="StepNotFoundError";constructor(e){super("step",e);}},Ie=class extends W{code="StepAlreadyExistsError";constructor(e){super("step",e);}};var K=class extends D{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},Pe=class extends W{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var Qe=n=>typeof structuredClone=="function"?structuredClone(n):JSON.parse(JSON.stringify(n));var ke=class{ajv;compiledSchemas;constructor(){this.ajv=new Lt__default.default({useDefaults:!0,removeAdditional:"failing"}),jt__default.default(this.ajv),this.compiledSchemas=new Map;}canHandle(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.allOf||!!e.oneOf}async validate(e,t){let i=this.compiledSchemas.get(t);i||(i=this.ajv.compile(t),this.compiledSchemas.set(t,i));let o=Qe(e);return i(o)?{success:!0,data:o}:{success:!1,errors:i.errors.map(c=>({path:c.instancePath,message:c.message}))}}transformToJsonSchema(e){return e}};var Ne=class{canHandle(e){return e.safeParseAsync!==void 0}async validate(e,t){let i=t.safeParse(e);return i.success?{success:!0,data:i.data}:{success:!1,errors:i.error.errors.map(o=>({path:`/${o.path.join("/")}`,message:o.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var Ce=new Ne,De=new ke,Me=async(n,e)=>{if(Ce.canHandle(n))return Ce.validate(e,n);if(De.canHandle(n))return De.validate(e,n);throw new Error("Invalid schema")},y=n=>{if(Ce.canHandle(n))return Ce.transformToJsonSchema(n);if(De.canHandle(n))return De.transformToJsonSchema(n);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Yt(){return ["development",void 0].includes(process.env.NODE_ENV)}var X=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=B;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Yt()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(i=>i.workflowId===t.definition.workflowId))throw new Pe(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((i,o)=>i+o.steps.length,0);return {status:"ok",sdkVersion:B,frameworkVersion:oe,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(i=>i.workflowId===e);if(t)return t;throw new K(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(a=>a.stepId===t);if(o)return o;throw new xe(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(y(e))}async validate(e,t,i,o,a,c,p){let d=await Me(t,e);if(d.success)return d.data;switch(i){case"event":this.throwInvalidEvent(o,a,d.errors);case"step":this.throwInvalidStep(c,o,a,d.errors);case"provider":this.throwInvalidProvider(c,p,o,a,d.errors);default:throw new Error(`Invalid component: '${i}'`)}}throwInvalidProvider(e,t,i,o,a){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(i){case"output":throw new he(o,e,t,a);default:throw new Error(`Invalid payload type: '${i}'`)}}throwInvalidStep(e,t,i,o){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new pe(i,e,o);case"result":throw new de(i,e,o);case"controls":throw new le(i,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,i){switch(e){case"controls":throw new ce(t,i);case"payload":throw new z(t,i);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(i,o,a)=>{let c=this.getStep(e.workflowId,i),p=await this.createStepControls(c,e),d=e.action==="preview";if(!d&&await this.shouldSkip(a?.skip,p))return i===e.stepId&&t({options:{skip:!0},outputs:{},providers:{}}),{};let f=this.previewStep.bind(this),T=this.executeStep.bind(this),A=await(d?f:T)(e,{...c,providers:c.providers.map(w=>{let P=a?.providers?.[w.type];if(!P)throw new Te(w.type);return {...w,resolve:P}}),resolve:o});return Object.values(F).includes(c.type)&&a?.disableOutputSanitization!==!0&&(A={...A,outputs:we(A.outputs)}),i===e.stepId&&t({...A,options:{skip:!1}}),A.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action"} workflowId:`;console.log(`
|
|
24
24
|
${m.bold(m.underline(o))} '${e.workflowId}'`);let a=this.getWorkflow(e.workflowId),c=process.hrtime(),p={outputs:{},providers:{},options:{skip:!1}},d,f=new Promise(k=>{d=k;}),T=k=>{d(),p=k;},I;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new z(e.workflowId,{message:"Event `payload` is required"});let k=await this.createExecutionPayload(e,a),N={...e,payload:k};await Promise.race([f,a.execute({payload:k,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(N,T),sms:this.executeStepFactory(N,T),inApp:this.executeStepFactory(N,T),digest:this.executeStepFactory(N,T),delay:this.executeStepFactory(N,T),push:this.executeStepFactory(N,T),chat:this.executeStepFactory(N,T),custom:this.executeStepFactory(N,T)}})]);}catch(k){I=k;}let A=process.hrtime(c),w=A[0],P=A[1],Ge=w*1e3+P/1e6,kt=I?S.ERROR:S.SUCCESS,Nt=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${kt} ${Nt} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,Ge,I),I)throw I;return {outputs:p.outputs,providers:p.providers,options:p.options,metadata:{status:"success",error:!1,duration:Ge}}}async createExecutionPayload(e,t){let i=e.payload||e.data;if(e.action==="preview"){let a=this.mock(t.payload.schema);i=Object.assign(a,i);}return await this.validate(i,t.payload.unknownSchema,"event","payload",e.workflowId)}prettyPrintExecute(e,t,i){let o=i?S.ERROR:S.SUCCESS,a=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",c=i?"Failed to execute":a,p=i?m.error:m.success,d=`${o} ${c} workflowId: '${e.workflowId}`;console.log(`
|
|
25
25
|
${m.bold(p(d))}'`),console.log(` \u251C ${S.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${S.ACTION} action: '${e.action}'`),console.log(` \u2514 ${S.DURATION} duration: '${t.toFixed(2)}ms'
|
|
26
26
|
`);}async executeProviders(e,t,i){return t.providers.reduce(async(o,a)=>{let c=await o,p=this.previewProvider.bind(this),d=this.executeProvider.bind(this),T=await(e.action==="preview"?p:d)(e,t,a,i);return {...c,[a.type]:T}},Promise.resolve({}))}previewProvider(e,t,i,o){return console.log(` ${S.MOCK} Mocked provider: \`${i.type}\``),this.mock(i.outputs.schema)}async executeProvider(e,t,i,o){let a=Ue__default.default({indent:2}).start(`Executing provider: \`${i.type}\``);try{if(e.stepId===t.stepId){let c=await this.createStepControls(t,e),p=await i.resolve({controls:c,outputs:o}),d=await this.validate(p,i.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,i.type);return a.succeed(`Executed provider: \`${i.type}\``),{...d,_passthrough:p._passthrough}}else return a.stopAndPersist({symbol:S.HYDRATED,text:`Hydrated provider: \`${i.type}\``}),{}}catch(c){throw a.stopAndPersist({symbol:S.ERROR,text:`Failed to execute provider: \`${i.type}\``}),new ve(`Failed to execute provider: '${i.type}'.
|
|
27
|
-
${c.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let i=Ue__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),a=await this.compileControls(o,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),d=await this.executeProviders(e,t,p);return i.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:p,providers:d}}catch(o){throw i.stopAndPersist({prefixText:"",symbol:S.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let i=Ue__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let o=e.state.find(a=>a.stepId===t.stepId);if(o){let a=await this.validate(o.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return i.stopAndPersist({symbol:S.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:a,providers:await this.executeProviders(e,t,a)}}else throw new ae(e.workflowId,t.stepId)}catch(o){throw i.stopAndPersist({symbol:S.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){try{let i=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(i,{payload:t.payload||t.data,subscriber:t.subscriber,...t.payload||t.data});return JSON.parse(o)}catch(i){throw new ue(t.workflowId,t.stepId,i)}}async createStepControls(e,t){let i=t.controls||t.inputs;return await this.validate(i,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let i=Ue__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let o=await this.createStepControls(t,e),a=await this.compileControls(o,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return i.stopAndPersist({symbol:S.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:p,providers:await this.executeProviders(e,t,p)}}else {let o=this.mock(t.results.schema);return i.stopAndPersist({symbol:S.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw i.stopAndPersist({symbol:S.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),o}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let i;if(e)t?i=this.getStepCode(e,t):i=this.getWorkflowCode(e);else throw new H(e);return i}};var We=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new X,this.client.addWorkflows(e.workflows),this.http=ge(this.client.secretKey),this.frameworkName=e.frameworkName,this.hmacEnabled=this.client.strictAuthentication;}createHandler(){return async(...e)=>{let t=await this.handler(...e),i=await this.handleAction({actions:t});return t.transformResponse(i)}}getStaticHeaders(){let e=`novu-framework:v${this.client.version}`;return {"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST","access-control-allow-headers":"*","access-control-max-age":"604800","novu-framework-version":oe,"novu-framework-sdk":B,"novu-framework-server":this.frameworkName,"user-agent":e}}createResponse(e,t){return {status:e,body:JSON.stringify(t),headers:{...this.getStaticHeaders()}}}createError(e){return {status:e.statusCode,body:JSON.stringify({message:e.message,data:e.data,code:e.code}),headers:this.getStaticHeaders()}}async handleAction({actions:e}){let t=await e.url(),i=await e.method(),o=t.searchParams.get("action")||"",a=t.searchParams.get("workflowId")||"",c=t.searchParams.get("stepId")||"",p=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",d={};try{i==="POST"&&(d=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(d,p);let f=this.getPostActionMap(d,a,c,o),T=this.getGetActionMap(a,c);if(i==="POST")return await this.handlePostAction(o,f);if(i==="GET")return await this.handleGetAction(o,T);if(i==="OPTIONS")return this.createResponse(200,{})}catch(f){return this.handleError(f)}return this.createError(new Se(i))}getPostActionMap(e,t,i,o){return {trigger:this.triggerAction({workflowId:t,...e}),execute:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:o});return this.createResponse(200,a)},preview:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:o});return this.createResponse(200,a)}}}triggerAction(e){return async()=>{let t={name:e.workflowId,to:e.to,payload:e?.payload||{},transactionId:e.transactionId,overrides:e.overrides||{},...e.actor&&{actor:e.actor},...e.bridgeUrl&&{bridgeUrl:e.bridgeUrl},...e.controls&&{controls:e.controls}},i=await this.http.post("/events/trigger",t);return this.createResponse(200,i)}}getGetActionMap(e,t){return {discover:async()=>{let i=await this.client.discover();return this.createResponse(200,i)},"health-check":async()=>{let i=await this.client.healthCheck();return this.createResponse(200,i)},code:async()=>{let i=await this.client.getCode(e,t);return this.createResponse(200,i)}}}async handlePostAction(e,t){if(Object.values(q).includes(e)){let i=t[e];return i()}else throw new K(e,q)}async handleGetAction(e,t){if(Object.values(ee).includes(e)){let i=t[e];return i()}else throw new K(e,ee)}isBridgeError(e){return Object.values(E).includes(e?.code)}isPlatformError(e){return e?.statusCode>=400&&e?.statusCode<500}handleError(e){return this.isBridgeError(e)?(e.statusCode===500&&console.error(e),this.createError(e)):this.isPlatformError(e)?this.createError(e):(console.error(e),this.createError(new V))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new Ae;if(!this.client.secretKey)throw new _e;let[i,o]=t.split(",");if(!i||!o)throw new Ee;let[a,c]=i.split("="),[p,d]=o.split("=");if(Number(a)<Date.now()-1500)throw new Re;if(!(this.hashHmac(this.client.secretKey,`${c}.${JSON.stringify(e)}`)===d))throw new Oe}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var l={output:{type:"object",properties:{},required:[],additionalProperties:!0}};var $t={type:"object",properties:{webhookUrl:{type:"string",format:"uri"},text:{type:"string"},blocks:{type:"array",items:{type:"object",properties:{type:{enum:["image","context","actions","divider","section","input","file","header","video","rich_text"]}},required:["type"],additionalProperties:!0}}},additionalProperties:!0},et={output:$t};var tt={[shared.ChatProviderIdEnum.Discord]:l,[shared.ChatProviderIdEnum.GetStream]:l,[shared.ChatProviderIdEnum.GrafanaOnCall]:l,[shared.ChatProviderIdEnum.Mattermost]:l,[shared.ChatProviderIdEnum.MsTeams]:l,[shared.ChatProviderIdEnum.RocketChat]:l,[shared.ChatProviderIdEnum.Ryver]:l,[shared.ChatProviderIdEnum.Slack]:et,[shared.ChatProviderIdEnum.WhatsAppBusiness]:l,[shared.ChatProviderIdEnum.Zulip]:l};var qt={type:"object",properties:{to:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:'Email address of the recipient(s). Example: "Bob bob@host.com". You can use commas to separate multiple recipients (e.g.: "test@example.com,test@example.com" or ["test@example.com", "test@example.com"]).'},from:{type:"string"},subject:{type:"string",description:"Subject of the message."},text:{type:"string",description:"Text version of the message."},html:{type:"string",description:"HTML version of the message."},message:{type:"string",description:"MIME string of the message. Make sure to use multipart/form-data to send this as a file upload."},cc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for carbon copy"},bcc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for blind carbon copy"},ampHtml:{type:"string"},tVersion:{type:"string"},tText:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oTag:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Tag string. See Tagging for more information."},oDkim:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables/disabled DKIM signatures on per-message basis. Pass yes or no"},oDeliverytime:{type:"string",description:"Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future."},oDeliverytimeOptimizePeriod:{type:"string"},oTimeZoneLocalize:{type:"string"},oTestmode:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables sending in test mode. Pass yes if needed. See Sending in Test Mode"},oTracking:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no."},oTrackingClicks:{anyOf:[{type:"string",enum:["yes","no","htmlonly"]},{type:"boolean"}],description:"Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly."},oTrackingOpens:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no."},oRequireTls:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oSkipVerification:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},recipientVariables:{type:"string"}},required:[],additionalProperties:!0},it={output:qt};var M={type:"object",properties:{name:{type:"string"},email:{type:"string"}},description:'JSON object, containing 2 properties: Name and Email address of a previously validated and active sender. Including the Name property in the JSON is optional. This property is not mandatory in case you use TemplateID and you specified a From address for the template. Format : { "Email":"value", "Name":"value" }.',required:["Email"],additionalProperties:!0},Bt={type:"object",properties:{contentType:{type:"string"},filename:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},zt={type:"object",properties:{filename:{type:"string"},contentType:{type:"string"},contentId:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},Kt={type:"object",properties:{from:M,sender:M,to:{type:"array",items:M},cc:{type:"array",items:M},bcc:{type:"array",items:M},replyTo:M,subject:{type:"string"},textPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},htmlPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},templateId:{type:"number",description:"an ID for a template that is previously created and stored in Mailjet's system. It is mandatory when From and TextPart and/or HtmlPart are not provided. "},templateLanguage:{type:"boolean"},templateErrorReporting:M,templateErrorDeliver:{type:"boolean"},attachments:{type:"array",items:Bt},inlineAttachments:{type:"array",items:zt},priority:{type:"number"},customCampaign:{type:"string"},deduplicateCampaign:{type:"boolean"},trackOpens:{type:"string",enum:["account_default","disabled","enabled"]},trackClicks:{type:"string",enum:["account_default","disabled","enabled"]},customId:{type:"string"},eventPayload:{type:"string"},urlTags:{type:"string"},headers:{type:"object",additionalProperties:!0},variables:{type:"object",additionalProperties:!0}},required:[],additionalProperties:!0},nt={output:Kt};var _={type:"object",properties:{address:{type:"string"},name:{type:"string"}},additionalProperties:!0},Fe={type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0},Ht={type:"object",properties:{from:{anyOf:[{type:"string"},_]},sender:{anyOf:[{type:"string"},_]},to:{anyOf:[{type:"string"},_,{type:"array",items:_}]},cc:{anyOf:[{type:"string"},_,{type:"array",items:_}]},bcc:{anyOf:[{type:"string"},_,{type:"array",items:_}]},replyTo:{anyOf:[{type:"string"},_,{type:"array",items:_}]},inReplyTo:{anyOf:[{type:"string"},_]},references:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},subject:{type:"string"},text:{anyOf:[{type:"string"},Fe]},html:{anyOf:[{type:"string"},Fe]},watchHtml:{anyOf:[{type:"string"},Fe]},amp:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},href:{type:"string"},encoding:{type:"string"},contentType:{type:"string"},raw:{anyOf:[{type:"string"},Fe]}}}]},icalEvent:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},method:{type:"string"},filename:{anyOf:[{type:"string"},{type:"boolean"}]},href:{type:"string"},encoding:{type:"string"}}}]},headers:{anyOf:[{type:"object",additionalProperties:!0},{type:"array",items:{type:"object",additionalProperties:!0}}]},list:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},attachments:{type:"array",items:{type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0}}},required:[],additionalProperties:!0},ot={output:Ht};var Xt={type:"object",properties:{},required:[],additionalProperties:!1},rt={output:Xt};var Jt={type:"object",properties:{personalizations:{type:"array",description:"An array of messages and their metadata. Each object within personalizations can be thought of as an envelope - it defines who should receive an individual message and how that message should be handled. See our [Personalizations documentation](https://sendgrid.com/docs/for-developers/sending-email/personalizations/) for examples.",uniqueItems:!1,maxItems:1e3,items:{type:"object",properties:{from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},to:{title:"To Email Array",type:"array",items:{type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},cc:{type:"array",description:"An array of recipients who will receive a copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},bcc:{type:"array",description:"An array of recipients who will receive a blind carbon copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},subject:{type:"string",description:"The subject of your email. See character length requirements according to [RFC 2822](http://stackoverflow.com/questions/1592291/what-is-the-email-subject-length-limit#answer-1592310).",minLength:1},headers:{type:"object",description:"A collection of JSON key/value pairs allowing you to specify handling instructions for your email. You may not overwrite the following headers: `x-sg-id`, `x-sg-eid`, `received`, `dkim-signature`, `Content-Type`, `Content-Transfer-Encoding`, `To`, `From`, `Subject`, `Reply-To`, `CC`, `BCC`"},substitutions:{type:"object",description:'Substitutions allow you to insert data without using Dynamic Transactional Templates. This field should **not** be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "substitutionTag":"value to substitute". The key/value pairs must be strings. These substitutions will apply to the text and html content of the body of your email, in addition to the `subject` and `reply-to` parameters. The total collective size of your substitutions may not exceed 10,000 bytes per personalization object.',maxProperties:1e4},dynamicTemplateData:{type:"object",description:'Dynamic template data is available using Handlebars syntax in Dynamic Transactional Templates. This field should be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "variable_name":"value to insert".'},customArgs:{type:"object",description:"Values that are specific to this personalization that will be carried along with the email and its activity data. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This field may not exceed 10,000 bytes.",maxProperties:1e4},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when your email should be delivered. Scheduling delivery more than 72 hours in advance is forbidden."}},required:["to"]}},from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},replyTo:{title:"Reply_to Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The email address where any replies or bounces will be returned."},name:{type:"string",description:"A name or title associated with the `replyTo` email address."}},required:["email"]},replyToList:{type:"array",description:"An array of recipients who will receive replies and/or bounces. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name. You can either choose to use \u201CreplyTo\u201D field or \u201CreplyToList\u201D but not both.",uniqueItems:!0,maxItems:1e3,items:{type:"object",properties:{email:{type:"string",description:"The email address where any replies or bounces will be returned.",format:"email"},name:{type:"string",description:"A name or title associated with the `replyToList` email address."}},required:["email"]}},subject:{type:"string",description:"The global or 'message level' subject of your email. This may be overridden by subject lines set in personalizations.",minLength:1},content:{type:"array",description:"An array where you can specify the content of your email. You can include multiple [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of content, but you must specify at least one MIME type. To include more than one MIME type, add another object to the array containing the `type` and `value` parameters.",items:{type:"object",properties:{type:{type:"string",description:"The MIME type of the content you are including in your email (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},value:{type:"string",description:"The actual content of the specified MIME type that you are including in your email.",minLength:1}},required:["type","value"]}},attachments:{type:"array",description:"An array of objects where you can specify any attachments you want to include.",items:{type:"object",properties:{content:{type:"string",description:"The Base64 encoded content of the attachment.",minLength:1},type:{type:"string",description:"The MIME type of the content you are attaching (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},filename:{type:"string",description:"The attachment's filename."},disposition:{type:"string",default:"attachment",description:"The attachment's content-disposition, specifying how you would like the attachment to be displayed. For example, `\u201Cinline\u201D` results in the attached file are displayed automatically within the message while `\u201Cattachment\u201D` results in the attached file require some action to be taken before it is displayed, such as opening or downloading the file.",enum:["inline","attachment"]},contentId:{type:"string",description:"The attachment's content ID. This is used when the disposition is set to `\u201Cinline\u201D` and the attachment is an image, allowing the file to be displayed within the body of your email."}},required:["content","filename"]}},templateId:{type:"string",description:"An email template ID. A template that contains a subject and content \u2014 either text or html \u2014 will override any subject and content values specified at the personalizations or message level."},headers:{description:"An object containing key/value pairs of header names and the value to substitute for them. The key/value pairs must be strings. You must ensure these are properly encoded if they contain unicode characters. These headers cannot be one of the reserved headers.",type:"object"},categories:{type:"array",description:"An array of category names for this message. Each category name may not exceed 255 characters. ",uniqueItems:!0,maxItems:10,items:{type:"string",maxLength:255}},customArgs:{description:"Values that are specific to the entire send that will be carried along with the email and its activity data. Key/value pairs must be strings. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This parameter is overridden by `customArgs` set at the personalizations level. Total `customArgs` size may not exceed 10,000 bytes.",type:"string"},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when you want your email to be delivered. This may be overridden by the `sendAt` parameter set at the personalizations level. Delivery cannot be scheduled more than 72 hours in advance. If you have the flexibility, it's better to schedule mail for off-peak times. Most emails are scheduled and sent at the top of the hour or half hour. Scheduling email to avoid peak times \u2014 for example, scheduling at 10:53 \u2014 can result in lower deferral rates due to the reduced traffic during off-peak times."},batchId:{type:"string",description:"An ID representing a batch of emails to be sent at the same time. Including a `batchId` in your request allows you include this email in that batch. It also enables you to cancel or pause the delivery of that batch. For more information, see the [Cancel Scheduled Sends API](https://sendgrid.com/docs/api-reference/)."},asm:{type:"object",description:"An object allowing you to specify how to handle unsubscribes.",properties:{groupId:{type:"integer",description:"The unsubscribe group to associate with this email."},groupsToDisplay:{type:"array",description:"An array containing the unsubscribe groups that you would like to be displayed on the unsubscribe preferences page.",maxItems:25,items:{type:"integer"}}},required:["groupId"]},ipPoolName:{type:"string",description:"The IP Pool that you would like to send this email from.",minLength:2,maxLength:64},mailSettings:{type:"object",description:"A collection of different mail settings that you can use to specify how you would like this email to be handled.",properties:{bypassListManagement:{type:"object",description:"Allows you to bypass all unsubscribe groups and suppressions to ensure that the email is delivered to every single recipient. This should only be used in emergencies when it is absolutely necessary that every recipient receives your email. This filter cannot be combined with any other bypass filters. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassSpamManagement:{type:"object",description:"Allows you to bypass the spam report list to ensure that the email is delivered to recipients. Bounce and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassBounceManagement:{type:"object",description:"Allows you to bypass the bounce list to ensure that the email is delivered to recipients. Spam report and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassUnsubscribeManagement:{type:"object",description:"Allows you to bypass the global unsubscribe list to ensure that the email is delivered to recipients. Bounce and spam report lists will still be checked; addresses on these other lists will not receive the message. This filter applies only to global unsubscribes and will not bypass group unsubscribes. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},footer:{type:"object",description:"The default footer that you would like included on every email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"The plain text content of your footer."},html:{type:"string",description:"The HTML content of your footer."}}},sandboxMode:{type:"object",description:"Sandbox Mode allows you to send a test email to ensure that your request body is valid and formatted correctly.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}}}},trackingSettings:{type:"object",description:"Settings to determine how you would like to track the metrics of how your recipients interact with your email.",properties:{clickTracking:{type:"object",description:"Allows you to track if a recipient clicked a link in your email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},enableText:{type:"boolean",description:"Indicates if this setting should be included in the `text/plain` portion of your email."}}},openTracking:{type:"object",description:"Allows you to track if the email was opened by including a single pixel image in the body of the content. When the pixel is loaded, Twilio SendGrid can log that the email was opened.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},substitutionTag:{type:"string",description:"Allows you to specify a substitution tag that you can insert in the body of your email at a location that you desire. This tag will be replaced by the open tracking pixel."}}},subscriptionTracking:{type:"object",description:"Allows you to insert a subscription management link at the bottom of the text and HTML bodies of your email. If you would like to specify the location of the link within your email, you may use the `substitutionTag`.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"Text to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},html:{type:"string",description:"HTML to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},substitutionTag:{type:"string",description:"A tag that will be replaced with the unsubscribe URL. for example: `[unsubscribe_url]`. If this parameter is used, it will override both the `text` and `html` parameters. The URL of the link will be placed at the substitution tag\u2019s location with no additional formatting."}}},ganalytics:{type:"object",description:"Allows you to enable tracking provided by Google Analytics.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},utmSource:{type:"string",description:"Name of the referrer source. (e.g. Google, SomeDomain.com, or Marketing Email)"},utmMedium:{type:"string",description:"Name of the marketing medium. (e.g. Email)"},utmTerm:{type:"string",description:"Used to identify any paid keywords."},utmContent:{type:"string",description:"Used to differentiate your campaign from advertisements."},utmCampaign:{type:"string",description:"The name of the campaign."}}}}}},required:[],additionalProperties:!1},st={output:Jt};var at={[shared.EmailProviderIdEnum.Braze]:l,[shared.EmailProviderIdEnum.Clickatell]:l,[shared.EmailProviderIdEnum.CustomSMTP]:ot,[shared.EmailProviderIdEnum.EmailJS]:l,[shared.EmailProviderIdEnum.EmailWebhook]:l,[shared.EmailProviderIdEnum.Infobip]:l,[shared.EmailProviderIdEnum.MailerSend]:l,[shared.EmailProviderIdEnum.Mailgun]:it,[shared.EmailProviderIdEnum.Mailjet]:nt,[shared.EmailProviderIdEnum.Mailtrap]:l,[shared.EmailProviderIdEnum.Mandrill]:l,[shared.EmailProviderIdEnum.NetCore]:l,[shared.EmailProviderIdEnum.Novu]:rt,[shared.EmailProviderIdEnum.Outlook365]:l,[shared.EmailProviderIdEnum.Plunk]:l,[shared.EmailProviderIdEnum.Postmark]:l,[shared.EmailProviderIdEnum.Resend]:l,[shared.EmailProviderIdEnum.SendGrid]:st,[shared.EmailProviderIdEnum.Sendinblue]:l,[shared.EmailProviderIdEnum.SES]:l,[shared.EmailProviderIdEnum.SparkPost]:l};var Zt={type:"object",properties:{},required:[],additionalProperties:!1},ct={output:Zt};var lt={[shared.InAppProviderIdEnum.Novu]:ct};var pt={anyOf:[{type:"string"},{type:"object",additionalProperties:!0,properties:{name:{type:"string"},volume:{type:"number"},critical:{type:"number"}},required:["name","volume","critical"]}]},ei={type:"object",properties:{topic:{type:"string",description:"The destination topic for the notification."},id:{type:"string",description:"A UUID to identify the notification with APNS. If an id is not supplied, APNS will generate one automatically. If an error occurs the response will contain the id. This property populates the apns-id header."},expiry:{type:"number",description:"A UNIX timestamp when the notification should expire. If the notification cannot be delivered to the device, APNS will retry until it expires. An expiry of 0 indicates that the notification expires immediately, therefore no retries will be attempted."},priority:{type:"number",description:`Provide one of the following values:
|
|
27
|
+
${c.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let i=Ue__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),a=await this.compileControls(o,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),d=await this.executeProviders(e,t,p);return i.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:p,providers:d}}catch(o){throw i.stopAndPersist({prefixText:"",symbol:S.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let i=Ue__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let o=e.state.find(a=>a.stepId===t.stepId);if(o){let a=await this.validate(o.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return i.stopAndPersist({symbol:S.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:a,providers:await this.executeProviders(e,t,a)}}else throw new ae(e.workflowId,t.stepId)}catch(o){throw i.stopAndPersist({symbol:S.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){try{let i=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(i,{payload:t.payload||t.data,subscriber:t.subscriber,...t.payload||t.data});return JSON.parse(o)}catch(i){throw new ue(t.workflowId,t.stepId,i)}}async createStepControls(e,t){let i=t.controls||t.inputs;return await this.validate(i,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let i=Ue__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let o=await this.createStepControls(t,e),a=await this.compileControls(o,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return i.stopAndPersist({symbol:S.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:p,providers:await this.executeProviders(e,t,p)}}else {let o=this.mock(t.results.schema);return i.stopAndPersist({symbol:S.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw i.stopAndPersist({symbol:S.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),o}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let i;if(e)t?i=this.getStepCode(e,t):i=this.getWorkflowCode(e);else throw new K(e);return i}};var We=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new X,this.client.addWorkflows(e.workflows),this.http=ge(this.client.secretKey),this.frameworkName=e.frameworkName,this.hmacEnabled=this.client.strictAuthentication;}createHandler(){return async(...e)=>{let t=await this.handler(...e),i=await this.handleAction({actions:t});return t.transformResponse(i)}}getStaticHeaders(){let e=`novu-framework:v${this.client.version}`;return {"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST","access-control-allow-headers":"*","access-control-max-age":"604800","novu-framework-version":oe,"novu-framework-sdk":B,"novu-framework-server":this.frameworkName,"user-agent":e}}createResponse(e,t){return {status:e,body:JSON.stringify(t),headers:{...this.getStaticHeaders()}}}createError(e){return {status:e.statusCode,body:JSON.stringify({message:e.message,data:e.data,code:e.code}),headers:this.getStaticHeaders()}}async handleAction({actions:e}){let t=await e.url(),i=await e.method(),o=t.searchParams.get("action")||"health-check",a=t.searchParams.get("workflowId")||"",c=t.searchParams.get("stepId")||"",p=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",d={};try{i==="POST"&&(d=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(d,p);let f=this.getPostActionMap(d,a,c,o),T=this.getGetActionMap(a,c);if(i==="POST")return await this.handlePostAction(o,f);if(i==="GET")return await this.handleGetAction(o,T);if(i==="OPTIONS")return this.createResponse(200,{})}catch(f){return this.handleError(f)}return this.createError(new Se(i))}getPostActionMap(e,t,i,o){return {trigger:this.triggerAction({workflowId:t,...e}),execute:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:o});return this.createResponse(200,a)},preview:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:o});return this.createResponse(200,a)}}}triggerAction(e){return async()=>{let t={name:e.workflowId,to:e.to,payload:e?.payload||{},transactionId:e.transactionId,overrides:e.overrides||{},...e.actor&&{actor:e.actor},...e.bridgeUrl&&{bridgeUrl:e.bridgeUrl},...e.controls&&{controls:e.controls}},i=await this.http.post("/events/trigger",t);return this.createResponse(200,i)}}getGetActionMap(e,t){return {discover:async()=>{let i=await this.client.discover();return this.createResponse(200,i)},"health-check":async()=>{let i=await this.client.healthCheck();return this.createResponse(200,i)},code:async()=>{let i=await this.client.getCode(e,t);return this.createResponse(200,i)}}}async handlePostAction(e,t){if(Object.values(q).includes(e)){let i=t[e];return i()}else throw new H(e,q)}async handleGetAction(e,t){if(Object.values(ee).includes(e)){let i=t[e];return i()}else throw new H(e,ee)}isBridgeError(e){return Object.values(E).includes(e?.code)}isPlatformError(e){return e?.statusCode>=400&&e?.statusCode<500}handleError(e){return this.isBridgeError(e)?(e.statusCode===500&&console.error(e),this.createError(e)):this.isPlatformError(e)?this.createError(e):(console.error(e),this.createError(new V))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new Ae;if(!this.client.secretKey)throw new _e;let[i,o]=t.split(",");if(!i||!o)throw new Ee;let[a,c]=i.split("="),[p,d]=o.split("=");if(Number(a)<Date.now()-1500)throw new Re;if(!(this.hashHmac(this.client.secretKey,`${c}.${JSON.stringify(e)}`)===d))throw new Oe}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var l={output:{type:"object",properties:{},required:[],additionalProperties:!0}};var $t={type:"object",properties:{webhookUrl:{type:"string",format:"uri"},text:{type:"string"},blocks:{type:"array",items:{type:"object",properties:{type:{enum:["image","context","actions","divider","section","input","file","header","video","rich_text"]}},required:["type"],additionalProperties:!0}}},additionalProperties:!0},et={output:$t};var tt={[shared.ChatProviderIdEnum.Discord]:l,[shared.ChatProviderIdEnum.GetStream]:l,[shared.ChatProviderIdEnum.GrafanaOnCall]:l,[shared.ChatProviderIdEnum.Mattermost]:l,[shared.ChatProviderIdEnum.MsTeams]:l,[shared.ChatProviderIdEnum.RocketChat]:l,[shared.ChatProviderIdEnum.Ryver]:l,[shared.ChatProviderIdEnum.Slack]:et,[shared.ChatProviderIdEnum.WhatsAppBusiness]:l,[shared.ChatProviderIdEnum.Zulip]:l};var qt={type:"object",properties:{to:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:'Email address of the recipient(s). Example: "Bob bob@host.com". You can use commas to separate multiple recipients (e.g.: "test@example.com,test@example.com" or ["test@example.com", "test@example.com"]).'},from:{type:"string"},subject:{type:"string",description:"Subject of the message."},text:{type:"string",description:"Text version of the message."},html:{type:"string",description:"HTML version of the message."},message:{type:"string",description:"MIME string of the message. Make sure to use multipart/form-data to send this as a file upload."},cc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for carbon copy"},bcc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for blind carbon copy"},ampHtml:{type:"string"},tVersion:{type:"string"},tText:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oTag:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Tag string. See Tagging for more information."},oDkim:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables/disabled DKIM signatures on per-message basis. Pass yes or no"},oDeliverytime:{type:"string",description:"Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future."},oDeliverytimeOptimizePeriod:{type:"string"},oTimeZoneLocalize:{type:"string"},oTestmode:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables sending in test mode. Pass yes if needed. See Sending in Test Mode"},oTracking:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no."},oTrackingClicks:{anyOf:[{type:"string",enum:["yes","no","htmlonly"]},{type:"boolean"}],description:"Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly."},oTrackingOpens:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no."},oRequireTls:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oSkipVerification:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},recipientVariables:{type:"string"}},required:[],additionalProperties:!0},it={output:qt};var M={type:"object",properties:{name:{type:"string"},email:{type:"string"}},description:'JSON object, containing 2 properties: Name and Email address of a previously validated and active sender. Including the Name property in the JSON is optional. This property is not mandatory in case you use TemplateID and you specified a From address for the template. Format : { "Email":"value", "Name":"value" }.',required:["Email"],additionalProperties:!0},Bt={type:"object",properties:{contentType:{type:"string"},filename:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},zt={type:"object",properties:{filename:{type:"string"},contentType:{type:"string"},contentId:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},Ht={type:"object",properties:{from:M,sender:M,to:{type:"array",items:M},cc:{type:"array",items:M},bcc:{type:"array",items:M},replyTo:M,subject:{type:"string"},textPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},htmlPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},templateId:{type:"number",description:"an ID for a template that is previously created and stored in Mailjet's system. It is mandatory when From and TextPart and/or HtmlPart are not provided. "},templateLanguage:{type:"boolean"},templateErrorReporting:M,templateErrorDeliver:{type:"boolean"},attachments:{type:"array",items:Bt},inlineAttachments:{type:"array",items:zt},priority:{type:"number"},customCampaign:{type:"string"},deduplicateCampaign:{type:"boolean"},trackOpens:{type:"string",enum:["account_default","disabled","enabled"]},trackClicks:{type:"string",enum:["account_default","disabled","enabled"]},customId:{type:"string"},eventPayload:{type:"string"},urlTags:{type:"string"},headers:{type:"object",additionalProperties:!0},variables:{type:"object",additionalProperties:!0}},required:[],additionalProperties:!0},nt={output:Ht};var _={type:"object",properties:{address:{type:"string"},name:{type:"string"}},additionalProperties:!0},Fe={type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0},Kt={type:"object",properties:{from:{anyOf:[{type:"string"},_]},sender:{anyOf:[{type:"string"},_]},to:{anyOf:[{type:"string"},_,{type:"array",items:_}]},cc:{anyOf:[{type:"string"},_,{type:"array",items:_}]},bcc:{anyOf:[{type:"string"},_,{type:"array",items:_}]},replyTo:{anyOf:[{type:"string"},_,{type:"array",items:_}]},inReplyTo:{anyOf:[{type:"string"},_]},references:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},subject:{type:"string"},text:{anyOf:[{type:"string"},Fe]},html:{anyOf:[{type:"string"},Fe]},watchHtml:{anyOf:[{type:"string"},Fe]},amp:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},href:{type:"string"},encoding:{type:"string"},contentType:{type:"string"},raw:{anyOf:[{type:"string"},Fe]}}}]},icalEvent:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},method:{type:"string"},filename:{anyOf:[{type:"string"},{type:"boolean"}]},href:{type:"string"},encoding:{type:"string"}}}]},headers:{anyOf:[{type:"object",additionalProperties:!0},{type:"array",items:{type:"object",additionalProperties:!0}}]},list:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},attachments:{type:"array",items:{type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0}}},required:[],additionalProperties:!0},ot={output:Kt};var Xt={type:"object",properties:{},required:[],additionalProperties:!1},rt={output:Xt};var Jt={type:"object",properties:{personalizations:{type:"array",description:"An array of messages and their metadata. Each object within personalizations can be thought of as an envelope - it defines who should receive an individual message and how that message should be handled. See our [Personalizations documentation](https://sendgrid.com/docs/for-developers/sending-email/personalizations/) for examples.",uniqueItems:!1,maxItems:1e3,items:{type:"object",properties:{from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},to:{title:"To Email Array",type:"array",items:{type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},cc:{type:"array",description:"An array of recipients who will receive a copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},bcc:{type:"array",description:"An array of recipients who will receive a blind carbon copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},subject:{type:"string",description:"The subject of your email. See character length requirements according to [RFC 2822](http://stackoverflow.com/questions/1592291/what-is-the-email-subject-length-limit#answer-1592310).",minLength:1},headers:{type:"object",description:"A collection of JSON key/value pairs allowing you to specify handling instructions for your email. You may not overwrite the following headers: `x-sg-id`, `x-sg-eid`, `received`, `dkim-signature`, `Content-Type`, `Content-Transfer-Encoding`, `To`, `From`, `Subject`, `Reply-To`, `CC`, `BCC`"},substitutions:{type:"object",description:'Substitutions allow you to insert data without using Dynamic Transactional Templates. This field should **not** be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "substitutionTag":"value to substitute". The key/value pairs must be strings. These substitutions will apply to the text and html content of the body of your email, in addition to the `subject` and `reply-to` parameters. The total collective size of your substitutions may not exceed 10,000 bytes per personalization object.',maxProperties:1e4},dynamicTemplateData:{type:"object",description:'Dynamic template data is available using Handlebars syntax in Dynamic Transactional Templates. This field should be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "variable_name":"value to insert".'},customArgs:{type:"object",description:"Values that are specific to this personalization that will be carried along with the email and its activity data. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This field may not exceed 10,000 bytes.",maxProperties:1e4},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when your email should be delivered. Scheduling delivery more than 72 hours in advance is forbidden."}},required:["to"]}},from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},replyTo:{title:"Reply_to Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The email address where any replies or bounces will be returned."},name:{type:"string",description:"A name or title associated with the `replyTo` email address."}},required:["email"]},replyToList:{type:"array",description:"An array of recipients who will receive replies and/or bounces. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name. You can either choose to use \u201CreplyTo\u201D field or \u201CreplyToList\u201D but not both.",uniqueItems:!0,maxItems:1e3,items:{type:"object",properties:{email:{type:"string",description:"The email address where any replies or bounces will be returned.",format:"email"},name:{type:"string",description:"A name or title associated with the `replyToList` email address."}},required:["email"]}},subject:{type:"string",description:"The global or 'message level' subject of your email. This may be overridden by subject lines set in personalizations.",minLength:1},content:{type:"array",description:"An array where you can specify the content of your email. You can include multiple [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of content, but you must specify at least one MIME type. To include more than one MIME type, add another object to the array containing the `type` and `value` parameters.",items:{type:"object",properties:{type:{type:"string",description:"The MIME type of the content you are including in your email (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},value:{type:"string",description:"The actual content of the specified MIME type that you are including in your email.",minLength:1}},required:["type","value"]}},attachments:{type:"array",description:"An array of objects where you can specify any attachments you want to include.",items:{type:"object",properties:{content:{type:"string",description:"The Base64 encoded content of the attachment.",minLength:1},type:{type:"string",description:"The MIME type of the content you are attaching (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},filename:{type:"string",description:"The attachment's filename."},disposition:{type:"string",default:"attachment",description:"The attachment's content-disposition, specifying how you would like the attachment to be displayed. For example, `\u201Cinline\u201D` results in the attached file are displayed automatically within the message while `\u201Cattachment\u201D` results in the attached file require some action to be taken before it is displayed, such as opening or downloading the file.",enum:["inline","attachment"]},contentId:{type:"string",description:"The attachment's content ID. This is used when the disposition is set to `\u201Cinline\u201D` and the attachment is an image, allowing the file to be displayed within the body of your email."}},required:["content","filename"]}},templateId:{type:"string",description:"An email template ID. A template that contains a subject and content \u2014 either text or html \u2014 will override any subject and content values specified at the personalizations or message level."},headers:{description:"An object containing key/value pairs of header names and the value to substitute for them. The key/value pairs must be strings. You must ensure these are properly encoded if they contain unicode characters. These headers cannot be one of the reserved headers.",type:"object"},categories:{type:"array",description:"An array of category names for this message. Each category name may not exceed 255 characters. ",uniqueItems:!0,maxItems:10,items:{type:"string",maxLength:255}},customArgs:{description:"Values that are specific to the entire send that will be carried along with the email and its activity data. Key/value pairs must be strings. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This parameter is overridden by `customArgs` set at the personalizations level. Total `customArgs` size may not exceed 10,000 bytes.",type:"string"},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when you want your email to be delivered. This may be overridden by the `sendAt` parameter set at the personalizations level. Delivery cannot be scheduled more than 72 hours in advance. If you have the flexibility, it's better to schedule mail for off-peak times. Most emails are scheduled and sent at the top of the hour or half hour. Scheduling email to avoid peak times \u2014 for example, scheduling at 10:53 \u2014 can result in lower deferral rates due to the reduced traffic during off-peak times."},batchId:{type:"string",description:"An ID representing a batch of emails to be sent at the same time. Including a `batchId` in your request allows you include this email in that batch. It also enables you to cancel or pause the delivery of that batch. For more information, see the [Cancel Scheduled Sends API](https://sendgrid.com/docs/api-reference/)."},asm:{type:"object",description:"An object allowing you to specify how to handle unsubscribes.",properties:{groupId:{type:"integer",description:"The unsubscribe group to associate with this email."},groupsToDisplay:{type:"array",description:"An array containing the unsubscribe groups that you would like to be displayed on the unsubscribe preferences page.",maxItems:25,items:{type:"integer"}}},required:["groupId"]},ipPoolName:{type:"string",description:"The IP Pool that you would like to send this email from.",minLength:2,maxLength:64},mailSettings:{type:"object",description:"A collection of different mail settings that you can use to specify how you would like this email to be handled.",properties:{bypassListManagement:{type:"object",description:"Allows you to bypass all unsubscribe groups and suppressions to ensure that the email is delivered to every single recipient. This should only be used in emergencies when it is absolutely necessary that every recipient receives your email. This filter cannot be combined with any other bypass filters. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassSpamManagement:{type:"object",description:"Allows you to bypass the spam report list to ensure that the email is delivered to recipients. Bounce and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassBounceManagement:{type:"object",description:"Allows you to bypass the bounce list to ensure that the email is delivered to recipients. Spam report and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassUnsubscribeManagement:{type:"object",description:"Allows you to bypass the global unsubscribe list to ensure that the email is delivered to recipients. Bounce and spam report lists will still be checked; addresses on these other lists will not receive the message. This filter applies only to global unsubscribes and will not bypass group unsubscribes. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},footer:{type:"object",description:"The default footer that you would like included on every email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"The plain text content of your footer."},html:{type:"string",description:"The HTML content of your footer."}}},sandboxMode:{type:"object",description:"Sandbox Mode allows you to send a test email to ensure that your request body is valid and formatted correctly.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}}}},trackingSettings:{type:"object",description:"Settings to determine how you would like to track the metrics of how your recipients interact with your email.",properties:{clickTracking:{type:"object",description:"Allows you to track if a recipient clicked a link in your email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},enableText:{type:"boolean",description:"Indicates if this setting should be included in the `text/plain` portion of your email."}}},openTracking:{type:"object",description:"Allows you to track if the email was opened by including a single pixel image in the body of the content. When the pixel is loaded, Twilio SendGrid can log that the email was opened.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},substitutionTag:{type:"string",description:"Allows you to specify a substitution tag that you can insert in the body of your email at a location that you desire. This tag will be replaced by the open tracking pixel."}}},subscriptionTracking:{type:"object",description:"Allows you to insert a subscription management link at the bottom of the text and HTML bodies of your email. If you would like to specify the location of the link within your email, you may use the `substitutionTag`.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"Text to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},html:{type:"string",description:"HTML to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},substitutionTag:{type:"string",description:"A tag that will be replaced with the unsubscribe URL. for example: `[unsubscribe_url]`. If this parameter is used, it will override both the `text` and `html` parameters. The URL of the link will be placed at the substitution tag\u2019s location with no additional formatting."}}},ganalytics:{type:"object",description:"Allows you to enable tracking provided by Google Analytics.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},utmSource:{type:"string",description:"Name of the referrer source. (e.g. Google, SomeDomain.com, or Marketing Email)"},utmMedium:{type:"string",description:"Name of the marketing medium. (e.g. Email)"},utmTerm:{type:"string",description:"Used to identify any paid keywords."},utmContent:{type:"string",description:"Used to differentiate your campaign from advertisements."},utmCampaign:{type:"string",description:"The name of the campaign."}}}}}},required:[],additionalProperties:!1},st={output:Jt};var at={[shared.EmailProviderIdEnum.Braze]:l,[shared.EmailProviderIdEnum.Clickatell]:l,[shared.EmailProviderIdEnum.CustomSMTP]:ot,[shared.EmailProviderIdEnum.EmailJS]:l,[shared.EmailProviderIdEnum.EmailWebhook]:l,[shared.EmailProviderIdEnum.Infobip]:l,[shared.EmailProviderIdEnum.MailerSend]:l,[shared.EmailProviderIdEnum.Mailgun]:it,[shared.EmailProviderIdEnum.Mailjet]:nt,[shared.EmailProviderIdEnum.Mailtrap]:l,[shared.EmailProviderIdEnum.Mandrill]:l,[shared.EmailProviderIdEnum.NetCore]:l,[shared.EmailProviderIdEnum.Novu]:rt,[shared.EmailProviderIdEnum.Outlook365]:l,[shared.EmailProviderIdEnum.Plunk]:l,[shared.EmailProviderIdEnum.Postmark]:l,[shared.EmailProviderIdEnum.Resend]:l,[shared.EmailProviderIdEnum.SendGrid]:st,[shared.EmailProviderIdEnum.Sendinblue]:l,[shared.EmailProviderIdEnum.SES]:l,[shared.EmailProviderIdEnum.SparkPost]:l};var Zt={type:"object",properties:{},required:[],additionalProperties:!1},ct={output:Zt};var lt={[shared.InAppProviderIdEnum.Novu]:ct};var pt={anyOf:[{type:"string"},{type:"object",additionalProperties:!0,properties:{name:{type:"string"},volume:{type:"number"},critical:{type:"number"}},required:["name","volume","critical"]}]},ei={type:"object",properties:{topic:{type:"string",description:"The destination topic for the notification."},id:{type:"string",description:"A UUID to identify the notification with APNS. If an id is not supplied, APNS will generate one automatically. If an error occurs the response will contain the id. This property populates the apns-id header."},expiry:{type:"number",description:"A UNIX timestamp when the notification should expire. If the notification cannot be delivered to the device, APNS will retry until it expires. An expiry of 0 indicates that the notification expires immediately, therefore no retries will be attempted."},priority:{type:"number",description:`Provide one of the following values:
|
|
28
28
|
|
|
29
29
|
10 - The push notification is sent to the device immediately. (Default)
|
|
30
30
|
The push notification must trigger an alert, sound, or badge on the device. It is an error to use this priority for a push notification that contains only the content-available key.
|
|
@@ -457,7 +457,7 @@ exports.ResourceEnum = ne;
|
|
|
457
457
|
exports.SDK_VERSION = B;
|
|
458
458
|
exports.SIGNATURE_TIMESTAMP_TOLERANCE = qe;
|
|
459
459
|
exports.SIGNATURE_TIMESTAMP_TOLERANCE_MINUTES = $e;
|
|
460
|
-
exports.WorkflowChannelEnum =
|
|
460
|
+
exports.WorkflowChannelEnum = Ke;
|
|
461
461
|
exports.actionStepSchemas = ui;
|
|
462
462
|
exports.channelStepSchemas = O;
|
|
463
463
|
exports.workflow = Ls;
|
package/dist/servers/express.js
CHANGED
|
@@ -7,7 +7,7 @@ var le = require('ora');
|
|
|
7
7
|
require('cross-fetch');
|
|
8
8
|
var N = require('chalk');
|
|
9
9
|
var shared = require('@novu/shared');
|
|
10
|
-
var
|
|
10
|
+
var Ie = require('sanitize-html');
|
|
11
11
|
var ke = require('ajv');
|
|
12
12
|
var Ve = require('ajv-formats');
|
|
13
13
|
var zodToJsonSchema = require('zod-to-json-schema');
|
|
@@ -16,15 +16,15 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
16
16
|
|
|
17
17
|
var le__default = /*#__PURE__*/_interopDefault(le);
|
|
18
18
|
var N__default = /*#__PURE__*/_interopDefault(N);
|
|
19
|
-
var
|
|
19
|
+
var Ie__default = /*#__PURE__*/_interopDefault(Ie);
|
|
20
20
|
var ke__default = /*#__PURE__*/_interopDefault(ke);
|
|
21
21
|
var Ve__default = /*#__PURE__*/_interopDefault(Ve);
|
|
22
22
|
|
|
23
|
-
var y=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(y||{}),M=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(M||{});var R=(c=>(c.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",c.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",c.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",c.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",c.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",c.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",c.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",c.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",c.STEP_NOT_FOUND_ERROR="StepNotFoundError",c.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",c.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",c.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",c.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",c.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",c.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",c.STEP_CONTROL_COMPILATION_FAILED_ERROR="StepControlCompilationFailedError",c.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",c.INVALID_ACTION_ERROR="InvalidActionError",c.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",c.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",c.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",c.SIGNATURE_INVALID_ERROR="SignatureInvalidError",c.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",c.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",c.BRIDGE_ERROR="BridgeError",c.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",c.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",c))(R||{});var Y=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(Y||{});var ue=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(ue||{});var Te="2.1.1";var D=Te,F="2024-06-26";var O=class extends Error{data},L=class extends O{statusCode=404},u=class extends O{statusCode=400},I=class extends O{statusCode=401},f=class extends O{statusCode=500},C=class extends O{statusCode=409};var b=class extends u{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},P=class extends u{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},W=class extends u{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},$=class extends u{code="ExecutionStateControlInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=r;}},G=class extends u{code="ExecutionStateOutputInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=r;}},j=class extends u{code="ExecutionStateResultInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=r;}},K=class extends u{code="StepControlCompilationFailedError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has invalid controls syntax in step with id: \`${t}\`. Please correct step control syntax.`),this.data=r;}},B=class extends u{code="ExecutionProviderOutputInvalidError";constructor(e,t,r,o){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${r}\` has invalid output. Please provide the correct provider output.`),this.data=o;}};var X=class extends O{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var l={info:s=>N__default.default.blue(s),warning:s=>N__default.default.yellow(s),error:s=>N__default.default.red(s),success:s=>N__default.default.green(s),underline:s=>N__default.default.underline(s),bold:s=>N__default.default.bold(s)},p={SUCCESS:l.success("\u2714"),ERROR:l.error("\u2717"),WARNING:l.warning("\u26A0"),INFO:l.info("\u2139"),ARROW:l.bold("\u2192"),MOCK:l.info("\u25CB"),HYDRATED:l.bold(l.info("\u2192")),STEP:l.info("\u03C3"),ACTION:l.info("\u03B1"),DURATION:l.info("\u0394"),PROVIDER:l.info("\u2699"),OUTPUT:l.info("\u21E2"),INPUT:l.info("\u21E0"),WORKFLOW:l.info("\u03C9"),STATE:l.info("\u03C3"),EXECUTE:l.info("\u03B5"),PREVIEW:l.info("\u03C1")};var Re=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),J=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Ae=(s,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(r,o)=>{let i=await fetch(`${t}/v1${r}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`},body:JSON.stringify(o)}),a=await i.json();if(i.ok)return a;throw shared.checkIsResponseError(a)?new X(a.statusCode,a.error,a.message):new v("Error processing API request to Novu Cloud from Bridge application.")},delete:async r=>(await fetch(`${t}/v1${r}`,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`}})).json()}};var Pe={allowedTags:me__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Ie=s=>{if(!s)return s;let e=/^<!DOCTYPE .*?>/,t=s.match(e),r=me__default.default(s,Pe);return t?t[0]+r:r},z=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Ie(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Ie(o):typeof o=="object"?z(o):o):typeof r=="object"&&r!==null?e[t]=z(r):e[t]=r,e},{});var q=class extends O{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${Re(Y)}`},x=class extends u{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${Re(t)}`);}};var v=class extends f{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends C{constructor(e,t){super(`${J(e)} with id: \`${t}\` already exists. Please use a different id.`);}},m=class extends L{constructor(e,t){super(`${J(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},g=class extends f{constructor(e,t){super(`Failed to execute ${J(e)} with id: \`${t}\`. Please try again later.`);}};var Z=class extends m{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Q=class extends g{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var H=class extends I{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},ee=class extends I{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},te=class extends I{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},re=class extends I{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},oe=class extends I{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var se=class extends m{code="StepNotFoundError";constructor(e){super("step",e);}};var k=class extends m{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},ie=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var fe=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var ae=class{ajv;compiledSchemas;constructor(){this.ajv=new ke__default.default({useDefaults:!0,removeAdditional:"failing"}),Ve__default.default(this.ajv),this.compiledSchemas=new Map;}canHandle(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.allOf||!!e.oneOf}async validate(e,t){let r=this.compiledSchemas.get(t);r||(r=this.ajv.compile(t),this.compiledSchemas.set(t,r));let o=fe(e);return r(o)?{success:!0,data:o}:{success:!1,errors:r.errors.map(a=>({path:a.instancePath,message:a.message}))}}transformToJsonSchema(e){return e}};var ne=class{canHandle(e){return e.safeParseAsync!==void 0}async validate(e,t){let r=t.safeParse(e);return r.success?{success:!0,data:r.data}:{success:!1,errors:r.error.errors.map(o=>({path:`/${o.path.join("/")}`,message:o.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var ce=new ne,de=new ae,Ne=async(s,e)=>{if(ce.canHandle(s))return ce.validate(e,s);if(de.canHandle(s))return de.validate(e,s);throw new Error("Invalid schema")},ve=s=>{if(ce.canHandle(s))return ce.transformToJsonSchema(s);if(de.canHandle(s))return de.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Fe(){return ["development",void 0].includes(process.env.NODE_ENV)}var pe=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=D;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Fe()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(r=>r.workflowId===t.definition.workflowId))throw new ie(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((r,o)=>r+o.steps.length,0);return {status:"ok",sdkVersion:D,frameworkVersion:F,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new k(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new se(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(ve(e))}async validate(e,t,r,o,i,a,d){let n=await Ne(t,e);if(n.success)return n.data;switch(r){case"event":this.throwInvalidEvent(o,i,n.errors);case"step":this.throwInvalidStep(a,o,i,n.errors);case"provider":this.throwInvalidProvider(a,d,o,i,n.errors);default:throw new Error(`Invalid component: '${r}'`)}}throwInvalidProvider(e,t,r,o,i){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(r){case"output":throw new B(o,e,t,i);default:throw new Error(`Invalid payload type: '${r}'`)}}throwInvalidStep(e,t,r,o){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new G(r,e,o);case"result":throw new j(r,e,o);case"controls":throw new $(r,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,r){switch(e){case"controls":throw new W(t,r);case"payload":throw new P(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let a=this.getStep(e.workflowId,r),d=await this.createStepControls(a,e),n=e.action==="preview";if(!n&&await this.shouldSkip(i?.skip,d))return r===e.stepId&&t({options:{skip:!0},outputs:{},providers:{}}),{};let E=this.previewStep.bind(this),_=this.executeStep.bind(this),T=await(n?E:_)(e,{...a,providers:a.providers.map(S=>{let V=i?.providers?.[S.type];if(!V)throw new Z(S.type);return {...S,resolve:V}}),resolve:o});return Object.values(ue).includes(a.type)&&(T={...T,outputs:z(T.outputs)}),r===e.stepId&&t({...T,options:{skip:!1}}),T.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action"} workflowId:`;console.log(`
|
|
24
|
-
${l.bold(l.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),a=process.hrtime(),d={outputs:{},providers:{},options:{skip:!1}},n,
|
|
23
|
+
var y=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(y||{}),M=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(M||{});var R=(c=>(c.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",c.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",c.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",c.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",c.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",c.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",c.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",c.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",c.STEP_NOT_FOUND_ERROR="StepNotFoundError",c.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",c.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",c.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",c.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",c.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",c.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",c.STEP_CONTROL_COMPILATION_FAILED_ERROR="StepControlCompilationFailedError",c.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",c.INVALID_ACTION_ERROR="InvalidActionError",c.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",c.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",c.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",c.SIGNATURE_INVALID_ERROR="SignatureInvalidError",c.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",c.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",c.BRIDGE_ERROR="BridgeError",c.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",c.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",c))(R||{});var Y=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(Y||{});var _e=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(_e||{});var Te="2.2.0";var D=Te,F="2024-06-26";var E=class extends Error{data},L=class extends E{statusCode=404},_=class extends E{statusCode=400},m=class extends E{statusCode=401},f=class extends E{statusCode=500},C=class extends E{statusCode=409};var b=class extends _{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},P=class extends _{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},W=class extends _{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},$=class extends _{code="ExecutionStateControlInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=r;}},j=class extends _{code="ExecutionStateOutputInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=r;}},G=class extends _{code="ExecutionStateResultInvalidError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=r;}},K=class extends _{code="StepControlCompilationFailedError";constructor(e,t,r){super(`Workflow with id: \`${e}\` has invalid controls syntax in step with id: \`${t}\`. Please correct step control syntax.`),this.data=r;}},B=class extends _{code="ExecutionProviderOutputInvalidError";constructor(e,t,r,o){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${r}\` has invalid output. Please provide the correct provider output.`),this.data=o;}};var X=class extends E{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var l={info:s=>N__default.default.blue(s),warning:s=>N__default.default.yellow(s),error:s=>N__default.default.red(s),success:s=>N__default.default.green(s),underline:s=>N__default.default.underline(s),bold:s=>N__default.default.bold(s)},p={SUCCESS:l.success("\u2714"),ERROR:l.error("\u2717"),WARNING:l.warning("\u26A0"),INFO:l.info("\u2139"),ARROW:l.bold("\u2192"),MOCK:l.info("\u25CB"),HYDRATED:l.bold(l.info("\u2192")),STEP:l.info("\u03C3"),ACTION:l.info("\u03B1"),DURATION:l.info("\u0394"),PROVIDER:l.info("\u2699"),OUTPUT:l.info("\u21E2"),INPUT:l.info("\u21E0"),WORKFLOW:l.info("\u03C9"),STATE:l.info("\u03C3"),EXECUTE:l.info("\u03B5"),PREVIEW:l.info("\u03C1")};var Re=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),J=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Ae=(s,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(r,o)=>{let i=await fetch(`${t}/v1${r}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`},body:JSON.stringify(o)}),a=await i.json();if(i.ok)return a;throw shared.checkIsResponseError(a)?new X(a.statusCode,a.error,a.message):new v("Error processing API request to Novu Cloud from Bridge application.")},delete:async r=>(await fetch(`${t}/v1${r}`,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`}})).json()}};var Pe={allowedTags:Ie__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},me=s=>{if(!s)return s;let e=/^<!DOCTYPE .*?>/,t=s.match(e),r=Ie__default.default(s,Pe);return t?t[0]+r:r},z=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=me(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?me(o):typeof o=="object"?z(o):o):typeof r=="object"&&r!==null?e[t]=z(r):e[t]=r,e},{});var q=class extends E{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${Re(Y)}`},x=class extends _{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${Re(t)}`);}};var v=class extends f{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends C{constructor(e,t){super(`${J(e)} with id: \`${t}\` already exists. Please use a different id.`);}},I=class extends L{constructor(e,t){super(`${J(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},g=class extends f{constructor(e,t){super(`Failed to execute ${J(e)} with id: \`${t}\`. Please try again later.`);}};var Z=class extends I{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Q=class extends g{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var H=class extends m{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},ee=class extends m{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},te=class extends m{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},re=class extends m{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},oe=class extends m{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var se=class extends I{code="StepNotFoundError";constructor(e){super("step",e);}};var k=class extends I{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},ie=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var fe=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var ae=class{ajv;compiledSchemas;constructor(){this.ajv=new ke__default.default({useDefaults:!0,removeAdditional:"failing"}),Ve__default.default(this.ajv),this.compiledSchemas=new Map;}canHandle(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.allOf||!!e.oneOf}async validate(e,t){let r=this.compiledSchemas.get(t);r||(r=this.ajv.compile(t),this.compiledSchemas.set(t,r));let o=fe(e);return r(o)?{success:!0,data:o}:{success:!1,errors:r.errors.map(a=>({path:a.instancePath,message:a.message}))}}transformToJsonSchema(e){return e}};var ne=class{canHandle(e){return e.safeParseAsync!==void 0}async validate(e,t){let r=t.safeParse(e);return r.success?{success:!0,data:r.data}:{success:!1,errors:r.error.errors.map(o=>({path:`/${o.path.join("/")}`,message:o.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var ce=new ne,de=new ae,Ne=async(s,e)=>{if(ce.canHandle(s))return ce.validate(e,s);if(de.canHandle(s))return de.validate(e,s);throw new Error("Invalid schema")},ve=s=>{if(ce.canHandle(s))return ce.transformToJsonSchema(s);if(de.canHandle(s))return de.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Fe(){return ["development",void 0].includes(process.env.NODE_ENV)}var pe=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=D;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Fe()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(r=>r.workflowId===t.definition.workflowId))throw new ie(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((r,o)=>r+o.steps.length,0);return {status:"ok",sdkVersion:D,frameworkVersion:F,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new k(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new se(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(ve(e))}async validate(e,t,r,o,i,a,d){let n=await Ne(t,e);if(n.success)return n.data;switch(r){case"event":this.throwInvalidEvent(o,i,n.errors);case"step":this.throwInvalidStep(a,o,i,n.errors);case"provider":this.throwInvalidProvider(a,d,o,i,n.errors);default:throw new Error(`Invalid component: '${r}'`)}}throwInvalidProvider(e,t,r,o,i){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(r){case"output":throw new B(o,e,t,i);default:throw new Error(`Invalid payload type: '${r}'`)}}throwInvalidStep(e,t,r,o){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new j(r,e,o);case"result":throw new G(r,e,o);case"controls":throw new $(r,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,r){switch(e){case"controls":throw new W(t,r);case"payload":throw new P(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let a=this.getStep(e.workflowId,r),d=await this.createStepControls(a,e),n=e.action==="preview";if(!n&&await this.shouldSkip(i?.skip,d))return r===e.stepId&&t({options:{skip:!0},outputs:{},providers:{}}),{};let O=this.previewStep.bind(this),u=this.executeStep.bind(this),T=await(n?O:u)(e,{...a,providers:a.providers.map(S=>{let V=i?.providers?.[S.type];if(!V)throw new Z(S.type);return {...S,resolve:V}}),resolve:o});return Object.values(_e).includes(a.type)&&i?.disableOutputSanitization!==!0&&(T={...T,outputs:z(T.outputs)}),r===e.stepId&&t({...T,options:{skip:!1}}),T.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action"} workflowId:`;console.log(`
|
|
24
|
+
${l.bold(l.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),a=process.hrtime(),d={outputs:{},providers:{},options:{skip:!1}},n,O=new Promise(h=>{n=h;}),u=h=>{n(),d=h;},w;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new P(e.workflowId,{message:"Event `payload` is required"});let h=await this.createExecutionPayload(e,i),A={...e,payload:h};await Promise.race([O,i.execute({payload:h,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(A,u),sms:this.executeStepFactory(A,u),inApp:this.executeStepFactory(A,u),digest:this.executeStepFactory(A,u),delay:this.executeStepFactory(A,u),push:this.executeStepFactory(A,u),chat:this.executeStepFactory(A,u),custom:this.executeStepFactory(A,u)}})]);}catch(h){w=h;}let T=process.hrtime(a),S=T[0],V=T[1],Oe=S*1e3+V/1e6,ge=w?p.ERROR:p.SUCCESS,Se=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${ge} ${Se} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,Oe,w),w)throw w;return {outputs:d.outputs,providers:d.providers,options:d.options,metadata:{status:"success",error:!1,duration:Oe}}}async createExecutionPayload(e,t){let r=e.payload||e.data;if(e.action==="preview"){let i=this.mock(t.payload.schema);r=Object.assign(i,r);}return await this.validate(r,t.payload.unknownSchema,"event","payload",e.workflowId)}prettyPrintExecute(e,t,r){let o=r?p.ERROR:p.SUCCESS,i=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",a=r?"Failed to execute":i,d=r?l.error:l.success,n=`${o} ${a} workflowId: '${e.workflowId}`;console.log(`
|
|
25
25
|
${l.bold(d(n))}'`),console.log(` \u251C ${p.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${p.ACTION} action: '${e.action}'`),console.log(` \u2514 ${p.DURATION} duration: '${t.toFixed(2)}ms'
|
|
26
|
-
`);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let a=await o,d=this.previewProvider.bind(this),n=this.executeProvider.bind(this),
|
|
27
|
-
${a.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=le__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),a=await t.resolve(i),d=await this.validate(a,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),n=await this.executeProviders(e,t,d);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:d,providers:n}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:p.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=le__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let o=e.state.find(i=>i.stepId===t.stepId);if(o){let i=await this.validate(o.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:i,providers:await this.executeProviders(e,t,i)}}else throw new b(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){try{let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{payload:t.payload||t.data,subscriber:t.subscriber,...t.payload||t.data});return JSON.parse(o)}catch(r){throw new K(t.workflowId,t.stepId,r)}}async createStepControls(e,t){let r=t.controls||t.inputs;return await this.validate(r,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let r=le__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),a=await t.resolve(i),d=await this.validate(a,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:d,providers:await this.executeProviders(e,t,d)}}else {let o=this.mock(t.results.schema);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),o}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let r;if(e)t?r=this.getStepCode(e,t):r=this.getWorkflowCode(e);else throw new k(e);return r}};var
|
|
26
|
+
`);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let a=await o,d=this.previewProvider.bind(this),n=this.executeProvider.bind(this),u=await(e.action==="preview"?d:n)(e,t,i,r);return {...a,[i.type]:u}},Promise.resolve({}))}previewProvider(e,t,r,o){return console.log(` ${p.MOCK} Mocked provider: \`${r.type}\``),this.mock(r.outputs.schema)}async executeProvider(e,t,r,o){let i=le__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let a=await this.createStepControls(t,e),d=await r.resolve({controls:a,outputs:o}),n=await this.validate(d,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),{...n,_passthrough:d._passthrough}}else return i.stopAndPersist({symbol:p.HYDRATED,text:`Hydrated provider: \`${r.type}\``}),{}}catch(a){throw i.stopAndPersist({symbol:p.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new Q(`Failed to execute provider: '${r.type}'.
|
|
27
|
+
${a.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=le__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),a=await t.resolve(i),d=await this.validate(a,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),n=await this.executeProviders(e,t,d);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:d,providers:n}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:p.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=le__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let o=e.state.find(i=>i.stepId===t.stepId);if(o){let i=await this.validate(o.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:i,providers:await this.executeProviders(e,t,i)}}else throw new b(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){try{let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{payload:t.payload||t.data,subscriber:t.subscriber,...t.payload||t.data});return JSON.parse(o)}catch(r){throw new K(t.workflowId,t.stepId,r)}}async createStepControls(e,t){let r=t.controls||t.inputs;return await this.validate(r,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let r=le__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),a=await t.resolve(i),d=await this.validate(a,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:d,providers:await this.executeProviders(e,t,d)}}else {let o=this.mock(t.results.schema);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),o}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let r;if(e)t?r=this.getStepCode(e,t):r=this.getWorkflowCode(e);else throw new k(e);return r}};var ue=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new pe,this.client.addWorkflows(e.workflows),this.http=Ae(this.client.secretKey),this.frameworkName=e.frameworkName,this.hmacEnabled=this.client.strictAuthentication;}createHandler(){return async(...e)=>{let t=await this.handler(...e),r=await this.handleAction({actions:t});return t.transformResponse(r)}}getStaticHeaders(){let e=`novu-framework:v${this.client.version}`;return {"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST","access-control-allow-headers":"*","access-control-max-age":"604800","novu-framework-version":F,"novu-framework-sdk":D,"novu-framework-server":this.frameworkName,"user-agent":e}}createResponse(e,t){return {status:e,body:JSON.stringify(t),headers:{...this.getStaticHeaders()}}}createError(e){return {status:e.statusCode,body:JSON.stringify({message:e.message,data:e.data,code:e.code}),headers:this.getStaticHeaders()}}async handleAction({actions:e}){let t=await e.url(),r=await e.method(),o=t.searchParams.get("action")||"health-check",i=t.searchParams.get("workflowId")||"",a=t.searchParams.get("stepId")||"",d=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",n={};try{r==="POST"&&(n=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(n,d);let O=this.getPostActionMap(n,i,a,o),u=this.getGetActionMap(i,a);if(r==="POST")return await this.handlePostAction(o,O);if(r==="GET")return await this.handleGetAction(o,u);if(r==="OPTIONS")return this.createResponse(200,{})}catch(O){return this.handleError(O)}return this.createError(new q(r))}getPostActionMap(e,t,r,o){return {trigger:this.triggerAction({workflowId:t,...e}),execute:async()=>{let i=await this.client.executeWorkflow({...e,workflowId:t,stepId:r,action:o});return this.createResponse(200,i)},preview:async()=>{let i=await this.client.executeWorkflow({...e,workflowId:t,stepId:r,action:o});return this.createResponse(200,i)}}}triggerAction(e){return async()=>{let t={name:e.workflowId,to:e.to,payload:e?.payload||{},transactionId:e.transactionId,overrides:e.overrides||{},...e.actor&&{actor:e.actor},...e.bridgeUrl&&{bridgeUrl:e.bridgeUrl},...e.controls&&{controls:e.controls}},r=await this.http.post("/events/trigger",t);return this.createResponse(200,r)}}getGetActionMap(e,t){return {discover:async()=>{let r=await this.client.discover();return this.createResponse(200,r)},"health-check":async()=>{let r=await this.client.healthCheck();return this.createResponse(200,r)},code:async()=>{let r=await this.client.getCode(e,t);return this.createResponse(200,r)}}}async handlePostAction(e,t){if(Object.values(y).includes(e)){let r=t[e];return r()}else throw new x(e,y)}async handleGetAction(e,t){if(Object.values(M).includes(e)){let r=t[e];return r()}else throw new x(e,M)}isBridgeError(e){return Object.values(R).includes(e?.code)}isPlatformError(e){return e?.statusCode>=400&&e?.statusCode<500}handleError(e){return this.isBridgeError(e)?(e.statusCode===500&&console.error(e),this.createError(e)):this.isPlatformError(e)?this.createError(e):(console.error(e),this.createError(new v))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new ee;if(!this.client.secretKey)throw new oe;let[r,o]=t.split(",");if(!r||!o)throw new te;let[i,a]=r.split("="),[d,n]=o.split("=");if(Number(i)<Date.now()-1500)throw new re;if(!(this.hashHmac(this.client.secretKey,`${a}.${JSON.stringify(e)}`)===n))throw new H}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var be="express",qr=s=>new ue({frameworkName:be,...s,handler:(t,r)=>({body:()=>t.body,headers:o=>{let i=t.headers[o];return Array.isArray(i)?i[0]:i},method:()=>t.method||"GET",url:()=>{let o=t.headers.host||"",i=o?.includes("://")?"":`${t.protocol||"https"}://`;return new URL(t.originalUrl||t.url||"",`${i}${o||""}`)},queryString:o=>{let i=t.query[o];return Array.isArray(i)?i[0]:i},transformResponse:({body:o,headers:i,status:a})=>(Object.entries(i).forEach(([d,n])=>{r.setHeader(d,n);}),r.status(a).send(o))})}).createHandler();
|
|
28
28
|
|
|
29
29
|
exports.frameworkName = be;
|
|
30
30
|
exports.serve = qr;
|
package/dist/servers/h3.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { H3Event, EventHandlerRequest } from 'h3';
|
|
2
|
-
import { w as SupportedFrameworkName, c as ServeHandlerOptions } from '../handler-
|
|
2
|
+
import { w as SupportedFrameworkName, c as ServeHandlerOptions } from '../handler-TDgxEYp-.js';
|
|
3
3
|
import '@novu/shared';
|
|
4
4
|
import 'json-schema-to-ts';
|
|
5
5
|
import 'zod';
|