@novu/framework 2.0.0-canary.4 → 2.0.0-canary.6

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.
@@ -3,28 +3,28 @@
3
3
  var crypto = require('crypto');
4
4
  var jsonSchemaFaker = require('json-schema-faker');
5
5
  var liquidjs = require('liquidjs');
6
- var ae = require('ora');
6
+ var de = require('ora');
7
7
  var crossFetch = require('cross-fetch');
8
- var g = require('chalk');
8
+ var y = require('chalk');
9
9
  var shared = require('@novu/shared');
10
- var he = require('sanitize-html');
11
- var xe = require('ajv');
12
- var Ue = require('ajv-formats');
10
+ var fe = require('sanitize-html');
11
+ var Ue = require('ajv');
12
+ var Me = require('ajv-formats');
13
13
  var zodToJsonSchema = require('zod-to-json-schema');
14
14
 
15
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
16
 
17
- var ae__default = /*#__PURE__*/_interopDefault(ae);
18
- var g__default = /*#__PURE__*/_interopDefault(g);
19
- var he__default = /*#__PURE__*/_interopDefault(he);
20
- var xe__default = /*#__PURE__*/_interopDefault(xe);
17
+ var de__default = /*#__PURE__*/_interopDefault(de);
18
+ var y__default = /*#__PURE__*/_interopDefault(y);
19
+ var fe__default = /*#__PURE__*/_interopDefault(fe);
21
20
  var Ue__default = /*#__PURE__*/_interopDefault(Ue);
21
+ var Me__default = /*#__PURE__*/_interopDefault(Me);
22
22
 
23
- var S=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(S||{}),V=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(V||{});var A=(l=>(l.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",l.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",l.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",l.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",l.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",l.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",l.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",l.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",l.STEP_NOT_FOUND_ERROR="StepNotFoundError",l.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",l.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",l.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",l.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",l.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",l.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",l.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",l.INVALID_ACTION_ERROR="InvalidActionError",l.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",l.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",l.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",l.SIGNATURE_INVALID_ERROR="SignatureInvalidError",l.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",l.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",l.BRIDGE_ERROR="BridgeError",l.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",l.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",l))(A||{});var Y=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(Y||{});var le=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(le||{});var ue="2.0.0-canary.4";var P=ue,b="2024-06-26";var I=class extends Error{data},F=class extends I{statusCode=404},h=class extends I{statusCode=400},N=class extends I{statusCode=401},v=class extends I{statusCode=500},L=class extends I{statusCode=409};var C=class extends h{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};}},x=class extends h{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 h{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},$=class extends h{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 h{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 h{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 h{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 q=class extends I{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var Ee=()=>typeof Response<"u"?Response:crossFetch.Response;var p={info:s=>g__default.default.blue(s),warning:s=>g__default.default.yellow(s),error:s=>g__default.default.red(s),success:s=>g__default.default.green(s),underline:s=>g__default.default.underline(s),bold:s=>g__default.default.bold(s)},u={SUCCESS:p.success("\u2714"),ERROR:p.error("\u2717"),WARNING:p.warning("\u26A0"),INFO:p.info("\u2139"),ARROW:p.bold("\u2192"),MOCK:p.info("\u25CB"),HYDRATED:p.bold(p.info("\u2192")),STEP:p.info("\u03C3"),ACTION:p.info("\u03B1"),DURATION:p.info("\u0394"),PROVIDER:p.info("\u2699"),OUTPUT:p.info("\u21E2"),INPUT:p.info("\u21E0"),WORKFLOW:p.info("\u03C9"),STATE:p.info("\u03C3"),EXECUTE:p.info("\u03B5"),PREVIEW:p.info("\u03C1")};var pe=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),B=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Oe=(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)}),c=await i.json();if(i.ok)return c;throw shared.checkIsResponseError(c)?new q(c.statusCode,c.error,c.message):new y("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 De={allowedTags:he__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Te=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=he__default.default(s,De);return t?t[0]+r:r},X=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Te(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Te(o):typeof o=="object"?X(o):o):typeof r=="object"&&r!==null?e[t]=X(r):e[t]=r,e},{});var J=class extends I{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${pe(Y)}`},U=class extends h{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${pe(t)}`);}};var y=class extends v{code="BridgeError";message="Something went wrong. Please try again later."};var M=class extends L{constructor(e,t){super(`${B(e)} with id: \`${t}\` already exists. Please use a different id.`);}},w=class extends F{constructor(e,t){super(`${B(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},D=class extends v{constructor(e,t){super(`Failed to execute ${B(e)} with id: \`${t}\`. Please try again later.`);}};var z=class extends w{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Z=class extends D{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Q=class extends N{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.");}},H=class extends N{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},ee=class extends N{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},te=class extends N{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},re=class extends N{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var oe=class extends w{code="StepNotFoundError";constructor(e){super("step",e);}};var k=class extends w{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},se=class extends M{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var ie=class{ajv;compiledSchemas;constructor(){this.ajv=new xe__default.default({useDefaults:!0,removeAdditional:"all"}),Ue__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.oneOf}async validate(e,t){let r=this.compiledSchemas.get(t);return r||(r=this.ajv.compile(t),this.compiledSchemas.set(t,r)),r(e)?{success:!0,data:e}:{success:!1,errors:r.errors.map(i=>({path:i.instancePath,message:i.message}))}}transformToJsonSchema(e){return e}};var ne=class{isSchema(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 Ie=[new ne,new ie],fe=async(s,e)=>{for(let t of Ie)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},Ne=s=>{for(let e of Ie)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Ve(){return ["development",void 0].includes(process.env.NODE_ENV)}var ce=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=P;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Ve()};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 se(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:P,frameworkVersion:b,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 oe(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(Ne(e))}async validate(e,t,r,o,i,c,d){let n=await fe(t,e);if(n.success)return n.data;switch(r){case"event":this.throwInvalidEvent(o,i,n.errors);case"step":this.throwInvalidStep(c,o,i,n.errors);case"provider":this.throwInvalidProvider(c,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 K(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 x(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let c=this.getStep(e.workflowId,r),d=Ye(e),n=await this.createStepControls(c,d),_=e.action==="preview";if(!_&&await this.shouldSkip(i?.skip,n))return t({options:{skip:!0}}),{};let a=this.previewStep.bind(this),R=this.executeStep.bind(this),f=await(_?a:R)(e,{...c,providers:c.providers.map(E=>{let O=i?.providers?.[E.type];if(!O)throw new z(E.type);return {...E,resolve:O}}),resolve:o});return Object.values(le).includes(c.type)&&(f={...f,outputs:X(f.outputs)}),r===e.stepId&&t(f),f.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
24
- ${p.bold(p.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),c=process.hrtime(),d={outputs:{},providers:{},options:{}},n,_=new Promise(m=>{n=m;}),a=m=>{n(),d=m;},R;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new x(e.workflowId,{message:"Event `payload` is required"});let m=await this.createExecutionPayload(e,i);await Promise.race([_,i.execute({payload:m,environment:{},inputs:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(e,a),sms:this.executeStepFactory(e,a),inApp:this.executeStepFactory(e,a),digest:this.executeStepFactory(e,a),delay:this.executeStepFactory(e,a),push:this.executeStepFactory(e,a),chat:this.executeStepFactory(e,a),custom:this.executeStepFactory(e,a)}})]);}catch(m){R=m;}let T=process.hrtime(c),f=T[0],E=T[1],O=f*1e3+E/1e6,we=R?u.ERROR:u.SUCCESS,me=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${we} ${me} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,O,R),R)throw R;return {outputs:d.outputs,providers:d.providers,options:d.options,metadata:{status:"success",error:!1,duration:O}}}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?u.ERROR:u.SUCCESS,i=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",c=r?"Failed to execute":i,d=r?p.error:p.success,n=`${o} ${c} workflowId: '${e.workflowId}`;console.log(`
25
- ${p.bold(d(n))}'`),console.log(` \u251C ${u.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${u.ACTION} action: '${e.action}'`),console.log(` \u2514 ${u.DURATION} duration: '${t.toFixed(2)}ms'
26
- `);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let c=await o,d=this.previewProvider.bind(this),n=this.executeProvider.bind(this),a=await(e.action==="preview"?d:n)(e,t,i,r);return {...c,[i.type]:a}},Promise.resolve({}))}previewProvider(e,t,r,o){return console.log(` ${u.MOCK} Mocked provider: \`${r.type}\``),this.mock(r.outputs.schema)}async executeProvider(e,t,r,o){let i=ae__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let c=await this.createStepControls(t,e),d=await r.resolve({controls:c,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}else i.stopAndPersist({symbol:u.HYDRATED,text:`Hydrated provider: \`${r.type}\``});}catch(c){throw i.stopAndPersist({symbol:u.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new Z(`Failed to execute provider: '${r.type}'.
27
- ${c.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=ae__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),c=await t.resolve(i),d=await this.validate(c,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:u.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=ae__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:u.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:i,providers:await this.executeProviders(e,t,i)}}else throw new C(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:u.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=ae__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),c=await t.resolve(i),d=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:u.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:u.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw r.stopAndPersist({symbol:u.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}};function Ye(s){return JSON.parse(JSON.stringify(s))}var de=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new ce,this.client.addWorkflows(e.workflows),this.http=Oe(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":b,"novu-framework-sdk":P,"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")||"",i=t.searchParams.get("workflowId")||"",c=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 _=this.getPostActionMap(n,i,c,o),a=this.getGetActionMap(i,c);if(r==="POST")return await this.handlePostAction(o,_);if(r==="GET")return await this.handleGetAction(o,a);if(r==="OPTIONS")return this.createResponse(200,{})}catch(_){return this.handleError(_)}return this.createError(new J(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.tenant&&{tenant:e.tenant},...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(S).includes(e)){let r=t[e];return r()}else throw new U(e,S)}async handleGetAction(e,t){if(Object.values(V).includes(e)){let r=t[e];return r()}else throw new U(e,V)}isBridgeError(e){return Object.values(A).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 y))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new H;if(!this.client.secretKey)throw new re;let[r,o]=t.split(",");if(!r||!o)throw new ee;let[i,c]=r.split("="),[d,n]=o.split("=");if(Number(i)<Date.now()-1500)throw new te;if(!(this.hashHmac(this.client.secretKey,`${c}.${JSON.stringify(e)}`)===n))throw new Q}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var Le="next",jr=s=>{let t=new de({frameworkName:Le,...s,handler:(i,c,d)=>{let n=c,_=a=>{let R=typeof n.headers.get=="function"?n.headers.get(a):n.headers[a];return Array.isArray(R)?R[0]:R};return {body:()=>typeof n.json=="function"?n.json():n.body,headers:_,method:()=>i||n.method||"",queryString:(a,R)=>{let T=n.query?.[a]||R.searchParams.get(a);return Array.isArray(T)?T[0]:T},url:()=>{let a;try{a=new URL(n.url);}catch{}if(a){let E=_("host");if(E){let O=new URL(E.includes("://")?E:`${a.protocol}//${E}`);a.protocol=O.protocol,a.host=O.host,a.port=O.port,a.username=O.username,a.password=O.password;}return a}let R="https",T=_("host")||"";try{process.env.NODE_ENV==="development"&&(R="http");}catch{}return new URL(n.url,`${R}://${T}`)},transformResponse:({body:a,headers:R,status:T})=>{if(typeof d?.setHeader=="function"&&Object.entries(R).forEach(([E,O])=>{d.setHeader(E,O);}),typeof d?.status=="function"&&typeof d?.send=="function"){d.status(T).send(a);return}let f=Ee();return new f(a,{status:T,headers:R})}}}}).createHandler(),r=t.bind(null,void 0);return Object.defineProperties(r,{GET:{value:t.bind(null,"GET")},POST:{value:t.bind(null,"POST")},OPTIONS:{value:t.bind(null,"OPTIONS")}})};
23
+ var P=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(P||{}),Y=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(Y||{});var A=(l=>(l.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",l.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",l.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",l.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",l.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",l.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",l.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",l.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",l.STEP_NOT_FOUND_ERROR="StepNotFoundError",l.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",l.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",l.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",l.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",l.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",l.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",l.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",l.INVALID_ACTION_ERROR="InvalidActionError",l.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",l.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",l.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",l.SIGNATURE_INVALID_ERROR="SignatureInvalidError",l.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",l.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",l.BRIDGE_ERROR="BridgeError",l.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",l.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",l))(A||{});var b=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(b||{});var ue=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(ue||{});var Oe="2.0.0-canary.6";var x=Oe,F="2024-06-26";var f=class extends Error{data},C=class extends f{statusCode=404},h=class extends f{statusCode=400},N=class extends f{statusCode=401},g=class extends f{statusCode=500},L=class extends f{statusCode=409};var W=class extends h{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};}},k=class extends h{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},$=class extends h{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},G=class extends h{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 h{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;}},K=class extends h{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;}},q=class extends h{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 B=class extends f{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var Te=()=>typeof Response<"u"?Response:crossFetch.Response;var p={info:s=>y__default.default.blue(s),warning:s=>y__default.default.yellow(s),error:s=>y__default.default.red(s),success:s=>y__default.default.green(s),underline:s=>y__default.default.underline(s),bold:s=>y__default.default.bold(s)},R={SUCCESS:p.success("\u2714"),ERROR:p.error("\u2717"),WARNING:p.warning("\u26A0"),INFO:p.info("\u2139"),ARROW:p.bold("\u2192"),MOCK:p.info("\u25CB"),HYDRATED:p.bold(p.info("\u2192")),STEP:p.info("\u03C3"),ACTION:p.info("\u03B1"),DURATION:p.info("\u0394"),PROVIDER:p.info("\u2699"),OUTPUT:p.info("\u21E2"),INPUT:p.info("\u21E0"),WORKFLOW:p.info("\u03C9"),STATE:p.info("\u03C3"),EXECUTE:p.info("\u03B5"),PREVIEW:p.info("\u03C1")};var Re=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),X=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var he=(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)}),n=await i.json();if(i.ok)return n;throw shared.checkIsResponseError(n)?new B(n.statusCode,n.error,n.message):new D("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:fe__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Ae=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=fe__default.default(s,Pe);return t?t[0]+r:r},J=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Ae(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Ae(o):typeof o=="object"?J(o):o):typeof r=="object"&&r!==null?e[t]=J(r):e[t]=r,e},{});var z=class extends f{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${Re(b)}`},U=class extends h{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${Re(t)}`);}};var D=class extends g{code="BridgeError";message="Something went wrong. Please try again later."};var M=class extends L{constructor(e,t){super(`${X(e)} with id: \`${t}\` already exists. Please use a different id.`);}},v=class extends C{constructor(e,t){super(`${X(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},S=class extends g{constructor(e,t){super(`Failed to execute ${X(e)} with id: \`${t}\`. Please try again later.`);}};var Z=class extends v{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Q=class extends S{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var H=class extends N{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 N{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},te=class extends N{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},re=class extends N{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 N{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var se=class extends v{code="StepNotFoundError";constructor(e){super("step",e);}};var V=class extends v{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},ie=class extends M{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var ne=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var ae=class{ajv;compiledSchemas;constructor(){this.ajv=new Ue__default.default({useDefaults:!0,removeAdditional:"failing"}),Me__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(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=ne(e);return r(o)?{success:!0,data:o}:{success:!1,errors:r.errors.map(n=>({path:n.instancePath,message:n.message}))}}transformToJsonSchema(e){return e}};var ce=class{isSchema(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 we=[new ce,new ae],me=async(s,e)=>{for(let t of we)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},Ne=s=>{for(let e of we)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function be(){return ["development",void 0].includes(process.env.NODE_ENV)}var le=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=x;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!be()};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:x,frameworkVersion:F,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new V(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(Ne(e))}async validate(e,t,r,o,i,n,d){let a=await me(t,e);if(a.success)return a.data;switch(r){case"event":this.throwInvalidEvent(o,i,a.errors);case"step":this.throwInvalidStep(n,o,i,a.errors);case"provider":this.throwInvalidProvider(n,d,o,i,a.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 q(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 K(r,e,o);case"controls":throw new G(r,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,r){switch(e){case"controls":throw new $(t,r);case"payload":throw new k(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let n=this.getStep(e.workflowId,r),d=ne(e),a=await this.createStepControls(n,d),_=e.action==="preview";if(!_&&await this.shouldSkip(i?.skip,a))return t({options:{skip:!0},outputs:{},providers:{}}),{};let c=this.previewStep.bind(this),u=this.executeStep.bind(this),I=await(_?c:u)(e,{...n,providers:n.providers.map(O=>{let E=i?.providers?.[O.type];if(!E)throw new Z(O.type);return {...O,resolve:E}}),resolve:o});return Object.values(ue).includes(n.type)&&(I={...I,outputs:J(I.outputs)}),r===e.stepId&&t({...I,options:{skip:!1}}),I.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
24
+ ${p.bold(p.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),n=process.hrtime(),d={outputs:{},providers:{},options:{skip:!1}},a,_=new Promise(w=>{a=w;}),c=w=>{a(),d=w;},u;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new k(e.workflowId,{message:"Event `payload` is required"});let w=await this.createExecutionPayload(e,i),m={...e,payload:w};await Promise.race([_,i.execute({payload:w,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(m,c),sms:this.executeStepFactory(m,c),inApp:this.executeStepFactory(m,c),digest:this.executeStepFactory(m,c),delay:this.executeStepFactory(m,c),push:this.executeStepFactory(m,c),chat:this.executeStepFactory(m,c),custom:this.executeStepFactory(m,c)}})]);}catch(w){u=w;}let T=process.hrtime(n),I=T[0],O=T[1],E=I*1e3+O/1e6,ve=u?R.ERROR:R.SUCCESS,ge=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${ve} ${ge} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,E,u),u)throw u;return {outputs:d.outputs,providers:d.providers,options:d.options,metadata:{status:"success",error:!1,duration:E}}}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?R.ERROR:R.SUCCESS,i=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",n=r?"Failed to execute":i,d=r?p.error:p.success,a=`${o} ${n} workflowId: '${e.workflowId}`;console.log(`
25
+ ${p.bold(d(a))}'`),console.log(` \u251C ${R.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${R.ACTION} action: '${e.action}'`),console.log(` \u2514 ${R.DURATION} duration: '${t.toFixed(2)}ms'
26
+ `);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let n=await o,d=this.previewProvider.bind(this),a=this.executeProvider.bind(this),c=await(e.action==="preview"?d:a)(e,t,i,r);return {...n,[i.type]:c}},Promise.resolve({}))}previewProvider(e,t,r,o){return console.log(` ${R.MOCK} Mocked provider: \`${r.type}\``),this.mock(r.outputs.schema)}async executeProvider(e,t,r,o){let i=de__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let n=await this.createStepControls(t,e),d=await r.resolve({controls:n,outputs:o}),a=await this.validate(d,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),{...a,_passthrough:d._passthrough}}else return i.stopAndPersist({symbol:R.HYDRATED,text:`Hydrated provider: \`${r.type}\``}),{}}catch(n){throw i.stopAndPersist({symbol:R.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new Q(`Failed to execute provider: '${r.type}'.
27
+ ${n.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=de__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),n=await t.resolve(i),d=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),a=await this.executeProviders(e,t,d);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:d,providers:a}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:R.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=de__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:R.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:i,providers:await this.executeProviders(e,t,i)}}else throw new W(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:R.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=de__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),n=await t.resolve(i),d=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:R.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:R.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw r.stopAndPersist({symbol:R.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 V(e);return r}};var pe=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new le,this.client.addWorkflows(e.workflows),this.http=he(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":x,"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")||"",i=t.searchParams.get("workflowId")||"",n=t.searchParams.get("stepId")||"",d=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",a={};try{r==="POST"&&(a=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(a,d);let _=this.getPostActionMap(a,i,n,o),c=this.getGetActionMap(i,n);if(r==="POST")return await this.handlePostAction(o,_);if(r==="GET")return await this.handleGetAction(o,c);if(r==="OPTIONS")return this.createResponse(200,{})}catch(_){return this.handleError(_)}return this.createError(new z(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.tenant&&{tenant:e.tenant},...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(P).includes(e)){let r=t[e];return r()}else throw new U(e,P)}async handleGetAction(e,t){if(Object.values(Y).includes(e)){let r=t[e];return r()}else throw new U(e,Y)}isBridgeError(e){return Object.values(A).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 D))}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,n]=r.split("="),[d,a]=o.split("=");if(Number(i)<Date.now()-1500)throw new re;if(!(this.hashHmac(this.client.secretKey,`${n}.${JSON.stringify(e)}`)===a))throw new H}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var Le="next",Xr=s=>{let t=new pe({frameworkName:Le,...s,handler:(i,n,d)=>{let a=n,_=c=>{let u=typeof a.headers.get=="function"?a.headers.get(c):a.headers[c];return Array.isArray(u)?u[0]:u};return {body:()=>typeof a.json=="function"?a.json():a.body,headers:_,method:()=>i||a.method||"",queryString:(c,u)=>{let T=a.query?.[c]||u.searchParams.get(c);return Array.isArray(T)?T[0]:T},url:()=>{let c;try{c=new URL(a.url);}catch{}if(c){let O=_("host");if(O){let E=new URL(O.includes("://")?O:`${c.protocol}//${O}`);c.protocol=E.protocol,c.host=E.host,c.port=E.port,c.username=E.username,c.password=E.password;}return c}let u="https",T=_("host")||"";try{process.env.NODE_ENV==="development"&&(u="http");}catch{}return new URL(a.url,`${u}://${T}`)},transformResponse:({body:c,headers:u,status:T})=>{if(typeof d?.setHeader=="function"&&Object.entries(u).forEach(([O,E])=>{d.setHeader(O,E);}),typeof d?.status=="function"&&typeof d?.send=="function"){d.status(T).send(c);return}let I=Te();return new I(c,{status:T,headers:u})}}}}).createHandler(),r=t.bind(null,void 0);return Object.defineProperties(r,{GET:{value:t.bind(null,"GET")},POST:{value:t.bind(null,"POST")},OPTIONS:{value:t.bind(null,"OPTIONS")}})};
28
28
 
29
29
  exports.frameworkName = Le;
30
- exports.serve = jr;
30
+ exports.serve = Xr;
@@ -1,6 +1,6 @@
1
1
  import * as h3 from 'h3';
2
2
  import { H3Event } from 'h3';
3
- import { r as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-RA4Feq8s.js';
3
+ import { s as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-908yagvL.js';
4
4
  import 'json-schema-to-ts';
5
5
  import 'zod';
6
6
  import '@novu/shared';
@@ -4,28 +4,28 @@ var h3 = require('h3');
4
4
  var crypto = require('crypto');
5
5
  var jsonSchemaFaker = require('json-schema-faker');
6
6
  var liquidjs = require('liquidjs');
7
- var ae = require('ora');
7
+ var ce = require('ora');
8
8
  require('cross-fetch');
9
- var m = require('chalk');
9
+ var v = require('chalk');
10
10
  var shared = require('@novu/shared');
11
- var Te = require('sanitize-html');
12
- var Pe = require('ajv');
13
- var xe = require('ajv-formats');
11
+ var Ae = require('sanitize-html');
12
+ var ke = require('ajv');
13
+ var Ue = require('ajv-formats');
14
14
  var zodToJsonSchema = require('zod-to-json-schema');
15
15
 
16
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
17
 
18
- var ae__default = /*#__PURE__*/_interopDefault(ae);
19
- var m__default = /*#__PURE__*/_interopDefault(m);
20
- var Te__default = /*#__PURE__*/_interopDefault(Te);
21
- var Pe__default = /*#__PURE__*/_interopDefault(Pe);
22
- var xe__default = /*#__PURE__*/_interopDefault(xe);
18
+ var ce__default = /*#__PURE__*/_interopDefault(ce);
19
+ var v__default = /*#__PURE__*/_interopDefault(v);
20
+ var Ae__default = /*#__PURE__*/_interopDefault(Ae);
21
+ var ke__default = /*#__PURE__*/_interopDefault(ke);
22
+ var Ue__default = /*#__PURE__*/_interopDefault(Ue);
23
23
 
24
- var D=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(D||{}),k=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(k||{});var E=(n=>(n.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",n.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",n.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",n.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",n.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",n.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",n.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",n.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",n.STEP_NOT_FOUND_ERROR="StepNotFoundError",n.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",n.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",n.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",n.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",n.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",n.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",n.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",n.INVALID_ACTION_ERROR="InvalidActionError",n.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",n.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",n.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",n.SIGNATURE_INVALID_ERROR="SignatureInvalidError",n.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",n.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",n.BRIDGE_ERROR="BridgeError",n.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",n.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",n))(E||{});var V=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(V||{});var le=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(le||{});var _e="2.0.0-canary.4";var S=_e,Y="2024-06-26";var O=class extends Error{data},b=class extends O{statusCode=404},_=class extends O{statusCode=400},T=class extends O{statusCode=401},N=class extends O{statusCode=500},C=class extends O{statusCode=409};var L=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;}},F=class extends _{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},W=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;}},$=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;}},j=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 K=class extends O{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var d={info:s=>m__default.default.blue(s),warning:s=>m__default.default.yellow(s),error:s=>m__default.default.red(s),success:s=>m__default.default.green(s),underline:s=>m__default.default.underline(s),bold:s=>m__default.default.bold(s)},p={SUCCESS:d.success("\u2714"),ERROR:d.error("\u2717"),WARNING:d.warning("\u26A0"),INFO:d.info("\u2139"),ARROW:d.bold("\u2192"),MOCK:d.info("\u25CB"),HYDRATED:d.bold(d.info("\u2192")),STEP:d.info("\u03C3"),ACTION:d.info("\u03B1"),DURATION:d.info("\u0394"),PROVIDER:d.info("\u2699"),OUTPUT:d.info("\u21E2"),INPUT:d.info("\u21E0"),WORKFLOW:d.info("\u03C9"),STATE:d.info("\u03C3"),EXECUTE:d.info("\u03B5"),PREVIEW:d.info("\u03C1")};var pe=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),B=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Ee=(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 K(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 ye={allowedTags:Te__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Oe=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=Te__default.default(s,ye);return t?t[0]+r:r},X=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Oe(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Oe(o):typeof o=="object"?X(o):o):typeof r=="object"&&r!==null?e[t]=X(r):e[t]=r,e},{});var J=class extends O{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${pe(V)}`},x=class extends _{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${pe(t)}`);}};var v=class extends N{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends C{constructor(e,t){super(`${B(e)} with id: \`${t}\` already exists. Please use a different id.`);}},A=class extends b{constructor(e,t){super(`${B(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},g=class extends N{constructor(e,t){super(`Failed to execute ${B(e)} with id: \`${t}\`. Please try again later.`);}};var q=class extends A{code="ProviderNotFoundError";constructor(e){super("provider",e);}},z=class extends g{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Z=class extends T{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.");}},Q=class extends T{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},H=class extends T{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},ee=class extends T{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},te=class extends T{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var re=class extends A{code="StepNotFoundError";constructor(e){super("step",e);}};var M=class extends A{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},oe=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var se=class{ajv;compiledSchemas;constructor(){this.ajv=new Pe__default.default({useDefaults:!0,removeAdditional:"all"}),xe__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.oneOf}async validate(e,t){let r=this.compiledSchemas.get(t);return r||(r=this.ajv.compile(t),this.compiledSchemas.set(t,r)),r(e)?{success:!0,data:e}:{success:!1,errors:r.errors.map(i=>({path:i.instancePath,message:i.message}))}}transformToJsonSchema(e){return e}};var ie=class{isSchema(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 he=[new ie,new se],Ie=async(s,e)=>{for(let t of he)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},we=s=>{for(let e of he)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function ke(){return ["development",void 0].includes(process.env.NODE_ENV)}var ne=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=S;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!ke()};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 oe(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:S,frameworkVersion:Y,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new M(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new re(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(we(e))}async validate(e,t,r,o,i,a,l){let c=await Ie(t,e);if(c.success)return c.data;switch(r){case"event":this.throwInvalidEvent(o,i,c.errors);case"step":this.throwInvalidStep(a,o,i,c.errors);case"provider":this.throwInvalidProvider(a,l,o,i,c.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 j(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 $(r,e,o);case"result":throw new G(r,e,o);case"controls":throw new W(r,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,r){switch(e){case"controls":throw new F(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),l=Ve(e),c=await this.createStepControls(a,l),u=e.action==="preview";if(!u&&await this.shouldSkip(i?.skip,c))return t({options:{skip:!0}}),{};let R=this.previewStep.bind(this),h=this.executeStep.bind(this),I=await(u?R:h)(e,{...a,providers:a.providers.map(f=>{let y=i?.providers?.[f.type];if(!y)throw new q(f.type);return {...f,resolve:y}}),resolve:o});return Object.values(le).includes(a.type)&&(I={...I,outputs:X(I.outputs)}),r===e.stepId&&t(I),I.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
25
- ${d.bold(d.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),a=process.hrtime(),l={outputs:{},providers:{},options:{}},c,u=new Promise(w=>{c=w;}),R=w=>{c(),l=w;},h;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new P(e.workflowId,{message:"Event `payload` is required"});let w=await this.createExecutionPayload(e,i);await Promise.race([u,i.execute({payload:w,environment:{},inputs:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(e,R),sms:this.executeStepFactory(e,R),inApp:this.executeStepFactory(e,R),digest:this.executeStepFactory(e,R),delay:this.executeStepFactory(e,R),push:this.executeStepFactory(e,R),chat:this.executeStepFactory(e,R),custom:this.executeStepFactory(e,R)}})]);}catch(w){h=w;}let de=process.hrtime(a),I=de[0],f=de[1],y=I*1e3+f/1e6,Ne=h?p.ERROR:p.SUCCESS,me=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${Ne} ${me} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,y,h),h)throw h;return {outputs:l.outputs,providers:l.providers,options:l.options,metadata:{status:"success",error:!1,duration:y}}}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,l=r?d.error:d.success,c=`${o} ${a} workflowId: '${e.workflowId}`;console.log(`
26
- ${d.bold(l(c))}'`),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'
27
- `);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let a=await o,l=this.previewProvider.bind(this),c=this.executeProvider.bind(this),R=await(e.action==="preview"?l:c)(e,t,i,r);return {...a,[i.type]:R}},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=ae__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let a=await this.createStepControls(t,e),l=await r.resolve({controls:a,outputs:o}),c=await this.validate(l,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),c}else 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 z(`Failed to execute provider: '${r.type}'.
28
- ${a.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=ae__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),l=await this.validate(a,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),c=await this.executeProviders(e,t,l);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:l,providers:c}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:p.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=ae__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 L(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=ae__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),l=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:l,providers:await this.executeProviders(e,t,l)}}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 M(e);return r}};function Ve(s){return JSON.parse(JSON.stringify(s))}var ce=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new ne,this.client.addWorkflows(e.workflows),this.http=Ee(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":Y,"novu-framework-sdk":S,"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")||"",i=t.searchParams.get("workflowId")||"",a=t.searchParams.get("stepId")||"",l=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",c={};try{r==="POST"&&(c=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(c,l);let u=this.getPostActionMap(c,i,a,o),R=this.getGetActionMap(i,a);if(r==="POST")return await this.handlePostAction(o,u);if(r==="GET")return await this.handleGetAction(o,R);if(r==="OPTIONS")return this.createResponse(200,{})}catch(u){return this.handleError(u)}return this.createError(new J(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.tenant&&{tenant:e.tenant},...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(D).includes(e)){let r=t[e];return r()}else throw new x(e,D)}async handleGetAction(e,t){if(Object.values(k).includes(e)){let r=t[e];return r()}else throw new x(e,k)}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 Q;if(!this.client.secretKey)throw new te;let[r,o]=t.split(",");if(!r||!o)throw new H;let[i,a]=r.split("="),[l,c]=o.split("=");if(Number(i)<Date.now()-1500)throw new ee;if(!(this.hashHmac(this.client.secretKey,`${a}.${JSON.stringify(e)}`)===c))throw new Z}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var $e="nuxt",qr=s=>new ce({frameworkName:$e,...s,handler:t=>({queryString:r=>String(h3.getQuery(t)[r]),body:()=>h3.readBody(t),headers:r=>h3.getHeader(t,r),url:()=>new URL(String(t.path),`${process.env.NODE_ENV==="development"?"http":"https"}://${String(h3.getHeader(t,"host"))}`),method:()=>t.method,transformResponse:r=>{let{res:o}=t.node;return o.statusCode=r.status,h3.setHeaders(t,r.headers),h3.send(t,r.body)}})}).createHandler();
24
+ var S=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(S||{}),V=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(V||{});var E=(a=>(a.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",a.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",a.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",a.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",a.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",a.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",a.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",a.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",a.STEP_NOT_FOUND_ERROR="StepNotFoundError",a.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",a.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",a.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",a.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",a.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",a.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",a.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",a.INVALID_ACTION_ERROR="InvalidActionError",a.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",a.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",a.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",a.SIGNATURE_INVALID_ERROR="SignatureInvalidError",a.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",a.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",a.BRIDGE_ERROR="BridgeError",a.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",a.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",a))(E||{});var Y=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(Y||{});var Re=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(Re||{});var Ee="2.0.0-canary.6";var P=Ee,C="2024-06-26";var O=class extends Error{data},b=class extends O{statusCode=404},u=class extends O{statusCode=400},A=class extends O{statusCode=401},N=class extends O{statusCode=500},L=class extends O{statusCode=409};var F=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};}},x=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="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 B=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=>v__default.default.blue(s),warning:s=>v__default.default.yellow(s),error:s=>v__default.default.red(s),success:s=>v__default.default.green(s),underline:s=>v__default.default.underline(s),bold:s=>v__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 ue=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),X=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Te=(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)}),n=await i.json();if(i.ok)return n;throw shared.checkIsResponseError(n)?new B(n.statusCode,n.error,n.message):new g("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 Se={allowedTags:Ae__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},he=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=Ae__default.default(s,Se);return t?t[0]+r:r},J=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=he(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?he(o):typeof o=="object"?J(o):o):typeof r=="object"&&r!==null?e[t]=J(r):e[t]=r,e},{});var q=class extends O{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${ue(Y)}`},k=class extends u{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${ue(t)}`);}};var g=class extends N{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends L{constructor(e,t){super(`${X(e)} with id: \`${t}\` already exists. Please use a different id.`);}},I=class extends b{constructor(e,t){super(`${X(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},D=class extends N{constructor(e,t){super(`Failed to execute ${X(e)} with id: \`${t}\`. Please try again later.`);}};var z=class extends I{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Z=class extends D{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Q=class extends A{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.");}},H=class extends A{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},ee=class extends A{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},te=class extends A{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},re=class extends A{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var oe=class extends I{code="StepNotFoundError";constructor(e){super("step",e);}};var M=class extends I{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},se=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var ie=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var ne=class{ajv;compiledSchemas;constructor(){this.ajv=new ke__default.default({useDefaults:!0,removeAdditional:"failing"}),Ue__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(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=ie(e);return r(o)?{success:!0,data:o}:{success:!1,errors:r.errors.map(n=>({path:n.instancePath,message:n.message}))}}transformToJsonSchema(e){return e}};var ae=class{isSchema(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 we=[new ae,new ne],fe=async(s,e)=>{for(let t of we)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},me=s=>{for(let e of we)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Ye(){return ["development",void 0].includes(process.env.NODE_ENV)}var de=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=P;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Ye()};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 se(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:P,frameworkVersion:C,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new M(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new oe(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(me(e))}async validate(e,t,r,o,i,n,c){let d=await fe(t,e);if(d.success)return d.data;switch(r){case"event":this.throwInvalidEvent(o,i,d.errors);case"step":this.throwInvalidStep(n,o,i,d.errors);case"provider":this.throwInvalidProvider(n,c,o,i,d.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 K(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 x(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let n=this.getStep(e.workflowId,r),c=ie(e),d=await this.createStepControls(n,c),_=e.action==="preview";if(!_&&await this.shouldSkip(i?.skip,d))return t({options:{skip:!0},outputs:{},providers:{}}),{};let R=this.previewStep.bind(this),w=this.executeStep.bind(this),f=await(_?R:w)(e,{...n,providers:n.providers.map(m=>{let y=i?.providers?.[m.type];if(!y)throw new z(m.type);return {...m,resolve:y}}),resolve:o});return Object.values(Re).includes(n.type)&&(f={...f,outputs:J(f.outputs)}),r===e.stepId&&t({...f,options:{skip:!1}}),f.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
25
+ ${l.bold(l.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),n=process.hrtime(),c={outputs:{},providers:{},options:{skip:!1}},d,_=new Promise(T=>{d=T;}),R=T=>{d(),c=T;},w;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new x(e.workflowId,{message:"Event `payload` is required"});let T=await this.createExecutionPayload(e,i),h={...e,payload:T};await Promise.race([_,i.execute({payload:T,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(h,R),sms:this.executeStepFactory(h,R),inApp:this.executeStepFactory(h,R),digest:this.executeStepFactory(h,R),delay:this.executeStepFactory(h,R),push:this.executeStepFactory(h,R),chat:this.executeStepFactory(h,R),custom:this.executeStepFactory(h,R)}})]);}catch(T){w=T;}let pe=process.hrtime(n),f=pe[0],m=pe[1],y=f*1e3+m/1e6,ve=w?p.ERROR:p.SUCCESS,ge=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${ve} ${ge} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,y,w),w)throw w;return {outputs:c.outputs,providers:c.providers,options:c.options,metadata:{status:"success",error:!1,duration:y}}}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",n=r?"Failed to execute":i,c=r?l.error:l.success,d=`${o} ${n} workflowId: '${e.workflowId}`;console.log(`
26
+ ${l.bold(c(d))}'`),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'
27
+ `);}async executeProviders(e,t,r){return t.providers.reduce(async(o,i)=>{let n=await o,c=this.previewProvider.bind(this),d=this.executeProvider.bind(this),R=await(e.action==="preview"?c:d)(e,t,i,r);return {...n,[i.type]:R}},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=ce__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let n=await this.createStepControls(t,e),c=await r.resolve({controls:n,outputs:o}),d=await this.validate(c,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),{...d,_passthrough:c._passthrough}}else return i.stopAndPersist({symbol:p.HYDRATED,text:`Hydrated provider: \`${r.type}\``}),{}}catch(n){throw i.stopAndPersist({symbol:p.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new Z(`Failed to execute provider: '${r.type}'.
28
+ ${n.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=ce__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),n=await t.resolve(i),c=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),d=await this.executeProviders(e,t,c);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:c,providers:d}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:p.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=ce__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 F(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=ce__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),n=await t.resolve(i),c=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:c,providers:await this.executeProviders(e,t,c)}}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 M(e);return r}};var le=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new de,this.client.addWorkflows(e.workflows),this.http=Te(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":C,"novu-framework-sdk":P,"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")||"",i=t.searchParams.get("workflowId")||"",n=t.searchParams.get("stepId")||"",c=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",d={};try{r==="POST"&&(d=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(d,c);let _=this.getPostActionMap(d,i,n,o),R=this.getGetActionMap(i,n);if(r==="POST")return await this.handlePostAction(o,_);if(r==="GET")return await this.handleGetAction(o,R);if(r==="OPTIONS")return this.createResponse(200,{})}catch(_){return this.handleError(_)}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.tenant&&{tenant:e.tenant},...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(S).includes(e)){let r=t[e];return r()}else throw new k(e,S)}async handleGetAction(e,t){if(Object.values(V).includes(e)){let r=t[e];return r()}else throw new k(e,V)}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 g))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new H;if(!this.client.secretKey)throw new re;let[r,o]=t.split(",");if(!r||!o)throw new ee;let[i,n]=r.split("="),[c,d]=o.split("=");if(Number(i)<Date.now()-1500)throw new te;if(!(this.hashHmac(this.client.secretKey,`${n}.${JSON.stringify(e)}`)===d))throw new Q}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var Ge="nuxt",Hr=s=>new le({frameworkName:Ge,...s,handler:t=>({queryString:r=>String(h3.getQuery(t)[r]),body:()=>h3.readBody(t),headers:r=>h3.getHeader(t,r),url:()=>new URL(String(t.path),`${process.env.NODE_ENV==="development"?"http":"https"}://${String(h3.getHeader(t,"host"))}`),method:()=>t.method,transformResponse:r=>{let{res:o}=t.node;return o.statusCode=r.status,h3.setHeaders(t,r.headers),h3.send(t,r.body)}})}).createHandler();
29
29
 
30
- exports.frameworkName = $e;
31
- exports.serve = qr;
30
+ exports.frameworkName = Ge;
31
+ exports.serve = Hr;
@@ -1,4 +1,4 @@
1
- import { r as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-RA4Feq8s.js';
1
+ import { s as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-908yagvL.js';
2
2
  import 'json-schema-to-ts';
3
3
  import 'zod';
4
4
  import '@novu/shared';
@@ -3,28 +3,28 @@
3
3
  var crypto = require('crypto');
4
4
  var jsonSchemaFaker = require('json-schema-faker');
5
5
  var liquidjs = require('liquidjs');
6
- var ae = require('ora');
6
+ var ce = require('ora');
7
7
  var crossFetch = require('cross-fetch');
8
- var N = require('chalk');
8
+ var v = require('chalk');
9
9
  var shared = require('@novu/shared');
10
- var Ae = require('sanitize-html');
11
- var xe = require('ajv');
12
- var Ue = require('ajv-formats');
10
+ var Ie = require('sanitize-html');
11
+ var Ue = require('ajv');
12
+ var Me = require('ajv-formats');
13
13
  var zodToJsonSchema = require('zod-to-json-schema');
14
14
 
15
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
16
 
17
- var ae__default = /*#__PURE__*/_interopDefault(ae);
18
- var N__default = /*#__PURE__*/_interopDefault(N);
19
- var Ae__default = /*#__PURE__*/_interopDefault(Ae);
20
- var xe__default = /*#__PURE__*/_interopDefault(xe);
17
+ var ce__default = /*#__PURE__*/_interopDefault(ce);
18
+ var v__default = /*#__PURE__*/_interopDefault(v);
19
+ var Ie__default = /*#__PURE__*/_interopDefault(Ie);
21
20
  var Ue__default = /*#__PURE__*/_interopDefault(Ue);
21
+ var Me__default = /*#__PURE__*/_interopDefault(Me);
22
22
 
23
- var D=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(D||{}),k=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(k||{});var E=(n=>(n.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",n.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",n.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",n.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",n.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",n.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",n.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",n.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",n.STEP_NOT_FOUND_ERROR="StepNotFoundError",n.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",n.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",n.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",n.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",n.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",n.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",n.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",n.INVALID_ACTION_ERROR="InvalidActionError",n.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",n.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",n.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",n.SIGNATURE_INVALID_ERROR="SignatureInvalidError",n.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",n.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",n.BRIDGE_ERROR="BridgeError",n.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",n.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",n))(E||{});var V=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(V||{});var de=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(de||{});var _e="2.0.0-canary.4";var S=_e,Y="2024-06-26";var O=class extends Error{data},b=class extends O{statusCode=404},_=class extends O{statusCode=400},T=class extends O{statusCode=401},m=class extends O{statusCode=500},C=class extends O{statusCode=409};var L=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;}},F=class extends _{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},W=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;}},$=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;}},j=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 K=class extends O{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var Ee=()=>typeof Response<"u"?Response:crossFetch.Response;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)},R={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(", "),B=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var Oe=(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 K(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 De={allowedTags:Ae__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Te=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=Ae__default.default(s,De);return t?t[0]+r:r},X=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Te(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Te(o):typeof o=="object"?X(o):o):typeof r=="object"&&r!==null?e[t]=X(r):e[t]=r,e},{});var J=class extends O{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${Re(V)}`},x=class extends _{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${Re(t)}`);}};var v=class extends m{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends C{constructor(e,t){super(`${B(e)} with id: \`${t}\` already exists. Please use a different id.`);}},A=class extends b{constructor(e,t){super(`${B(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},g=class extends m{constructor(e,t){super(`Failed to execute ${B(e)} with id: \`${t}\`. Please try again later.`);}};var q=class extends A{code="ProviderNotFoundError";constructor(e){super("provider",e);}},z=class extends g{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Z=class extends T{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.");}},Q=class extends T{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},H=class extends T{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},ee=class extends T{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},te=class extends T{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var re=class extends A{code="StepNotFoundError";constructor(e){super("step",e);}};var M=class extends A{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},oe=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var se=class{ajv;compiledSchemas;constructor(){this.ajv=new xe__default.default({useDefaults:!0,removeAdditional:"all"}),Ue__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.oneOf}async validate(e,t){let r=this.compiledSchemas.get(t);return r||(r=this.ajv.compile(t),this.compiledSchemas.set(t,r)),r(e)?{success:!0,data:e}:{success:!1,errors:r.errors.map(i=>({path:i.instancePath,message:i.message}))}}transformToJsonSchema(e){return e}};var ie=class{isSchema(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 Ie=[new ie,new se],we=async(s,e)=>{for(let t of Ie)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},fe=s=>{for(let e of Ie)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Ve(){return ["development",void 0].includes(process.env.NODE_ENV)}var ne=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=S;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Ve()};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 oe(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:S,frameworkVersion:Y,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new M(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new re(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(fe(e))}async validate(e,t,r,o,i,a,d){let c=await we(t,e);if(c.success)return c.data;switch(r){case"event":this.throwInvalidEvent(o,i,c.errors);case"step":this.throwInvalidStep(a,o,i,c.errors);case"provider":this.throwInvalidProvider(a,d,o,i,c.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 j(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 $(r,e,o);case"result":throw new G(r,e,o);case"controls":throw new W(r,e,o);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,r){switch(e){case"controls":throw new F(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=Ye(e),c=await this.createStepControls(a,d),u=e.action==="preview";if(!u&&await this.shouldSkip(i?.skip,c))return t({options:{skip:!0}}),{};let p=this.previewStep.bind(this),h=this.executeStep.bind(this),I=await(u?p:h)(e,{...a,providers:a.providers.map(f=>{let y=i?.providers?.[f.type];if(!y)throw new q(f.type);return {...f,resolve:y}}),resolve:o});return Object.values(de).includes(a.type)&&(I={...I,outputs:X(I.outputs)}),r===e.stepId&&t(I),I.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.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:{}},c,u=new Promise(w=>{c=w;}),p=w=>{c(),d=w;},h;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new P(e.workflowId,{message:"Event `payload` is required"});let w=await this.createExecutionPayload(e,i);await Promise.race([u,i.execute({payload:w,environment:{},inputs:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(e,p),sms:this.executeStepFactory(e,p),inApp:this.executeStepFactory(e,p),digest:this.executeStepFactory(e,p),delay:this.executeStepFactory(e,p),push:this.executeStepFactory(e,p),chat:this.executeStepFactory(e,p),custom:this.executeStepFactory(e,p)}})]);}catch(w){h=w;}let le=process.hrtime(a),I=le[0],f=le[1],y=I*1e3+f/1e6,me=h?R.ERROR:R.SUCCESS,Ne=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${me} ${Ne} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,y,h),h)throw h;return {outputs:d.outputs,providers:d.providers,options:d.options,metadata:{status:"success",error:!1,duration:y}}}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?R.ERROR:R.SUCCESS,i=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",a=r?"Failed to execute":i,d=r?l.error:l.success,c=`${o} ${a} workflowId: '${e.workflowId}`;console.log(`
25
- ${l.bold(d(c))}'`),console.log(` \u251C ${R.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${R.ACTION} action: '${e.action}'`),console.log(` \u2514 ${R.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),c=this.executeProvider.bind(this),p=await(e.action==="preview"?d:c)(e,t,i,r);return {...a,[i.type]:p}},Promise.resolve({}))}previewProvider(e,t,r,o){return console.log(` ${R.MOCK} Mocked provider: \`${r.type}\``),this.mock(r.outputs.schema)}async executeProvider(e,t,r,o){let i=ae__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}),c=await this.validate(d,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),c}else i.stopAndPersist({symbol:R.HYDRATED,text:`Hydrated provider: \`${r.type}\``});}catch(a){throw i.stopAndPersist({symbol:R.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new z(`Failed to execute provider: '${r.type}'.
27
- ${a.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=ae__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),c=await this.executeProviders(e,t,d);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:d,providers:c}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:R.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=ae__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:R.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:i,providers:await this.executeProviders(e,t,i)}}else throw new L(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:R.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=ae__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:R.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:R.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:o,providers:await this.executeProviders(e,t,o)}}}catch(o){throw r.stopAndPersist({symbol:R.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 M(e);return r}};function Ye(s){return JSON.parse(JSON.stringify(s))}var ce=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new ne,this.client.addWorkflows(e.workflows),this.http=Oe(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":Y,"novu-framework-sdk":S,"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")||"",i=t.searchParams.get("workflowId")||"",a=t.searchParams.get("stepId")||"",d=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",c={};try{r==="POST"&&(c=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(c,d);let u=this.getPostActionMap(c,i,a,o),p=this.getGetActionMap(i,a);if(r==="POST")return await this.handlePostAction(o,u);if(r==="GET")return await this.handleGetAction(o,p);if(r==="OPTIONS")return this.createResponse(200,{})}catch(u){return this.handleError(u)}return this.createError(new J(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.tenant&&{tenant:e.tenant},...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(D).includes(e)){let r=t[e];return r()}else throw new x(e,D)}async handleGetAction(e,t){if(Object.values(k).includes(e)){let r=t[e];return r()}else throw new x(e,k)}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 Q;if(!this.client.secretKey)throw new te;let[r,o]=t.split(",");if(!r||!o)throw new H;let[i,a]=r.split("="),[d,c]=o.split("=");if(Number(i)<Date.now()-1500)throw new ee;if(!(this.hashHmac(this.client.secretKey,`${a}.${JSON.stringify(e)}`)===c))throw new Z}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var Le="remix",jr=s=>new ce({frameworkName:Le,...s,handler:({request:t})=>({body:()=>t.json(),headers:r=>t.headers.get(r),method:()=>t.method,url:()=>new URL(t.url,`https://${t.headers.get("host")||""}`),transformResponse:({body:r,status:o,headers:i})=>{let a=Ee();return new a(r,{status:o,headers:i})}})}).createHandler();
23
+ var S=(r=>(r.TRIGGER="trigger",r.EXECUTE="execute",r.PREVIEW="preview",r))(S||{}),V=(r=>(r.DISCOVER="discover",r.HEALTH_CHECK="health-check",r.CODE="code",r))(V||{});var E=(a=>(a.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",a.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",a.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",a.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",a.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",a.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",a.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",a.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",a.STEP_NOT_FOUND_ERROR="StepNotFoundError",a.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",a.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",a.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",a.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",a.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",a.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",a.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",a.INVALID_ACTION_ERROR="InvalidActionError",a.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",a.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",a.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",a.SIGNATURE_INVALID_ERROR="SignatureInvalidError",a.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",a.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",a.BRIDGE_ERROR="BridgeError",a.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",a.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",a))(E||{});var Y=(r=>(r.POST="POST",r.GET="GET",r.OPTIONS="OPTIONS",r))(Y||{});var Re=(i=>(i.EMAIL="email",i.SMS="sms",i.PUSH="push",i.CHAT="chat",i.IN_APP="in_app",i))(Re||{});var Ee="2.0.0-canary.6";var P=Ee,C="2024-06-26";var O=class extends Error{data},b=class extends O{statusCode=404},u=class extends O{statusCode=400},A=class extends O{statusCode=401},N=class extends O{statusCode=500},L=class extends O{statusCode=409};var F=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};}},x=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="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 B=class extends O{statusCode;data;code;constructor(e,t,r){super(),this.data={message:r},this.statusCode=e,this.code=t;}};var Te=()=>typeof Response<"u"?Response:crossFetch.Response;var l={info:s=>v__default.default.blue(s),warning:s=>v__default.default.yellow(s),error:s=>v__default.default.red(s),success:s=>v__default.default.green(s),underline:s=>v__default.default.underline(s),bold:s=>v__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 ue=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),X=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,r)=>t.toUpperCase()+r.toLowerCase()).replaceAll(/[\s-]+/g,"");var he=(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)}),n=await i.json();if(i.ok)return n;throw shared.checkIsResponseError(n)?new B(n.statusCode,n.error,n.message):new g("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}},Ae=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),r=Ie__default.default(s,Pe);return t?t[0]+r:r},J=s=>Object.keys(s).reduce((e,t)=>{let r=s[t];return typeof r=="string"?e[t]=Ae(r):Array.isArray(r)?e[t]=r.map(o=>typeof o=="string"?Ae(o):typeof o=="object"?J(o):o):typeof r=="object"&&r!==null?e[t]=J(r):e[t]=r,e},{});var q=class extends O{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${ue(Y)}`},k=class extends u{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${ue(t)}`);}};var g=class extends N{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends L{constructor(e,t){super(`${X(e)} with id: \`${t}\` already exists. Please use a different id.`);}},I=class extends b{constructor(e,t){super(`${X(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},D=class extends N{constructor(e,t){super(`Failed to execute ${X(e)} with id: \`${t}\`. Please try again later.`);}};var z=class extends I{code="ProviderNotFoundError";constructor(e){super("provider",e);}},Z=class extends D{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var Q=class extends A{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.");}},H=class extends A{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},ee=class extends A{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},te=class extends A{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},re=class extends A{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var oe=class extends I{code="StepNotFoundError";constructor(e){super("step",e);}};var M=class extends I{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},se=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var ie=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var ne=class{ajv;compiledSchemas;constructor(){this.ajv=new Ue__default.default({useDefaults:!0,removeAdditional:"failing"}),Me__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(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=ie(e);return r(o)?{success:!0,data:o}:{success:!1,errors:r.errors.map(n=>({path:n.instancePath,message:n.message}))}}transformToJsonSchema(e){return e}};var ae=class{isSchema(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 fe=[new ae,new ne],me=async(s,e)=>{for(let t of fe)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},Ne=s=>{for(let e of fe)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Ce(){return ["development",void 0].includes(process.env.NODE_ENV)}var de=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=P;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Ce()};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 se(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:P,frameworkVersion:C,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(r=>r.workflowId===e);if(t)return t;throw new M(e)}getStep(e,t){let o=this.getWorkflow(e).steps.find(i=>i.stepId===t);if(o)return o;throw new oe(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(Ne(e))}async validate(e,t,r,o,i,n,c){let d=await me(t,e);if(d.success)return d.data;switch(r){case"event":this.throwInvalidEvent(o,i,d.errors);case"step":this.throwInvalidStep(n,o,i,d.errors);case"provider":this.throwInvalidProvider(n,c,o,i,d.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 K(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 x(t,r);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(r,o,i)=>{let n=this.getStep(e.workflowId,r),c=ie(e),d=await this.createStepControls(n,c),_=e.action==="preview";if(!_&&await this.shouldSkip(i?.skip,d))return t({options:{skip:!0},outputs:{},providers:{}}),{};let R=this.previewStep.bind(this),w=this.executeStep.bind(this),f=await(_?R:w)(e,{...n,providers:n.providers.map(m=>{let y=i?.providers?.[m.type];if(!y)throw new z(m.type);return {...m,resolve:y}}),resolve:o});return Object.values(Re).includes(n.type)&&(f={...f,outputs:J(f.outputs)}),r===e.stepId&&t({...f,options:{skip:!1}}),f.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let o=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
24
+ ${l.bold(l.underline(o))} '${e.workflowId}'`);let i=this.getWorkflow(e.workflowId),n=process.hrtime(),c={outputs:{},providers:{},options:{skip:!1}},d,_=new Promise(T=>{d=T;}),R=T=>{d(),c=T;},w;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new x(e.workflowId,{message:"Event `payload` is required"});let T=await this.createExecutionPayload(e,i),h={...e,payload:T};await Promise.race([_,i.execute({payload:T,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(h,R),sms:this.executeStepFactory(h,R),inApp:this.executeStepFactory(h,R),digest:this.executeStepFactory(h,R),delay:this.executeStepFactory(h,R),push:this.executeStepFactory(h,R),chat:this.executeStepFactory(h,R),custom:this.executeStepFactory(h,R)}})]);}catch(T){w=T;}let pe=process.hrtime(n),f=pe[0],m=pe[1],y=f*1e3+m/1e6,ve=w?p.ERROR:p.SUCCESS,ge=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${ve} ${ge} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,y,w),w)throw w;return {outputs:c.outputs,providers:c.providers,options:c.options,metadata:{status:"success",error:!1,duration:y}}}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",n=r?"Failed to execute":i,c=r?l.error:l.success,d=`${o} ${n} workflowId: '${e.workflowId}`;console.log(`
25
+ ${l.bold(c(d))}'`),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 n=await o,c=this.previewProvider.bind(this),d=this.executeProvider.bind(this),R=await(e.action==="preview"?c:d)(e,t,i,r);return {...n,[i.type]:R}},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=ce__default.default({indent:2}).start(`Executing provider: \`${r.type}\``);try{if(e.stepId===t.stepId){let n=await this.createStepControls(t,e),c=await r.resolve({controls:n,outputs:o}),d=await this.validate(c,r.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,r.type);return i.succeed(`Executed provider: \`${r.type}\``),{...d,_passthrough:c._passthrough}}else return i.stopAndPersist({symbol:p.HYDRATED,text:`Hydrated provider: \`${r.type}\``}),{}}catch(n){throw i.stopAndPersist({symbol:p.ERROR,text:`Failed to execute provider: \`${r.type}\``}),new Z(`Failed to execute provider: '${r.type}'.
27
+ ${n.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let r=ce__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let o=await this.createStepControls(t,e),i=await this.compileControls(o,e),n=await t.resolve(i),c=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),d=await this.executeProviders(e,t,c);return r.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:c,providers:d}}catch(o){throw r.stopAndPersist({prefixText:"",symbol:p.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),o}}else {let r=ce__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 F(e.workflowId,t.stepId)}catch(o){throw r.stopAndPersist({symbol:p.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),o}}}async compileControls(e,t){let r=this.templateEngine.parse(JSON.stringify(e)),o=await this.templateEngine.render(r,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(o)}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=ce__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),n=await t.resolve(i),c=await this.validate(n,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return r.stopAndPersist({symbol:p.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:c,providers:await this.executeProviders(e,t,c)}}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 M(e);return r}};var le=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new de,this.client.addWorkflows(e.workflows),this.http=he(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":C,"novu-framework-sdk":P,"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")||"",i=t.searchParams.get("workflowId")||"",n=t.searchParams.get("stepId")||"",c=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",d={};try{r==="POST"&&(d=await e.body());}catch{}try{o!=="health-check"&&this.validateHmac(d,c);let _=this.getPostActionMap(d,i,n,o),R=this.getGetActionMap(i,n);if(r==="POST")return await this.handlePostAction(o,_);if(r==="GET")return await this.handleGetAction(o,R);if(r==="OPTIONS")return this.createResponse(200,{})}catch(_){return this.handleError(_)}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.tenant&&{tenant:e.tenant},...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(S).includes(e)){let r=t[e];return r()}else throw new k(e,S)}async handleGetAction(e,t){if(Object.values(V).includes(e)){let r=t[e];return r()}else throw new k(e,V)}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 g))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new H;if(!this.client.secretKey)throw new re;let[r,o]=t.split(",");if(!r||!o)throw new ee;let[i,n]=r.split("="),[c,d]=o.split("=");if(Number(i)<Date.now()-1500)throw new te;if(!(this.hashHmac(this.client.secretKey,`${n}.${JSON.stringify(e)}`)===d))throw new Q}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var Fe="remix",Jr=s=>new le({frameworkName:Fe,...s,handler:({request:t})=>({body:()=>t.json(),headers:r=>t.headers.get(r),method:()=>t.method,url:()=>new URL(t.url,`https://${t.headers.get("host")||""}`),transformResponse:({body:r,status:o,headers:i})=>{let n=Te();return new n(r,{status:o,headers:i})}})}).createHandler();
28
28
 
29
- exports.frameworkName = Le;
30
- exports.serve = jr;
29
+ exports.frameworkName = Fe;
30
+ exports.serve = Jr;
@@ -1,5 +1,5 @@
1
1
  import { RequestEvent } from '@sveltejs/kit';
2
- import { r as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-RA4Feq8s.js';
2
+ import { s as SupportedFrameworkName, b as ServeHandlerOptions } from '../handler-908yagvL.js';
3
3
  import 'json-schema-to-ts';
4
4
  import 'zod';
5
5
  import '@novu/shared';