@5minds/processcube_app_sdk
Version:
The SDK for ProcessCube Apps
2 lines (1 loc) • 19.9 kB
JavaScript
var v=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var xe=(e,t)=>{for(var s in t)v(e,s,{get:t[s],enumerable:!0})},Ne=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Pe(t))!Re.call(e,o)&&o!==s&&v(e,o,{get:()=>t[o],enumerable:!(n=Ce(t,o))||n.enumerable});return e};var Ue=e=>Ne(v({},"__esModule",{value:!0}),e);var mt={};xe(mt,{AuthorityClient:()=>M,cancelReservedUserTask:()=>rt,finishManualTask:()=>J,finishTask:()=>lt,finishUntypedTask:()=>Z,finishUserTask:()=>Q,finishUserTaskAndGetNext:()=>Qe,getActiveProcessInstances:()=>Ye,getAssignedUserTasksByIdentity:()=>ot,getEngineClient:()=>je,getFlowNodeInstances:()=>yt,getFlowNodeInstancesByProcessInstanceId:()=>H,getFlowNodeInstancesTriggeredByFlowNodeInstanceIds:()=>G,getIdentity:()=>d,getProcessInstance:()=>ft,getProcessInstanceById:()=>X,getReservedUserTasksByIdentity:()=>st,getServerAccessToken:()=>U,getServerIdentity:()=>Fe,getTriggeredFlowNodeInstances:()=>It,getUserTasks:()=>we,getWaitingUserTaskByFlowNodeInstanceId:()=>Ee,getWaitingUserTasks:()=>Ze,getWaitingUserTasksByCorrelationId:()=>tt,getWaitingUserTasksByFlowNodeId:()=>et,getWaitingUserTasksByProcessInstanceId:()=>ze,navigateToUrl:()=>at,reserveUserTask:()=>nt,retryProcess:()=>pt,retryProcessInstance:()=>j,startProcess:()=>ct,terminateProcess:()=>ut,terminateProcessInstance:()=>Y,waitForProcessEnd:()=>Ve,waitForUserTask:()=>Je,withApplicationSdk:()=>it});module.exports=Ue(mt);var ts=require("only-server"),ss=require("../common/index.cjs");var se=require("@5minds/processcube_engine_sdk");var z=require("jwt-decode"),ee=require("@5minds/processcube_engine_sdk"),F=new ee.Logger("processcube_app_sdk:server_identity"),be=.85,Ae="upe_admin engine_read engine_write",P=null;function Oe(e){let t=e?.authorityUrl??process.env.PROCESSCUBE_AUTHORITY_URL,s=e?.clientId??process.env.PROCESSCUBE_SERVER_CLIENT_ID,n=e?.clientSecret??process.env.PROCESSCUBE_SERVER_CLIENT_SECRET,o=e?.scopes??process.env.PROCESSCUBE_SERVER_SCOPES??Ae;if(!t)throw new Error("PROCESSCUBE_AUTHORITY_URL is not configured. Set the environment variable or pass authorityUrl.");if(!s)throw new Error("PROCESSCUBE_SERVER_CLIENT_ID is not configured. Set the environment variable or pass clientId.");if(!n)throw new Error("PROCESSCUBE_SERVER_CLIENT_SECRET is not configured. Set the environment variable or pass clientSecret.");return{authorityUrl:t,clientId:s,clientSecret:n,scopes:o}}function ve(){return P?Date.now()<P.expiresAt:!1}async function U(e){if(!e?.skipCache&&ve())return P.accessToken;let{authorityUrl:t,clientId:s,clientSecret:n,scopes:o}=Oe(e);F.info("Fetching new server access token");let i=await fetch(`${t}/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},redirect:"follow",body:new URLSearchParams({grant_type:"client_credentials",client_id:s,client_secret:n,scope:o}).toString(),cache:"no-store"});if(!i.ok){let l=await i.text().catch(()=>""),m=`Failed to fetch server access token: ${i.status} ${i.statusText}${l?` \u2014 ${l}`:""}`;throw F.error(m),new Error(m)}let a=await i.json();if(!a.access_token)throw new Error("Authority response did not contain an access_token");let c=a.expires_in;return c&&c>0?P={accessToken:a.access_token,expiresAt:Date.now()+c*be*1e3}:P=null,F.info("Server access token fetched successfully"),a.access_token}async function Fe(e){let t=await U(e),s=(0,z.jwtDecode)(t);if(!s.sub)throw new Error('Server access token does not contain a "sub" claim');return{token:t,userId:s.sub}}var te=new se.Logger("processcube_app_sdk:authority_client"),M=class{authorityUrl;tokenOptions;constructor(t){let s=t?.authorityUrl??process.env.PROCESSCUBE_AUTHORITY_URL;if(!s)throw new Error("PROCESSCUBE_AUTHORITY_URL is not configured. Set the environment variable or pass authorityUrl.");this.authorityUrl=s.replace(/\/+$/,""),this.tokenOptions=t??{}}async request(t,s,n){let o=await U(this.tokenOptions),i=`${this.authorityUrl}${s}`;te.info(`Authority request: ${t} ${s}`);let a={Cookie:`access_token=${o}`,"Content-Type":"application/json"},c=await fetch(i,{method:t,headers:a,redirect:"follow",body:n!==void 0?JSON.stringify(n):void 0}),l;try{l=await c.json()}catch{l=void 0}return c.ok||te.error(`Authority request failed: ${t} ${s} \u2192 ${c.status} ${c.statusText}`),{ok:c.ok,status:c.status,data:l}}userAdminPath(t,s){return`/acr/username_password/admin/user/${encodeURIComponent(t)}/${s}`}async updateClaim(t,s,n){return this.request("PATCH",this.userAdminPath(t,"update/claim"),{claimName:s,claimValue:n})}async addScope(t,s){return this.request("PATCH",this.userAdminPath(t,"add/scope"),{scopeName:s})}async addGroup(t,s){return this.request("PATCH",this.userAdminPath(t,"add/group"),{groupName:s})}async deleteUser(t,s){return this.request("DELETE",this.userAdminPath(t,"delete"),{fullDelete:s?.fullDelete??!1})}};var oe=require("chokidar"),ie=require("esbuild"),ae=require("jwt-decode"),ce=require("node:child_process"),R=require("node:fs"),u=require("node:path"),de=require("node:url"),A=require("openid-client"),le=require("@5minds/processcube_engine_sdk");var ne=require("@5minds/processcube_engine_client"),B=process.env.PROCESSCUBE_ENGINE_URL??"http://localhost:10560",r=new ne.EngineClient(B);var Ge={},Me={token:"ZHVtbXlfdG9rZW4=",userId:"dummy_token"},Be=.85,b=["external_task.ts","external_task.js"],x=process.env.PROCESSCUBE_AUTHORITY_URL!==void 0,f=new le.Logger("processcube_app_sdk:external_task_adapter"),w={},L={},E,W=!1,ue=6,De=3e5,Le=3e4,D=10,We=3e4,re=10,$e=6e4;async function pe(e){if(e&&!(0,R.existsSync)(e))throw new Error(`Invalid customExternalTasksDirPath. The given path '${e}' does not exist`);A.custom.setHttpOptionsDefaults({timeout:1e5});let t=await Ie();E=q(t),await me(t);let s=Xe(e);(0,oe.watch)(s).on("add",async n=>{if(b.includes((0,u.basename)(n)))return $(n,s)}).on("change",async n=>{if(b.includes((0,u.basename)(n)))return qe(n,s)}).on("unlink",async n=>{b.includes((0,u.basename)(n))&&fe(n)}).on("error",n=>f.error(`Watcher error: ${n}`))}async function $(e,t){let s=(0,u.dirname)(e);if((await R.promises.readdir(s)).filter(y=>b.includes(y)).length>1){f.error(`Multiple external task files found in directory ${s}. Stopping all external task workers for this directory.`),w[s]&&fe(e);return}let i=await Te(e),a=(0,u.relative)(t,s),c=ke(a),l=typeof __dirname<"u"?__dirname:(0,u.dirname)((0,de.fileURLToPath)(Ge.url)),m=(0,u.join)(l,"lib/ExternalTaskWorkerProcess.cjs"),p=(0,ce.fork)(m,{stdio:["pipe","inherit","inherit","ipc"],env:{...process.env,PROCESSCUBE_ENGINE_URL:B}});w[s]=p,p.once("disconnect",()=>{delete w[s]}),p.on("error",y=>{f.error(`External Task Worker process error for ${c}`,{error:y,topic:c,workerDirectory:s})}),p.on("exit",(y,O)=>{if(f.info(`External Task Worker process exited for ${c}`,{code:y,signal:O,topic:c,workerDirectory:s}),delete w[s],y===3||y===4)if(He(s)){let _=L[s]?.count??1,C=Math.min(1e3*Math.pow(2,_-1),Le);f.info(`Scheduling restart for ${c} in ${C}ms (attempt ${_}/${ue})`,{delay:C,restartCount:_,exitCode:y,topic:c,workerDirectory:s}),setTimeout(async()=>{try{if(x&&!W){f.info("Token refresh cycle is not active, restarting it before worker restart");let g=await Ie();E=q(g),await me(g)}await $(e,t)}catch(g){f.error(`Failed to restart External Task Worker process for ${c}`,{error:g,topic:c,workerDirectory:s})}},C)}else f.error(`External Task Worker process for ${c} reached maximum restart attempts`,{exitCode:y,topic:c,workerDirectory:s})}),p.send({action:"create",payload:{topic:c,identity:E,moduleString:i,workerPath:e}})}async function qe(e,t){let s=(0,u.dirname)(e),n=w[s];if(!n)return $(e,t);let o=await Te(e),i=(0,u.relative)(t,s),a=ke(i);n.send({action:"restart",payload:{topic:a,identity:E,moduleString:o,workerPath:e}})}function fe(e){let t=(0,u.dirname)(e),s=w[t];s&&s.kill()}async function ye(){if(!x)return null;if(!process.env.PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_ID||!process.env.PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_SECRET){let n=new Error("Required environment variables PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_ID and PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_SECRET are missing. For help, please refer to our documentation on environment variables at: https://processcube.io/docs/app-sdk/samples/nextjs/external-task-adapter-with-nextjs#authority");throw f.error("Required environment variables PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_ID and PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_SECRET are missing",{err:n}),n}let e=await A.Issuer.discover(process.env.PROCESSCUBE_AUTHORITY_URL);return await new e.Client({client_id:process.env.PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_ID,client_secret:process.env.PROCESSCUBE_EXTERNAL_TASK_WORKER_CLIENT_SECRET}).grant({grant_type:"client_credentials",scope:"engine_etw"})}async function Ie(){if(!x)return null;for(let e=1;e<=D;e++)try{return await ye()}catch(t){let s=Math.min(1e3*Math.pow(2,e-1),We);if(f.error(`Failed to fetch initial token set (attempt ${e}/${D}), retrying in ${s}ms`,{error:t,attempt:e,delay:s}),e===D)throw t;await new Promise(n=>setTimeout(n,s))}return null}function q(e){if(!x||e===null)return Me;let t=e.access_token,s=(0,ae.jwtDecode)(t);return{token:e.access_token,userId:s.sub}}async function me(e){if(!x||e===null||W)return;W=!0;let t=0,n=await Ke(e)*Be*1e3,o=async()=>{try{let i=await ye();E=q(i);for(let[a,c]of Object.entries(w))try{c.send({action:"updateIdentity",payload:{identity:E}})}catch(l){f.warn(`Failed to send identity update to worker process ${a}`,{sendError:l})}t=0,setTimeout(o,n)}catch(i){t++;let a=Math.min(1e3*Math.pow(2,t-1),$e);t<=re?f.error(`Could not refresh identity (attempt ${t}/${re}), retrying in ${a}ms`,{error:i,attempt:t,delay:a}):f.error(`Could not refresh identity (attempt ${t}), continuing to retry every ${a}ms`,{error:i,attempt:t,delay:a}),setTimeout(o,a)}};setTimeout(o,n)}async function Te(e){let t=await(0,ie.build)({entryPoints:[e],write:!1,bundle:!0,platform:"node",target:"node18",format:"cjs",external:["@opentelemetry/api"]});if(t.errors.length>0)throw f.error(`Could not transpile file at '${e}'`,{errors:t.errors}),new Error(`Could not transpile file at '${e}'`);return t.warnings.length>0&&f.warn(`Transpiled file at '${e}' with warnings`,{warnings:t.warnings}),t.outputFiles[0].text}async function Ke(e){let t=e.expires_in;if(!t&&e.expires_at&&(t=Math.floor(e.expires_at-Date.now()/1e3)),t===void 0)throw new Error("Could not determine the time until the access token for external task workers expires");return t}function ke(e){return e.replace(/^\.\/+|\([^)]+\)|^\/*|\/*$/g,"").replace(/[\/]{2,}/g,"/")}function Xe(e){let t,s=[e,(0,u.join)(process.cwd(),"app"),(0,u.join)(process.cwd(),"src","app")];for(let n of s)if(n&&(0,R.existsSync)(n)){t=n;break}if(!t)throw new Error("Could not find external tasks directory");return t}function He(e){let t=Date.now(),s=L[e];return!s||t-s.timestamp>De?(L[e]={count:1,timestamp:t},!0):s.count>=ue?!1:(s.count++,!0)}function je(){return r}var K=require("next-auth/jwt"),ge=require("next/dist/compiled/@edge-runtime/cookies/index.js"),k=require("next/headers");async function d(){let e=await(0,K.getToken)({req:{cookies:await(0,k.cookies)(),headers:await(0,k.headers)()}});if(e?.expiresAt&&Date.now()>=e.expiresAt*1e3){let s=await fetch(`${process.env.NEXTAUTH_URL}/api/auth/session`,{method:"GET",headers:{"Content-Type":"application/json",cookie:(await(0,k.cookies)()).toString()}}),n=new ge.ResponseCookies(s.headers);if(n.getAll().length){let o=!1;try{for(let i of n.getAll())(await(0,k.cookies)()).set(i.name,i.value,{...i})}catch{o=!0}if(e=await(0,K.getToken)({req:{cookies:o?n:await(0,k.cookies)(),headers:await(0,k.headers)()}}),e?.error)throw e.error}}if(!e?.accessToken||!e?.sub)throw new Error("AccessToken or Sub could not be determined!");return{token:e?.accessToken,userId:e?.sub}}var h=require("@5minds/processcube_engine_client");async function N(){try{return d()}catch{return}}async function X(e){let t=await N();return(await r.processInstances.query({processInstanceId:e},{identity:t,includeXml:!0})).processInstances[0]}async function H(e,t={sortSettings:{sortBy:h.DataModels.FlowNodeInstances.FlowNodeInstanceSortableColumns.createdAt,sortDir:"ASC"}}){return(await r.flowNodeInstances.query({processInstanceId:e},{...t,identity:t.identity??await N()})).flowNodeInstances}async function G(e){let t=await N();return(await r.flowNodeInstances.query({triggeredByFlowNodeInstance:e},{identity:t})).flowNodeInstances}async function j(e,t,s){let n=await N();await r.processInstances.retryProcessInstance(e,{flowNodeInstanceId:t,newStartToken:s,identity:n})}async function Y(e){let t=await N();await r.processInstances.terminateProcessInstance(e,t)}async function Ye(e={options:{identity:!0}}){switch(e.options.identity){case!0:e.options.identity=await d();break;case!1:delete e.options.identity;break;case void 0:e.options.identity=await d();break}return await r.processInstances.query({...e?.query,state:h.DataModels.ProcessInstances.ProcessInstanceState.running},e?.options)}async function Ve(e={},t=!0){let{processInstanceId:s}=e,n=typeof t=="boolean"?t==!0?await d():void 0:t;return new Promise(async(o,i)=>{let a=[],c=async l=>{if(s!==void 0&&l.processInstanceId!==s)return;let p=await r.processInstances.query({processInstanceId:l.processInstanceId},{identity:n});for(let y of a)r.notification.removeSubscription(y,n);return p.totalCount===0?i(new Error(`Process with instance ID "${l.processInstanceId}" does not exist.`)):o(p.processInstances[0])};if(a.push(await r.notification.onProcessEnded(c,{identity:n})),a.push(await r.notification.onProcessError(c,{identity:n})),a.push(await r.notification.onProcessTerminated(c,{identity:n})),s){let l=await r.processInstances.query({processInstanceId:s,state:[h.DataModels.ProcessInstances.ProcessInstanceState.finished,h.DataModels.ProcessInstances.ProcessInstanceState.terminated,h.DataModels.ProcessInstances.ProcessInstanceState.error]},{identity:n});if(l.totalCount>0){for(let m of a)r.notification.removeSubscription(m,n);o(l.processInstances[0])}}})}var T=require("@5minds/processcube_engine_client"),I=require("../common/index.cjs");async function Je(e={},t=!0){let{correlationId:s,processInstanceId:n,flowNodeId:o}=e,i=typeof t=="boolean"?t==!0?await d():void 0:t;return new Promise(async(a,c)=>{let l=await r.userTasks.onUserTaskWaiting(async p=>{let y=s!==void 0&&p.correlationId!==s,O=p.flowNodeInstanceId===void 0,_=n!==void 0&&p.processInstanceId!==n,C=o!==void 0&&p.flowNodeId!==o;if(y||O||_||C)return;let g=await Ee(p.flowNodeInstanceId,{identity:i});return r.notification.removeSubscription(l,i),g===null?c(new Error(`UserTask with instance ID "${p.flowNodeInstanceId}" does not exist.`)):a(g)},{identity:i}),m=await we({correlationId:s,processInstanceId:n,flowNodeId:o,state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},{identity:i});m.userTasks.length>0&&(r.notification.removeSubscription(l,i),a(m.userTasks[0]))})}async function Qe(e,t={},s={},n=!0){let o=typeof n=="boolean"?n==!0?await d():void 0:n;await r.userTasks.finishUserTask(e,s,o);let i={state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended,...t},a=await r.userTasks.query(i,{identity:o});return(0,I.mapUserTask)(a.userTasks[0])}async function we(e,t={identity:!0}){switch(t?.identity){case!0:t.identity=await d();break;case!1:delete t.identity;break;case void 0:t.identity=await d();break}let s=await r.userTasks.query(e,t);return(0,I.mapUserTaskList)(s)}async function Ze(e={identity:!0}){switch(e?.identity){case!0:e.identity=await d();break;case!1:delete e.identity;break;case void 0:e.identity=await d();break}let t=await r.userTasks.query({state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},e);return(0,I.mapUserTaskList)(t)}async function ze(e,t={identity:!0}){switch(t?.identity){case!0:t.identity=await d();break;case!1:delete t.identity;break;case void 0:t.identity=await d();break}let s=await r.userTasks.query({processInstanceId:e,state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},t);return(0,I.mapUserTaskList)(s)}async function et(e,t={identity:!0}){switch(t?.identity){case!0:t.identity=await d();break;case!1:delete t.identity;break;case void 0:t.identity=await d();break}let s=await r.userTasks.query({flowNodeId:e,state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},t);return(0,I.mapUserTaskList)(s)}async function Ee(e,t={identity:!0}){switch(t?.identity){case!0:t.identity=await d();break;case!1:delete t.identity;break;case void 0:t.identity=await d();break}let s=await r.userTasks.query({flowNodeInstanceId:e,state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},{...t,limit:1});return s.userTasks.length===0?null:(0,I.mapUserTask)(s.userTasks[0])}async function tt(e,t={identity:!0}){switch(t?.identity){case!0:t.identity=await d();break;case!1:delete t.identity;break;case void 0:t.identity=await d();break}let s=await r.userTasks.query({correlationId:e,state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},t);return(0,I.mapUserTaskList)(s)}async function st(e,t){let s=e||await d(),n=await r.userTasks.query({state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},{identity:s,...t}),o=n.userTasks.filter(i=>i.actualOwnerId===s.userId);return n.userTasks=o,(0,I.mapUserTaskList)(n)}async function nt(e,t,s){await r.userTasks.reserveUserTaskInstance(e,t,s||e.userId)}async function rt(e,t){await r.userTasks.cancelUserTaskInstanceReservation(e,t)}async function ot(e,t){let s=e||await d(),n=await r.userTasks.query({state:T.DataModels.FlowNodeInstances.FlowNodeInstanceState.suspended},{identity:s,...t}),o=n.userTasks.filter(i=>i.assignedUserIds?.includes(s.userId));return n.userTasks=o,(0,I.mapUserTaskList)(n)}var S=require("next/dist/shared/lib/constants");var he=!1,V=!1;function it(e={}){let{applicationSdk:t,...s}=e;return async(n,o)=>{V=V||n===S.PHASE_PRODUCTION_BUILD;let i=n===S.PHASE_DEVELOPMENT_SERVER||n===S.PHASE_PRODUCTION_SERVER;return t?.useExternalTasks&&i&&!he&&!V&&(he=!0,await pe(t?.customExternalTasksDirPath)),{...s,serverExternalPackages:[...s.serverExternalPackages||[],"esbuild"]}}}var Se=require("next/navigation");function at(e){(0,Se.redirect)(e)}async function ct(...e){return await r.processModels.startProcessInstance(...e)}async function J(...e){await r.manualTasks.finishManualTask(...e)}async function Q(...e){await r.userTasks.finishUserTask(...e)}async function Z(...e){await r.untypedTasks.finishTask(...e)}var _e=require("@5minds/processcube_engine_client");async function dt(){try{return d()}catch{return}}var lt=async(e,t)=>{let s=await dt();t==="bpmn:UserTask"?await Q(e,{},s):t==="bpmn:ManualTask"?await J(e,s):t==="bpmn:Task"?await Z(e,s):console.error(`[@5minds/processcube_app_sdk:handlePlay] Unsupported flow node type: ${t}`)},ut=async e=>{await Y(e)},pt=async(e,t,s)=>{await j(e,t,s)},ft=async e=>X(e),yt=async e=>H(e,{sortSettings:{sortBy:_e.DataModels.FlowNodeInstances.FlowNodeInstanceSortableColumns.createdAt,sortDir:"DESC"}}),It=async e=>G(e);0&&(module.exports={AuthorityClient,cancelReservedUserTask,finishManualTask,finishTask,finishUntypedTask,finishUserTask,finishUserTaskAndGetNext,getActiveProcessInstances,getAssignedUserTasksByIdentity,getEngineClient,getFlowNodeInstances,getFlowNodeInstancesByProcessInstanceId,getFlowNodeInstancesTriggeredByFlowNodeInstanceIds,getIdentity,getProcessInstance,getProcessInstanceById,getReservedUserTasksByIdentity,getServerAccessToken,getServerIdentity,getTriggeredFlowNodeInstances,getUserTasks,getWaitingUserTaskByFlowNodeInstanceId,getWaitingUserTasks,getWaitingUserTasksByCorrelationId,getWaitingUserTasksByFlowNodeId,getWaitingUserTasksByProcessInstanceId,navigateToUrl,reserveUserTask,retryProcess,retryProcessInstance,startProcess,terminateProcess,terminateProcessInstance,waitForProcessEnd,waitForUserTask,withApplicationSdk});