{"id":18777508,"url":"https://github.com/onify/flow-extensions","last_synced_at":"2025-04-13T10:32:22.725Z","repository":{"id":57133238,"uuid":"463882316","full_name":"onify/flow-extensions","owner":"onify","description":"Onify Flow Extensions","archived":false,"fork":false,"pushed_at":"2024-05-19T06:04:19.000Z","size":165,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"default","last_synced_at":"2024-05-19T07:22:34.140Z","etag":null,"topics":["bpmn","extensions","onify"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-26T14:54:33.000Z","updated_at":"2024-05-19T07:22:37.751Z","dependencies_parsed_at":"2024-04-11T05:30:51.132Z","dependency_job_id":"16aae27f-e042-4620-89ff-92c25c56c190","html_url":"https://github.com/onify/flow-extensions","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"b159346ed39aea3988b2c08a5cdfbb2f5a115208"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fflow-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fflow-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fflow-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fflow-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onify","download_url":"https://codeload.github.com/onify/flow-extensions/tar.gz/refs/heads/default","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223581918,"owners_count":17168655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bpmn","extensions","onify"],"created_at":"2024-11-07T20:11:22.434Z","updated_at":"2024-11-07T20:11:23.162Z","avatar_url":"https://github.com/onify.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Onify Flow Extensions\n\n[![Built latest](https://github.com/onify/flow-extensions/actions/workflows/build-latest.yaml/badge.svg)](https://github.com/onify/flow-extensions/actions/workflows/build-latest.yaml)[![Coverage Status](https://coveralls.io/repos/github/onify/flow-extensions/badge.svg?branch=default)](https://coveralls.io/github/onify/flow-extensions?branch=default)\n\n# Api\n\n- `extensions`: Flow extensions\n- `extendFn`: extend function to pass to [serializer](https://github.com/paed01/moddle-context-serializer/blob/master/API.md)\n\n# Examples\n\n## Bpmn engine example\n\n```javascript\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport { Engine } from 'bpmn-engine';\nimport { extensions } from '@onify/flow-extensions';\nimport { FlowScripts } from '@onify/flow-extensions/FlowScripts';\n\nconst nodeRequire = createRequire(fileURLToPath(import.meta.url));\n\nconst source = `\n\u003cdefinitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"\u003e\n  \u003cprocess id=\"theProcess\" isExecutable=\"true\"\u003e\n    \u003cserviceTask id=\"task1\" camunda:expression=\"\\${environment.services.serviceFn}\" camunda:resultVariable=\"result\" /\u003e\n    \u003csequenceFlow id=\"to-task2\" sourceRef=\"task1\" targetRef=\"task2\" /\u003e\n    \u003cscriptTask id=\"task2\" camunda:resultVariable=\"out\" scriptFormat=\"js\"\u003e\n      \u003cscript\u003e\n        next(null, myContextFn());\n      \u003c/script\u003e\n    \u003c/scriptTask\u003e\n  \u003c/process\u003e\n\u003c/definitions\u003e`;\n\nconst name = 'onify flow';\nconst engine = new Engine({\n  name,\n  source,\n  moddleOptions: {\n    camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),\n  },\n  services: {\n    serviceFn(scope, callback) {\n      callback(null, { data: 1 });\n    },\n  },\n  extensions: {\n    onify: extensions,\n  },\n  scripts: new FlowScripts(name, './script-resources', {\n    myContextFn() {\n      return 2;\n    },\n  }),\n});\n\nengine.execute((err, instance) =\u003e {\n  if (err) throw err;\n  console.log(instance.name, instance.environment.output);\n});\n```\n\n## Extract scripts with extend function\n\n```javascript\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport BpmnModdle from 'bpmn-moddle';\nimport * as Elements from 'bpmn-elements';\nimport { Serializer, TypeResolver } from 'moddle-context-serializer';\nimport { extendFn } from '@onify/flow-extensions';\n\nconst nodeRequire = createRequire(fileURLToPath(import.meta.url));\n\nconst source = `\n\u003cdefinitions id=\"Def_0\" xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"\n  xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  targetNamespace=\"http://bpmn.io/schema/bpmn\"\u003e\n  \u003cprocess id=\"process-1\" name=\"Onify Flow\" isExecutable=\"true\"\u003e\n    \u003cserviceTask id=\"task1\"\u003e\n      \u003cextensionElements\u003e\n        \u003ccamunda:connector\u003e\n          \u003ccamunda:connectorId\u003eonifyApiRequest\u003c/camunda:connectorId\u003e\n          \u003ccamunda:inputOutput\u003e\n            \u003ccamunda:inputParameter name=\"method\"\u003eGET\u003c/camunda:inputParameter\u003e\n            \u003ccamunda:inputParameter name=\"url\"\u003e/my/items/workspace-1\u003c/camunda:inputParameter\u003e\n            \u003ccamunda:outputParameter name=\"result\"\u003e\n              \u003ccamunda:script scriptFormat=\"js\"\u003e\n                next(null, {\n                  id: content.id,\n                  statuscode,\n                });\n              \u003c/camunda:script\u003e\n            \u003c/camunda:outputParameter\u003e\n          \u003c/camunda:inputOutput\u003e\n        \u003c/camunda:connector\u003e\n        \u003ccamunda:inputOutput\u003e\n          \u003ccamunda:outputParameter name=\"result\"\u003e\\${content.output.result.statuscode}\u003c/camunda:outputParameter\u003e\n        \u003c/camunda:inputOutput\u003e\n      \u003c/extensionElements\u003e\n    \u003c/serviceTask\u003e\n    \u003csequenceFlow id=\"to-task2\" sourceRef=\"task1\" targetRef=\"task2\" /\u003e\n    \u003cscriptTask id=\"task2\" camunda:resultVariable=\"out\" scriptFormat=\"js\"\u003e\n      \u003cscript\u003e\n        next(null, 2);\n      \u003c/script\u003e\n    \u003c/scriptTask\u003e\n  \u003c/process\u003e\n\u003c/definitions\u003e`;\n\ngetScripts(source).then(console.log).catch(console.error);\n\nasync function getScripts(bpmnSource) {\n  const moddle = await getModdleContext(bpmnSource, {\n    camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),\n  });\n\n  const serialized = Serializer(moddle, TypeResolver(Elements), extendFn);\n  return serialized.elements.scripts;\n}\n\nfunction getModdleContext(source, options) {\n  const bpmnModdle = new BpmnModdle(options);\n  return bpmnModdle.fromXML(Buffer.isBuffer(source) ? source.toString() : source.trim());\n}\n```\n\n## Extract timers\n\n```javascript\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport BpmnModdle from 'bpmn-moddle';\nimport * as Elements from 'bpmn-elements';\nimport { Serializer, TypeResolver } from 'moddle-context-serializer';\nimport { extendFn, OnifyTimerEventDefinition } from '@onify/flow-extensions';\n\nconst nodeRequire = createRequire(fileURLToPath(import.meta.url));\n\nconst source = `\n\u003cdefinitions id=\"Def_0\" xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"\n  xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  targetNamespace=\"http://bpmn.io/schema/bpmn\"\u003e\n  \u003cprocess id=\"cycle-1\" name=\"Onify start at time cycle\" isExecutable=\"true\" camunda:historyTimeToLive=\"PT180M\"\u003e\n    \u003cstartEvent id=\"start\"\u003e\n      \u003ctimerEventDefinition\u003e\n        \u003ctimeCycle xsi:type=\"tFormalExpression\"\u003e0 1 * * *\u003c/timeCycle\u003e\n      \u003c/timerEventDefinition\u003e\n    \u003c/startEvent\u003e\n    \u003csequenceFlow id=\"to-task\" sourceRef=\"start\" targetRef=\"task\" /\u003e\n    \u003cuserTask id=\"task\" /\u003e\n    \u003cboundaryEvent id=\"bound-timer\" cancelActivity=\"false\" attachedToRef=\"task\"\u003e\n      \u003ctimerEventDefinition\u003e\n        \u003ctimeDuration xsi:type=\"tFormalExpression\"\u003eR3/PT1M\u003c/timeDuration\u003e\n      \u003c/timerEventDefinition\u003e\n    \u003c/boundaryEvent\u003e\n    \u003csequenceFlow id=\"to-wait\" sourceRef=\"task\" targetRef=\"wait\" /\u003e\n    \u003cintermediateThrowEvent id=\"timer\"\u003e\n      \u003ctimerEventDefinition\u003e\n        \u003ctimeCycle xsi:type=\"tFormalExpression\"\u003e\\${environment.settings.postpone}\u003c/timeCycle\u003e\n      \u003c/timerEventDefinition\u003e\n    \u003c/intermediateThrowEvent\u003e\n    \u003csequenceFlow id=\"to-end\" sourceRef=\"wait\" targetRef=\"end\" /\u003e\n    \u003cendEvent id=\"end\" /\u003e\n  \u003c/process\u003e\n\u003c/definitions\u003e`;\n\ngetTimers(source).then(console.log).catch(console.error);\n\nconst dummyEventActivity = { broker: {}, environment: { Logger() {} } };\n\nasync function getTimers(bpmnSource) {\n  const moddle = await getModdleContext(bpmnSource, {\n    camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),\n  });\n\n  const serialized = Serializer(moddle, TypeResolver(Elements), extendFn);\n\n  for (const t of serialized.elements.timers) {\n    const ed = new OnifyTimerEventDefinition(dummyEventActivity, t.timer);\n\n    try {\n      t.parsed = ed.parse(t.timer.timerType, t.timer.value);\n    } catch {}\n  }\n\n  return serialized.elements.timers;\n}\n\nfunction getModdleContext(source, options) {\n  const bpmnModdle = new BpmnModdle(options);\n  return bpmnModdle.fromXML(Buffer.isBuffer(source) ? source.toString() : source.trim());\n}\n```\n\n## Extend sequence flow with properties and take listeners\n\n```javascript\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport { Engine } from 'bpmn-engine';\nimport * as Elements from 'bpmn-elements';\nimport { OnifySequenceFlow, extensions } from '@onify/flow-extensions';\nimport { FlowScripts } from '@onify/flow-extensions/FlowScripts';\n\nconst nodeRequire = createRequire(fileURLToPath(import.meta.url));\n\nconst source = `\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cdefinitions\n  id=\"Def_0\"\n  xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"\n  xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"\n  targetNamespace=\"http://bpmn.io/schema/bpmn\"\u003e\n  \u003cprocess id=\"Process_1kk79yr\" isExecutable=\"true\"\u003e\n    \u003cstartEvent id=\"start\" /\u003e\n    \u003csequenceFlow id=\"to-script\" sourceRef=\"start\" targetRef=\"script\"\u003e\n      \u003cextensionElements\u003e\n        \u003ccamunda:properties\u003e\n          \u003ccamunda:property name=\"source\" value=\"\\${content.id}\" /\u003e\n        \u003c/camunda:properties\u003e\n        \u003ccamunda:executionListener event=\"take\"\u003e\n          \u003ccamunda:script scriptFormat=\"js\"\u003eenvironment.output.fields = listener.fields; next();\u003c/camunda:script\u003e\n          \u003ccamunda:field name=\"taken\"\u003e\n            \u003ccamunda:expression\u003e\\${true}\u003c/camunda:expression\u003e\n          \u003c/camunda:field\u003e\n          \u003ccamunda:field name=\"bar\"\u003e\n            \u003ccamunda:string\u003ebaz\u003c/camunda:string\u003e\n          \u003c/camunda:field\u003e\n        \u003c/camunda:executionListener\u003e\n      \u003c/extensionElements\u003e\n    \u003c/sequenceFlow\u003e\n    \u003csequenceFlow id=\"to-end\" sourceRef=\"script\" targetRef=\"end\"\u003e\n      \u003cextensionElements\u003e\n        \u003ccamunda:properties\u003e\n          \u003ccamunda:property name=\"foo\" value=\"bar\" /\u003e\n        \u003c/camunda:properties\u003e\n      \u003c/extensionElements\u003e\n    \u003c/sequenceFlow\u003e\n    \u003cscriptTask id=\"script\" name=\"script\" scriptFormat=\"js\"\u003e\n      \u003cscript\u003enext(null, { foo: environment.variables.required.input });\u003c/script\u003e\n    \u003c/scriptTask\u003e\n    \u003cboundaryEvent id=\"catch-err\" attachedToRef=\"script\"\u003e\n      \u003cerrorEventDefinition /\u003e\n    \u003c/boundaryEvent\u003e\n    \u003cendEvent id=\"end-err\"\u003e\n      \u003cextensionElements\u003e\n        \u003ccamunda:executionListener event=\"start\"\u003e\n          \u003ccamunda:script scriptFormat=\"js\"\u003e\n            environment.output.failedBy = content.inbound[0].properties.error;\n            if (next) next();\n          \u003c/camunda:script\u003e\n        \u003c/camunda:executionListener\u003e\n      \u003c/extensionElements\u003e\n    \u003c/endEvent\u003e\n    \u003csequenceFlow id=\"to-end-err\" sourceRef=\"catch-err\" targetRef=\"end-err\"\u003e\n      \u003cextensionElements\u003e\n        \u003ccamunda:properties\u003e\n          \u003ccamunda:property name=\"error\" value=\"\\${content.output}\" /\u003e\n        \u003c/camunda:properties\u003e\n      \u003c/extensionElements\u003e\n    \u003c/sequenceFlow\u003e\n    \u003cendEvent id=\"end\" /\u003e\n  \u003c/process\u003e\n\u003c/definitions\u003e`;\n\nconst engine = new Engine({\n  name: 'sequence flow extension',\n  source,\n  moddleOptions: {\n    camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),\n  },\n  extensions: {\n    onify: extensions,\n  },\n  scripts: new FlowScripts('sequence flow extension'),\n  elements: {\n    ...Elements,\n    SequenceFlow: OnifySequenceFlow,\n  },\n  variables: {\n    required: {\n      input: true,\n    },\n  },\n});\n\nengine.execute((err, instance) =\u003e {\n  if (err) throw err;\n  console.log(instance.name, instance.environment.output);\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonify%2Fflow-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonify%2Fflow-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonify%2Fflow-extensions/lists"}