├── .prettierignore ├── getting-started ├── STEP_FUNCTIONS_SETUP.md ├── jaeger │ ├── jaeger.png │ ├── jaeger-home.png │ ├── jaeger-span.png │ └── jaeger-trace.png ├── operate │ └── zeebe-operate.png ├── worker-topology-1 │ ├── Group.png │ ├── Group@2x.png │ └── Group@3x.png ├── worker-topology-2 │ ├── Group.png │ ├── Group@2x.png │ └── Group@3x.png └── worker-topology-3 │ ├── Group.png │ ├── Group@2x.png │ └── Group@3x.png ├── packages ├── workit │ ├── .prettierignore │ ├── .eslintignore │ ├── prettier.config.js │ ├── .env │ ├── tests │ │ ├── functionals │ │ │ ├── __mocks__ │ │ │ │ ├── createInstanceResult.json │ │ │ │ ├── deployWorkflowResult.json │ │ │ │ ├── message.ts │ │ │ │ ├── createWorkflowInstanceResponse.camunda.json │ │ │ │ ├── getWorkflowResponse.2.camunda.json │ │ │ │ ├── incidentResponse.camunda.json │ │ │ │ ├── getWorkflowsResult.json │ │ │ │ └── deployResponse.camunda.json │ │ │ └── __snapshots__ │ │ │ │ └── camundaManager.spec.ts.snap │ │ ├── utils │ │ │ ├── func-test.ts │ │ │ └── fake.ts │ │ └── data │ │ │ ├── camundaResponsePaginated2.json │ │ │ ├── camundaResponsePaginated.json │ │ │ └── camunda-response.json │ ├── types │ │ └── nock.d.ts │ ├── jest.config.js │ ├── src │ │ ├── config │ │ │ ├── constants │ │ │ │ ├── tag.ts │ │ │ │ ├── identifiers.ts │ │ │ │ └── index.ts │ │ │ └── container.ts │ │ ├── index.ts │ │ ├── camundaBpm │ │ │ ├── camundaManager.ts │ │ │ └── camundaBpmWorker.ts │ │ ├── stepFunction │ │ │ ├── stepFunctionManager.ts │ │ │ └── stepFunctionWorker.ts │ │ └── camunda-n-mq │ │ │ └── client.ts │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── .commitlintrc.yml │ └── LICENSE ├── workit-core │ ├── .prettierignore │ ├── .eslintignore │ ├── prettier.config.js │ ├── tests │ │ ├── units │ │ │ └── node_modules │ │ │ │ └── @villemontreal │ │ │ │ ├── plugin-task-module │ │ │ │ ├── package.json │ │ │ │ ├── index.js │ │ │ │ └── task-module.js │ │ │ │ ├── plugin-simple-module │ │ │ │ ├── package.json │ │ │ │ ├── index.js │ │ │ │ └── simple-module.js │ │ │ │ ├── plugin-supported-module │ │ │ │ ├── package.json │ │ │ │ ├── index.js │ │ │ │ └── simple-module.js │ │ │ │ └── plugin-notsupported-module │ │ │ │ ├── package.json │ │ │ │ ├── index.js │ │ │ │ └── simple-module.js │ │ └── utils │ │ │ ├── func-test.ts │ │ │ └── fake.ts │ ├── src │ │ ├── plugin │ │ │ ├── index.ts │ │ │ └── basePlugin.ts │ │ ├── utils │ │ │ ├── isPrimitive.ts │ │ │ ├── concat.ts │ │ │ └── utils.ts │ │ ├── tracer │ │ │ └── noopTracerPropagator.ts │ │ ├── strategies │ │ │ └── SuccessStrategySimple.ts │ │ ├── specs │ │ │ └── taskBase.ts │ │ ├── index.ts │ │ ├── common │ │ │ └── noopLogger.ts │ │ ├── worker.ts │ │ └── config │ │ │ └── constants │ │ │ └── index.ts │ ├── jest.config.js │ ├── .eslintrc.js │ ├── tsconfig.json │ ├── .commitlintrc.yml │ └── LICENSE ├── workit-types │ ├── .prettierignore │ ├── .eslintignore │ ├── prettier.config.js │ ├── src │ │ ├── utils │ │ │ └── validation.ts │ │ ├── commons │ │ │ ├── logLevel.ts │ │ │ ├── paginationOptions.ts │ │ │ ├── paging.ts │ │ │ ├── customHeaders.ts │ │ │ ├── pagination.ts │ │ │ └── logger.ts │ │ ├── http │ │ │ ├── headers.ts │ │ │ ├── httpOptions.ts │ │ │ └── httpResponse.ts │ │ ├── camundaBpm │ │ │ ├── topicSubscription.ts │ │ │ ├── link.ts │ │ │ ├── processXmlDefinition.ts │ │ │ ├── variables.ts │ │ │ ├── resolveIncident.ts │ │ │ ├── camundaBpmCreateInstanceResponse.ts │ │ │ ├── processDefinition.ts │ │ │ ├── incident.ts │ │ │ ├── index.ts │ │ │ ├── camundaClient.ts │ │ │ ├── payload.ts │ │ │ ├── bpmnDeployResponse.ts │ │ │ ├── subscriptionOptions.ts │ │ │ └── camundaRepository.ts │ │ ├── core │ │ │ ├── camunda │ │ │ │ ├── workflowOptions.ts │ │ │ │ ├── updateWorkflowRetry.ts │ │ │ │ ├── workflowResponse.ts │ │ │ │ ├── workflow.ts │ │ │ │ ├── updateWorkflowVariables.ts │ │ │ │ ├── deployWorkflowResponse.ts │ │ │ │ ├── createWorkflowInstanceResponse.ts │ │ │ │ ├── incidentException.ts │ │ │ │ ├── failureException.ts │ │ │ │ ├── workflowProps.ts │ │ │ │ ├── workflowPropsBase.ts │ │ │ │ ├── camundaService.ts │ │ │ │ ├── publishMessage.ts │ │ │ │ ├── createWorkflowInstance.ts │ │ │ │ ├── index.ts │ │ │ │ ├── workflowDefinition.ts │ │ │ │ └── workflowClient.ts │ │ │ ├── successStrategy.ts │ │ │ ├── failureStrategy.ts │ │ │ ├── message.ts │ │ │ ├── client.ts │ │ │ ├── interceptor.ts │ │ │ └── ioc.ts │ │ ├── plugin │ │ │ ├── hookState.ts │ │ │ ├── index.ts │ │ │ ├── plugins.ts │ │ │ ├── pluginConfig.ts │ │ │ └── plugin.ts │ │ ├── aws │ │ │ ├── index.ts │ │ │ ├── stepFunction │ │ │ │ └── stepFunctionConfig.ts │ │ │ ├── awsConfig.ts │ │ │ └── sqs │ │ │ │ └── sqsConfig.ts │ │ ├── process │ │ │ ├── processHandler.ts │ │ │ ├── process.ts │ │ │ └── processHandlerConfig.ts │ │ ├── tasks │ │ │ └── task.ts │ │ ├── tracer │ │ │ └── tracerPropagator.ts │ │ └── index.ts │ ├── jest.config.js │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── README.md │ ├── .commitlintrc.yml │ └── LICENSE ├── workit-bpm-client │ ├── .prettierignore │ ├── .eslintignore │ ├── prettier.config.js │ ├── tests │ │ ├── functionals │ │ │ ├── __mocks__ │ │ │ │ ├── createInstanceResult.json │ │ │ │ ├── deployWorkflowResult.json │ │ │ │ ├── message.ts │ │ │ │ ├── createWorkflowInstanceResponse.camunda.json │ │ │ │ ├── getWorkflowResponse.2.camunda.json │ │ │ │ ├── incidentResponse.camunda.json │ │ │ │ ├── getWorkflowsResult.json │ │ │ │ └── deployResponse.camunda.json │ │ │ └── __snapshots__ │ │ │ │ ├── camundaMessage.spec.ts.snap │ │ │ │ └── camundaManager.spec.ts.snap │ │ ├── units │ │ │ ├── variable.spec.ts │ │ │ └── camundaMessage.spec.ts │ │ ├── data │ │ │ ├── camundaResponsePaginated2.json │ │ │ ├── camundaResponsePaginated.json │ │ │ └── camunda-response.json │ │ └── utils │ │ │ ├── func-test.ts │ │ │ └── fake.ts │ ├── types │ │ ├── nock.d.ts │ │ └── camunda-external-task-client-js.d.ts │ ├── jest.config.js │ ├── src │ │ ├── variables.ts │ │ ├── bpmLogger.ts │ │ ├── bpmClient.ts │ │ ├── index.ts │ │ ├── config │ │ │ ├── container.ts │ │ │ └── constants │ │ │ │ └── identifiers.ts │ │ └── utils │ │ │ └── paginationUtils.ts │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── .commitlintrc.yml │ └── LICENSE └── workit-stepfunction-client │ ├── .prettierignore │ ├── .eslintignore │ ├── prettier.config.js │ ├── types │ └── nock.d.ts │ ├── tests │ ├── data │ │ └── workflow.json │ ├── utils │ │ ├── sqs.ts │ │ ├── func-test.ts │ │ └── fake.ts │ ├── units │ │ └── __snapshots__ │ │ │ └── sfnMessage.spec.ts.snap │ └── scripts │ │ ├── localstack │ │ └── init.sh │ │ ├── initIntTests.sh │ │ └── docker-compose.yml │ ├── tsconfig.json │ ├── src │ ├── sfnClient.ts │ ├── index.ts │ ├── utils │ │ └── datetime.ts │ └── config │ │ ├── constants │ │ ├── params.ts │ │ └── identifiers.ts │ │ └── container.ts │ ├── jest.config.js │ ├── .eslintrc.js │ ├── jest.setup.js │ ├── .commitlintrc.yml │ └── LICENSE ├── .dockerignore ├── .repo ├── sfn_demo.png └── render1561149492572.gif ├── examples ├── basic │ ├── .eslintignore │ ├── prettier.config.js │ ├── tsconfig.json │ ├── tasks │ │ └── helloWorldTask.ts │ ├── .eslintrc.js │ ├── LICENSE │ ├── workflow │ │ └── stepfunctions │ │ │ └── WORKFLOW_DEMO.json │ ├── src │ │ ├── create-process-instances.ts │ │ ├── worker.ts │ │ └── deploy.ts │ └── README.md ├── binding │ ├── .eslintignore │ ├── prettier.config.js │ ├── tsconfig.json │ ├── src │ │ ├── deploy.ts │ │ ├── create-process-instances.ts │ │ └── worker.ts │ ├── README.md │ ├── tasks │ │ ├── helloWorldTaskV3.ts │ │ ├── helloWorldTask.ts │ │ └── helloWorldTaskV2.ts │ ├── .eslintrc.js │ └── LICENSE ├── parallel │ ├── .eslintignore │ ├── prettier.config.js │ ├── tsconfig.json │ ├── src │ │ ├── deploy.ts │ │ ├── create-process-instances.ts │ │ └── worker.ts │ ├── README.md │ ├── .eslintrc.js │ ├── tasks │ │ └── helloWorldTask.ts │ └── LICENSE ├── opentelemetry │ ├── .eslintignore │ ├── prettier.config.js │ ├── tsconfig.json │ ├── src │ │ ├── deploy.ts │ │ └── create-process-instances.ts │ ├── tasks │ │ └── helloWorldTask.ts │ ├── .eslintrc.js │ └── LICENSE ├── failure-strategy │ ├── .eslintignore │ ├── prettier.config.js │ ├── tsconfig.json │ ├── src │ │ ├── deploy.ts │ │ ├── create-process-instances.ts │ │ └── worker.ts │ ├── README.md │ ├── tasks │ │ └── helloWorldTask.ts │ ├── .eslintrc.js │ ├── LICENSE │ └── workflow │ │ └── stepfunctions │ │ └── WORKFLOW_DEMO.json ├── plugin-metrics │ ├── prettier.config.js │ ├── tsconfig.json │ ├── CHANGELOG.md │ └── .eslintrc.js └── README.md ├── prettier.config.js ├── docs └── assets │ └── images │ ├── icons.png │ ├── widgets.png │ ├── icons@2x.png │ └── widgets@2x.png ├── .npmrc.template ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE │ ├── feature.md │ ├── bug.md │ └── regression.md ├── CODE_OF_CONDUCT_FR.md ├── codecov.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTORS.md ├── .circleci └── checksum.sh ├── lerna.json ├── tsconfig.base.json ├── .commitlintrc.yml ├── .gitignore ├── LICENSE └── eslint.rules.js /.prettierignore: -------------------------------------------------------------------------------- 1 | .* -------------------------------------------------------------------------------- /getting-started/STEP_FUNCTIONS_SETUP.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/workit/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | coverage 3 | .* -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | docker 3 | coverage 4 | .* 5 | -------------------------------------------------------------------------------- /packages/workit-core/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | coverage 3 | .* -------------------------------------------------------------------------------- /packages/workit-types/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | coverage 3 | .* -------------------------------------------------------------------------------- /packages/workit-bpm-client/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | coverage 3 | .* -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | coverage 3 | .* -------------------------------------------------------------------------------- /.repo/sfn_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/.repo/sfn_demo.png -------------------------------------------------------------------------------- /examples/basic/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /examples/binding/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests/ -------------------------------------------------------------------------------- /examples/parallel/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /packages/workit/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /examples/basic/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /examples/binding/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /examples/opentelemetry/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /examples/parallel/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /packages/workit-core/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /packages/workit-types/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /packages/workit/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /.repo/render1561149492572.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/.repo/render1561149492572.gif -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /examples/failure-strategy/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /examples/opentelemetry/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /packages/workit-core/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /examples/failure-strategy/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /packages/workit/.env: -------------------------------------------------------------------------------- 1 | # Docker Compose env file 2 | COMPOSE_PROJECT_NAME=camunda_worker 3 | COMPOSE_HTTP_TIMEOUT=120 4 | -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /getting-started/jaeger/jaeger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/jaeger/jaeger.png -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | .vscode 4 | coverage 5 | *lock* 6 | *.md 7 | tests -------------------------------------------------------------------------------- /packages/workit-types/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | singleQuote: true 4 | }; 5 | -------------------------------------------------------------------------------- /getting-started/jaeger/jaeger-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/jaeger/jaeger-home.png -------------------------------------------------------------------------------- /getting-started/jaeger/jaeger-span.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/jaeger/jaeger-span.png -------------------------------------------------------------------------------- /getting-started/jaeger/jaeger-trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/jaeger/jaeger-trace.png -------------------------------------------------------------------------------- /getting-started/operate/zeebe-operate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/operate/zeebe-operate.png -------------------------------------------------------------------------------- /getting-started/worker-topology-1/Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-1/Group.png -------------------------------------------------------------------------------- /getting-started/worker-topology-2/Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-2/Group.png -------------------------------------------------------------------------------- /getting-started/worker-topology-3/Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-3/Group.png -------------------------------------------------------------------------------- /getting-started/worker-topology-1/Group@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-1/Group@2x.png -------------------------------------------------------------------------------- /getting-started/worker-topology-1/Group@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-1/Group@3x.png -------------------------------------------------------------------------------- /getting-started/worker-topology-2/Group@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-2/Group@2x.png -------------------------------------------------------------------------------- /getting-started/worker-topology-2/Group@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-2/Group@3x.png -------------------------------------------------------------------------------- /getting-started/worker-topology-3/Group@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-3/Group@2x.png -------------------------------------------------------------------------------- /getting-started/worker-topology-3/Group@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VilledeMontreal/workit/HEAD/getting-started/worker-topology-3/Group@3x.png -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-task-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@villemontreal/plugin-task-module", 3 | "version": "0.0.1" 4 | } 5 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-simple-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@villemontreal/plugin-simple-module", 3 | "version": "0.0.1" 4 | } 5 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-supported-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@villemontreal/plugin-supported-module", 3 | "version": "0.0.1" 4 | } 5 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-notsupported-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@villemontreal/plugin-notsupported-module", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /.npmrc.template: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} 2 | //registry.npmjs.org/:username=olivieralbertini 3 | //registry.npmjs.org/:email=olivier.albertini@montreal.ca 4 | //registry.npmjs.org/:always-auth=true -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | - [ ] My pull request adheres to the following guidelines 3 | - [ ] Search previous suggestions before making a new one, as yours may be a duplicate. 4 | 5 | closes # 6 | 7 | Thanks for contributing! -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/createInstanceResult.json: -------------------------------------------------------------------------------- 1 | {"bpmnProcessId":"message-event","version":"5","workflowInstanceKey":"04f04c4b-5404-11e9-8953-0242ac110002","workflowKey":"message-event:5:8e65496a-53fb-11e9-8953-0242ac110002"} -------------------------------------------------------------------------------- /packages/workit/types/nock.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | declare module 'nock'; 7 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/createInstanceResult.json: -------------------------------------------------------------------------------- 1 | {"bpmnProcessId":"message-event","version":"5","workflowInstanceKey":"04f04c4b-5404-11e9-8953-0242ac110002","workflowKey":"message-event:5:8e65496a-53fb-11e9-8953-0242ac110002"} -------------------------------------------------------------------------------- /packages/workit-bpm-client/types/nock.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | declare module 'nock'; 7 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/types/nock.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | declare module 'nock'; 7 | -------------------------------------------------------------------------------- /examples/plugin-metrics/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | tabWidth: 2, 4 | useTabs: false, 5 | semi: true, 6 | singleQuote: true, 7 | quoteProps: 'as-needed', 8 | trailingComma: 'es5', 9 | bracketSpacing: true, 10 | arrowParens: 'avoid', 11 | }; -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-task-module/index.js: -------------------------------------------------------------------------------- 1 | function __export(m) { 2 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 3 | } 4 | Object.defineProperty(exports, "__esModule", { value: true }); 5 | __export(require("./task-module")); 6 | -------------------------------------------------------------------------------- /packages/workit-types/src/utils/validation.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export type ValidationFn = (value: string) => boolean; 8 | -------------------------------------------------------------------------------- /packages/workit-core/src/plugin/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export * from './basePlugin'; 7 | export * from './pluginLoader'; 8 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-simple-module/index.js: -------------------------------------------------------------------------------- 1 | function __export(m) { 2 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 3 | } 4 | Object.defineProperty(exports, "__esModule", { value: true }); 5 | __export(require("./simple-module")); 6 | -------------------------------------------------------------------------------- /packages/workit-types/src/commons/logLevel.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export type Loglevel = 'INFO' | 'DEBUG' | 'NONE' | 'ERROR'; 8 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-notsupported-module/index.js: -------------------------------------------------------------------------------- 1 | function __export(m) { 2 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 3 | } 4 | Object.defineProperty(exports, "__esModule", { value: true }); 5 | __export(require("./simple-module")); 6 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-supported-module/index.js: -------------------------------------------------------------------------------- 1 | function __export(m) { 2 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 3 | } 4 | Object.defineProperty(exports, "__esModule", { value: true }); 5 | __export(require("./simple-module")); 6 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/types/camunda-external-task-client-js.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | declare module 'camunda-external-task-client-js'; 7 | -------------------------------------------------------------------------------- /packages/workit-types/src/http/headers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IHeaders { 8 | [custom: string]: string; 9 | } 10 | -------------------------------------------------------------------------------- /packages/workit-types/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "rootDir": ".", 9 | coverageReporters: ["json", "text"], 10 | testPathIgnorePatterns: ['node_modules', 'lib'] 11 | }; -------------------------------------------------------------------------------- /packages/workit/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "rootDir": ".", 9 | coverageReporters: ["json", "text"], 10 | testPathIgnorePatterns: ['node_modules', 'lib'] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/workit-core/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "rootDir": ".", 9 | coverageReporters: ["json", "text"], 10 | testPathIgnorePatterns: ['node_modules', 'lib'] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/data/workflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment": "A description of my state machine", 3 | "StartAt": "Parallel", 4 | "States": { 5 | "Parallel": { 6 | "Type": "Parallel", 7 | "Branches": [], 8 | "End": true 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "rootDir": ".", 9 | coverageReporters: ["json", "text"], 10 | testPathIgnorePatterns: ['node_modules', 'lib'] 11 | }; 12 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/topicSubscription.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ITopicSubscription { 8 | unsubscribe(): void; 9 | } 10 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowOptions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IWorkflowOptions { 8 | bpmnProcessId: string; 9 | } 10 | -------------------------------------------------------------------------------- /packages/workit-types/src/plugin/hookState.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export enum HookState { 8 | UNINITIALIZED, 9 | LOADED, 10 | UNLOADED, 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/variables.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Variables } from 'camunda-external-task-client-js'; 8 | 9 | export { Variables }; 10 | -------------------------------------------------------------------------------- /examples/basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/link.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ILink { 8 | method: string; 9 | href: string; 10 | rel: string; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit-types/src/commons/paginationOptions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IPaginationOptions { 8 | from: number; 9 | size: number; 10 | } 11 | -------------------------------------------------------------------------------- /packages/workit-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } -------------------------------------------------------------------------------- /examples/binding/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /examples/parallel/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit-types/src/aws/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export * from './awsConfig'; 7 | export * from './sqs/sqsConfig'; 8 | export * from './stepFunction/stepFunctionConfig'; 9 | -------------------------------------------------------------------------------- /packages/workit-types/src/commons/paging.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IPaging { 8 | from: number; 9 | size: number; 10 | totalCount: number; 11 | } 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT_FR.md: -------------------------------------------------------------------------------- 1 | # Code de conduite 2 | 3 | Les participants aux projets doivent souscrire au code de conduite que la Ville de Montréal a adopté. Veuillez lire [le texte intégral](http://ville.montreal.qc.ca/pls/portal/docs/page/intra_fr/media/documents/code_conduite_employes.pdf) afin de comprendre quelles actions seront ou ne seront pas tolérées. 4 | -------------------------------------------------------------------------------- /examples/failure-strategy/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /examples/opentelemetry/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit-types/src/commons/customHeaders.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ICustomHeaders { 8 | [custom: string]: string | Date | number | boolean; 9 | } 10 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | notify: 3 | require_ci_to_pass: no 4 | comment: 5 | layout: "header, changes, diff, files" 6 | behavior: default 7 | coverage: 8 | status: 9 | patch: 10 | default: 11 | target: 80% 12 | project: 13 | default: 14 | target: auto 15 | threshold: 1% 16 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/bpmLogger.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { logger as camundaLogger } from 'camunda-external-task-client-js'; 8 | 9 | export { camundaLogger }; 10 | -------------------------------------------------------------------------------- /packages/workit-core/src/utils/isPrimitive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export const isPrimitive = (value: any) => value === null || (typeof value !== 'object' && typeof value !== 'function'); 7 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/processXmlDefinition.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IProcessXmlDefinition { 8 | id: string; 9 | bpmn20Xml: string; 10 | } 11 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/updateWorkflowRetry.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IUpdateWorkflowRetry { 8 | jobKey: string; 9 | retries: number; 10 | } 11 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "temp", 10 | "node_modules", 11 | "output", 12 | "log", 13 | "mocha", 14 | ".*", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit/src/config/constants/tag.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export const TAG = { 8 | stepFunction: Symbol('stepFunction'), 9 | camundaBpm: Symbol('camundaBpm'), 10 | }; 11 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/sfnClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SFNClient as StepFunctionClient } from '@aws-sdk/client-sfn'; 8 | 9 | export { StepFunctionClient }; 10 | -------------------------------------------------------------------------------- /packages/workit-types/src/plugin/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export * from './hookState'; 7 | export * from './plugin'; 8 | export * from './pluginConfig'; 9 | export * from './plugins'; 10 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/bpmClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Client as CamundaExternalClient } from 'camunda-external-task-client-js'; 8 | 9 | export { CamundaExternalClient }; 10 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/utils/sqs.ts: -------------------------------------------------------------------------------- 1 | export const sqsConfig = { 2 | region: 'eu-west-1', 3 | endpoint: 'http://localhost:4566', 4 | credentials: { 5 | accessKeyId: 'key', 6 | secretAccessKey: 'secret', 7 | }, 8 | }; 9 | 10 | export const QUEUE_URL = process.env.SQS_QUEUE_URL || 'http://localhost:4566/000000000000/sqs-consumer-data'; 11 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/units/__snapshots__/sfnMessage.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Step function Message Step function Message wrap should behave like Camunda Bpm Engine - meta object 1`] = ` 4 | { 5 | "MD5OfBody": "hash", 6 | "a": 1, 7 | "enteredTime": undefined, 8 | "messageId": "id", 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /packages/workit-types/src/plugin/plugins.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { IPluginConfig } from './pluginConfig'; 7 | 8 | export interface IPlugins { 9 | [pluginName: string]: IPluginConfig; 10 | } 11 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | [Français](CODE_OF_CONDUCT_FR.md) 2 | 3 | # Code of Conduct 4 | 5 | Ville de Montreal has adopted a Code of Conduct that we expect project participants to adhere to. Please read the [full text](http://ville.montreal.qc.ca/pls/portal/docs/page/intra_fr/media/documents/code_conduite_employes.pdf) so that you can understand what actions will and will not be tolerated. 6 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IWorkflow } from './workflow'; 8 | 9 | export interface IWorkflowResponse { 10 | workflows: IWorkflow[]; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit-types/src/commons/pagination.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IPaging } from './paging'; 8 | 9 | export interface IPagination { 10 | paging: IPaging; 11 | items: T[]; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflow.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IWorkflow { 8 | bpmnProcessId: string; 9 | workflowKey: string; 10 | resourceName: string; 11 | version: number; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/http/httpOptions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IHeaders } from './headers'; 8 | 9 | export interface IHttpOptions { 10 | headers: IHeaders; 11 | params: Record; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/updateWorkflowVariables.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IUpdateWorkflowVariables { 8 | processInstanceId: string; 9 | variables: T; 10 | local?: boolean; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/deployWorkflowResult.json: -------------------------------------------------------------------------------- 1 | { 2 | "workflows": [ 3 | { 4 | "bpmnProcessId": "message-event", 5 | "workflowKey": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 6 | "resourceName": "MESSAGE_EVENT.bpmn", 7 | "version": 5 8 | } 9 | ], 10 | "key": "8e5e6b98-53fb-11e9-8953-0242ac110002" 11 | } -------------------------------------------------------------------------------- /packages/workit-types/src/core/successStrategy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from './message'; 8 | 9 | export interface ISuccessStrategy { 10 | handle(message: IMessage, service: T): Promise; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/message.ts: -------------------------------------------------------------------------------- 1 | export const message = { 2 | _body: null, 3 | _properties: {}, 4 | set body(value: any) { 5 | this._body = value; 6 | }, 7 | get body(): any { 8 | return this._body; 9 | }, 10 | set properties(value: any) { 11 | this._properties = value; 12 | }, 13 | get properties(): any { 14 | return this._properties; 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /packages/workit-core/tests/utils/func-test.ts: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import { Worker } from '../../models/core/worker'; 3 | 4 | export const run = (worker: Worker, scoped: any, done: any, delay: number = 500) => { 5 | worker.start(); 6 | worker.run(); 7 | 8 | setTimeout(async () => { 9 | await worker.stop(); 10 | assert.isTrue(scoped.isDone()); 11 | done(); 12 | }, delay); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/deployWorkflowResult.json: -------------------------------------------------------------------------------- 1 | { 2 | "workflows": [ 3 | { 4 | "bpmnProcessId": "message-event", 5 | "workflowKey": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 6 | "resourceName": "MESSAGE_EVENT.bpmn", 7 | "version": 5 8 | } 9 | ], 10 | "key": "8e5e6b98-53fb-11e9-8953-0242ac110002" 11 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/message.ts: -------------------------------------------------------------------------------- 1 | export const message = { 2 | _body: null, 3 | _properties: {}, 4 | set body(value: any) { 5 | this._body = value; 6 | }, 7 | get body(): any { 8 | return this._body; 9 | }, 10 | set properties(value: any) { 11 | this._properties = value; 12 | }, 13 | get properties(): any { 14 | return this._properties; 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/deployWorkflowResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IWorkflowResponse } from './workflowResponse'; 8 | 9 | export interface IDeployWorkflowResponse extends IWorkflowResponse { 10 | key: string; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/failureStrategy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from './message'; 8 | 9 | export interface IFailureStrategy { 10 | handle(error: any, message: IMessage, service: T): Promise; 11 | } 12 | -------------------------------------------------------------------------------- /packages/workit-types/src/aws/stepFunction/stepFunctionConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { IAwsConfig } from '../awsConfig'; 7 | import { ISqsConfig } from '../sqs/sqsConfig'; 8 | 9 | export interface IStepFunctionClientConfig extends ISqsConfig, IAwsConfig {} 10 | -------------------------------------------------------------------------------- /packages/workit-types/src/aws/awsConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export interface IAwsConfig { 7 | region: string; 8 | credentials: IAwsCredentials; 9 | } 10 | 11 | export interface IAwsCredentials { 12 | accessKeyId: string; 13 | secretAccessKey: string; 14 | } 15 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/createWorkflowInstanceResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ICreateWorkflowInstanceResponse { 8 | workflowKey: string; 9 | bpmnProcessId: string; 10 | version: number; 11 | workflowInstanceKey: string; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/incidentException.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export class IncidentException extends Error { 8 | public get code() { 9 | return 'Workit.Incident'; 10 | } 11 | 12 | public get retries() { 13 | return 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/message.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IMessageBase { 8 | body: TBody; 9 | properties: TProps; 10 | } 11 | 12 | export type IMessage = IMessageBase; 13 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import './config/container'; 8 | 9 | export * from './config/constants/identifiers'; 10 | 11 | export * from './sfnClient'; 12 | 13 | export * from './sfnSQSClient'; 14 | 15 | export * from './sfnMessage'; 16 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | "typeRoots": ["./types", "./node_modules/@types", "../../node_modules/@types"], 7 | "types": ["node", "jest"] 8 | }, 9 | "exclude": [ 10 | "lib", 11 | "temp", 12 | "node_modules", 13 | "output", 14 | "log", 15 | "mocha", 16 | ".*", 17 | "tests" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/client.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from './message'; 8 | 9 | export interface IClient { 10 | subscribe(onMessageReceived: (message: IMessage, service: T) => Promise): Promise; 11 | unsubscribe(): Promise; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/failureException.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export class FailureException extends Error { 8 | constructor( 9 | message?: string, 10 | public retries: number = 1, 11 | public retryTimeout: number = 1000, 12 | ) { 13 | super(message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/workit-types/src/plugin/pluginConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export interface IPluginConfig { 7 | /** 8 | * Whether to enable the plugin. 9 | * @default true 10 | */ 11 | enabled?: boolean; 12 | 13 | /** 14 | * Path of the trace plugin to load. 15 | */ 16 | path?: string; 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | "esModuleInterop": true, 7 | "typeRoots": ["./types", "./node_modules/@types", "../../node_modules/@types"], 8 | "types": ["node", "jest"] 9 | }, 10 | "exclude": [ 11 | "lib", 12 | "temp", 13 | "node_modules", 14 | "output", 15 | "log", 16 | "mocha", 17 | ".*", 18 | "tests" 19 | ] 20 | } -------------------------------------------------------------------------------- /packages/workit-types/src/commons/logger.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export type LogFunction = (message: string, ...args: unknown[]) => void; 7 | 8 | /** Defines a logger interface. */ 9 | export interface ILogger { 10 | error: LogFunction; 11 | warn: LogFunction; 12 | info: LogFunction; 13 | debug: LogFunction; 14 | } 15 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | * **Olivier Albertini** - [Ville de Montréal](https://github.com/VilledeMontreal) 4 | * **Yann Debonnel** - [Ville de Montréal](https://github.com/VilledeMontreal) 5 | * **Zakaria Chérif Chérid** - [Ville de Montréal](https://github.com/VilledeMontreal) 6 | * **Josh Wulf** - [Zeebe](https://github.com/zeebe-io) 7 | * **JPerron-ca** - [Contributor](https://github.com/jperron-ca) 8 | * **Sylvain Bouchard** - [@sylvain-bouchard](https://github.com/sylvain-bouchard) -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/variables.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IVariables extends IReadOnlyVariables { 8 | set(key: string, value: any): void; 9 | } 10 | 11 | export interface IReadOnlyVariables { 12 | get(key: keyof T): K; 13 | getAll(): T; 14 | [custom: string]: any; 15 | } 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Proposal 3 | labels: ':rocket: Feature Request' 4 | about: Submit a proposal for a new feature 5 | --- 6 | 7 | ## 🚀 Feature Proposal 8 | 9 | A clear and concise description of what the feature is. 10 | 11 | ## Motivation 12 | 13 | Please outline the motivation for the proposal. 14 | 15 | ## Example 16 | 17 | Please provide an example for how this feature would be used. 18 | 19 | ## Pitch 20 | 21 | Why does this feature belong in the library 22 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowProps.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { ICustomHeaders } from '../../commons/customHeaders'; 8 | import { IWorkflowPropsBase } from './workflowPropsBase'; 9 | 10 | export interface IWorkflowProps extends Readonly { 11 | customHeaders: T; 12 | } 13 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/resolveIncident.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IResolveIncident { 8 | skipCustomListeners: boolean; 9 | skipIoMappings: boolean; 10 | instructions: IInstruction[]; 11 | } 12 | 13 | export interface IInstruction { 14 | type: string; 15 | activityId: string; 16 | [custom: string]: any; 17 | } 18 | -------------------------------------------------------------------------------- /packages/workit-core/src/utils/concat.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export const concatPath = (path: string, property: string | number | symbol) => { 7 | let clonePath = path; 8 | if (property && property.toString) { 9 | if (path) { 10 | clonePath += '.'; 11 | } 12 | 13 | clonePath += property.toString(); 14 | } 15 | 16 | return clonePath; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/workit-types/src/http/httpResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IHeaders } from './headers'; 8 | 9 | /** 10 | * https://www.npmjs.com/package/axios#response-schema 11 | */ 12 | export interface IHttpResponse { 13 | data: T; 14 | status: number; 15 | statusText: string; 16 | headers: IHeaders; 17 | 18 | [custom: string]: any; 19 | } 20 | -------------------------------------------------------------------------------- /packages/workit-types/src/process/processHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from '../core/message'; 8 | 9 | export interface IProcessHandler { 10 | on(event: 'message-handled', listener: (e: Error, message: IMessage) => void): this; 11 | on(event: 'message', listener: (message: IMessage) => void): this; 12 | handle(...args: any[]): Promise; 13 | } 14 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/utils/datetime.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export const dateTimeReviver = (key: unknown, value: unknown) => { 7 | let a; 8 | if (typeof value === 'string' && value[0] === '2' && value[value.length - 1] === 'Z') { 9 | a = Date.parse(value); 10 | if (!isNaN(a)) { 11 | return new Date(a); 12 | } 13 | } 14 | return value; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/workit-types/src/process/process.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IProcessHandler } from './processHandler'; 8 | 9 | export interface IProcess { 10 | on(event: 'starting' | 'running' | 'stopping' | 'stopped', listener: () => void): this; 11 | start(): void; 12 | run(): Promise; 13 | stop(): Promise; 14 | getProcessHandler(): IProcessHandler; 15 | } 16 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | "globals": { 6 | "__DEV__": true 7 | }, 8 | "rootDir": ".", 9 | coverageReporters: ["json", "text"], 10 | testPathIgnorePatterns: ['node_modules', 'lib'], 11 | // Node.js 20 compatibility settings 12 | maxWorkers: 1, 13 | workerIdleMemoryLimit: '256MB', 14 | testTimeout: 60000, 15 | // Additional memory management settings 16 | forceExit: true, 17 | detectOpenHandles: true 18 | }; 19 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/camundaBpmCreateInstanceResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { ILink } from './link'; 8 | 9 | export interface ICamundaBpmCreateInstanceResponse { 10 | links: ILink[]; 11 | id: string; 12 | definitionId: string; 13 | businessKey?: string; 14 | caseInstanceId?: string; 15 | ended: boolean; 16 | suspended: boolean; 17 | tenantId?: string; 18 | } 19 | -------------------------------------------------------------------------------- /packages/workit/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import './config/ioc'; 8 | 9 | export * from './config/constants'; 10 | export * from './config/constants/identifiers'; 11 | export * from './config/constants/tag'; 12 | export * from './config/ioc'; 13 | export * from './camunda-n-mq/client'; 14 | export * from './camunda-n-mq/clientManager'; 15 | export * from './stepFunction/stepFunctionManager'; 16 | -------------------------------------------------------------------------------- /packages/workit-types/src/tasks/task.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from '../core/message'; 8 | 9 | export interface ITask { 10 | readonly name: string; 11 | /** 12 | * All your business logic related to the task should be executed here. 13 | * A task tends to be a controller, so you can inject services among other things in the ctor 14 | */ 15 | execute(model: I): Promise; 16 | } 17 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/createWorkflowInstanceResponse.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": [ 3 | { 4 | "method": "GET", 5 | "href": "http://localhost:8080/engine-rest/process-instance/04f04c4b-5404-11e9-8953-0242ac110002", 6 | "rel": "self" 7 | } 8 | ], 9 | "id": "04f04c4b-5404-11e9-8953-0242ac110002", 10 | "definitionId": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 11 | "businessKey": null, 12 | "caseInstanceId": null, 13 | "ended": false, 14 | "suspended": false, 15 | "tenantId": null 16 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/units/variable.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IVariables } from '@villedemontreal/workit-types'; 8 | import { Variables } from '../../src/variables'; 9 | 10 | describe('Variables class', () => { 11 | it('should return undefined on non existing variable', () => { 12 | const vars: IVariables = new Variables(); 13 | expect(vars.get('_meta')).toBeUndefined(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/workit-core/src/tracer/noopTracerPropagator.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Context } from '@opentelemetry/api'; 8 | import { IMessageBase, ITracerPropagator } from '@villedemontreal/workit-types'; 9 | 10 | export class NoopTracerPropagator implements ITracerPropagator { 11 | public extractFromMessage(message: IMessageBase<{ requestInfo: unknown }>): Context | undefined { 12 | return undefined; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/getWorkflowResponse.2.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "message-event:6:76bf01bc-5410-11e9-8953-0242ac110002", 3 | "key": "message-event", 4 | "category": "http://bpmn.io/schema/bpmn", 5 | "description": null, 6 | "name": "Message event", 7 | "version": 6, 8 | "resource": "MESSAGE_EVENT.bpmn", 9 | "deploymentId": "76bcb7ca-5410-11e9-8953-0242ac110002", 10 | "diagram": null, 11 | "suspended": false, 12 | "tenantId": null, 13 | "versionTag": null, 14 | "historyTimeToLive": null, 15 | "startableInTasklist": true 16 | } -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/scripts/localstack/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | echo "configuring localstack" 6 | echo "===================" 7 | LOCALSTACK_HOST=localhost 8 | AWS_REGION=eu-west-1 9 | 10 | 11 | # https://docs.aws.amazon.com/cli/latest/reference/sqs/create-queue.html 12 | create_queue() { 13 | local QUEUE_NAME_TO_CREATE=$1 14 | awslocal --endpoint-url=http://${LOCALSTACK_HOST}:4566 sqs create-queue --queue-name ${QUEUE_NAME_TO_CREATE} --region ${AWS_REGION} --attributes VisibilityTimeout=30 15 | } 16 | 17 | create_queue "sqs-consumer-data" -------------------------------------------------------------------------------- /packages/workit-types/src/core/interceptor.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from './message'; 8 | /** 9 | * When we receive a payload from the client, we execute all interceptors. 10 | * Those interceptors return IMessage that is merged (Shallow copy for body and customHeaders). 11 | * This payload is passed to the task bound to the IoC. 12 | */ 13 | export type Interceptor = (message: T) => Promise; 14 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/createWorkflowInstanceResponse.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": [ 3 | { 4 | "method": "GET", 5 | "href": "http://localhost:8080/engine-rest/process-instance/04f04c4b-5404-11e9-8953-0242ac110002", 6 | "rel": "self" 7 | } 8 | ], 9 | "id": "04f04c4b-5404-11e9-8953-0242ac110002", 10 | "definitionId": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 11 | "businessKey": null, 12 | "caseInstanceId": null, 13 | "ended": false, 14 | "suspended": false, 15 | "tenantId": null 16 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/getWorkflowResponse.2.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "message-event:6:76bf01bc-5410-11e9-8953-0242ac110002", 3 | "key": "message-event", 4 | "category": "http://bpmn.io/schema/bpmn", 5 | "description": null, 6 | "name": "Message event", 7 | "version": 6, 8 | "resource": "MESSAGE_EVENT.bpmn", 9 | "deploymentId": "76bcb7ca-5410-11e9-8953-0242ac110002", 10 | "diagram": null, 11 | "suspended": false, 12 | "tenantId": null, 13 | "versionTag": null, 14 | "historyTimeToLive": null, 15 | "startableInTasklist": true 16 | } -------------------------------------------------------------------------------- /packages/workit/tests/utils/func-test.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Worker } from '@villedemontreal/workit-core'; 8 | import * as assert from 'assert'; 9 | 10 | export const run = (worker: Worker, scoped: any, done: any, delay: number = 500) => { 11 | worker.start(); 12 | worker.run(); 13 | 14 | setTimeout(async () => { 15 | await worker.stop(); 16 | assert.ok(scoped.isDone()); 17 | done(); 18 | }, delay); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/processDefinition.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IProcessDefinition { 8 | id: string; 9 | key: string; 10 | category: string; 11 | description?: string; 12 | name: string; 13 | version: number; 14 | resource: string; 15 | deploymentId: string; 16 | diagram?: any; 17 | suspended: boolean; 18 | tenantId?: string; 19 | versionTag?: any; 20 | historyTimeToLive: number; 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug report 3 | labels: ':bug: Bug' 4 | about: Create a report to help us improve 5 | --- 6 | 7 | ## 🐛 Bug Report 8 | 9 | A clear and concise description of what the bug is. 10 | 11 | ## To Reproduce 12 | 13 | Steps to reproduce the behavior: 14 | 15 | ## Expected behavior 16 | 17 | A clear and concise description of what you expected to happen. 18 | 19 | ## Link to repl or repo (highly encouraged) 20 | 21 | Please provide either a [repl.it demo](https://repl.it) or a minimal repository on GitHub. 22 | 23 | ## Your environment 24 | Nodejs: 25 | workit: 26 | Windows/Mac 27 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import './config/container'; 8 | 9 | export * from './config/constants/identifiers'; 10 | 11 | export * from './bpmClient'; 12 | export * from './bpmLogger'; 13 | export * from './camundaBpmClient'; 14 | export * from './camundaMapperProperties'; 15 | export * from './logger'; 16 | export * from './camundaMessage'; 17 | 18 | export * from './utils/utils'; 19 | export * from './variables'; 20 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-task-module/task-module.js: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, "__esModule", { value: true }); 2 | const core_1 = require('../../../../../lib/src/plugin/basePlugin'); 3 | 4 | class TaskModulePlugin extends core_1.BasePlugin { 5 | constructor(name) { 6 | super(`@villemontreal/plugin-${name}`); 7 | this.moduleName = name; 8 | } 9 | 10 | bind() { 11 | 12 | } 13 | 14 | unbind() { 15 | 16 | } 17 | } 18 | exports.TaskModulePlugin = TaskModulePlugin; 19 | const plugin = new TaskModulePlugin('task'); 20 | exports.plugin = plugin; 21 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/utils/func-test.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Worker } from '@villedemontreal/workit-core'; 8 | import { assert } from 'chai'; 9 | 10 | export const run = (worker: Worker, scoped: any, done: any, delay: number = 500) => { 11 | worker.start(); 12 | worker.run(); 13 | 14 | setTimeout(async () => { 15 | await worker.stop(); 16 | assert.isTrue(scoped.isDone()); 17 | done(); 18 | }, delay); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/workit/tests/data/camundaResponsePaginated2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 4 | "key": "message-event", 5 | "category": "http://bpmn.io/schema/bpmn", 6 | "description": null, 7 | "name": "Message event", 8 | "version": 1, 9 | "resource": "MESSAGE_EVENT.bpmn", 10 | "deploymentId": "ea1ac083-9b3e-11e9-ba13-0242ac110002", 11 | "diagram": null, 12 | "suspended": false, 13 | "tenantId": null, 14 | "versionTag": null, 15 | "historyTimeToLive": null, 16 | "startableInTasklist": true 17 | } 18 | ] -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowPropsBase.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IWorkflowPropsBase { 8 | activityId: string; 9 | jobKey: string; 10 | processInstanceId: string; 11 | workflowKey: string; 12 | workflowInstanceKey: string; 13 | workflowDefinitionVersion: number; 14 | bpmnProcessId: string; 15 | retries: number | null; 16 | lockExpirationTime: Date; 17 | topicName: string; 18 | workerId: string; 19 | [custom: string]: any; 20 | } 21 | -------------------------------------------------------------------------------- /packages/workit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "plugins": [ 4 | "@typescript-eslint", 5 | "prettier", 6 | "header", 7 | "import" 8 | ], 9 | "extends": [ 10 | "airbnb-typescript/base", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 14 | "prettier" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "project": "./tsconfig.json" 19 | }, 20 | "rules": require('../../eslint.rules.js') 21 | } -------------------------------------------------------------------------------- /packages/workit-core/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "plugins": [ 4 | "@typescript-eslint", 5 | "prettier", 6 | "header", 7 | "import" 8 | ], 9 | "extends": [ 10 | "airbnb-typescript/base", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 14 | "prettier" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "project": "./tsconfig.json" 19 | }, 20 | "rules": require('../../eslint.rules.js') 21 | } -------------------------------------------------------------------------------- /packages/workit-core/src/strategies/SuccessStrategySimple.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { ICamundaService, IMessage, ISuccessStrategy } from '@villedemontreal/workit-types'; 8 | import { injectable } from 'inversify'; 9 | import 'reflect-metadata'; 10 | 11 | @injectable() 12 | export class SuccessStrategySimple implements ISuccessStrategy { 13 | public handle(message: IMessage, service: ICamundaService): Promise { 14 | return service.ack(message); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/workit-types/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "plugins": [ 4 | "@typescript-eslint", 5 | "prettier", 6 | "header", 7 | "import" 8 | ], 9 | "extends": [ 10 | "airbnb-typescript/base", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 14 | "prettier" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "project": "./tsconfig.json" 19 | }, 20 | "rules": require('../../eslint.rules.js') 21 | } -------------------------------------------------------------------------------- /packages/workit-types/src/tracer/tracerPropagator.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Context } from '@opentelemetry/api'; 8 | import { IMessageBase } from '../core/message'; 9 | 10 | /** 11 | * Utility for tracer 12 | */ 13 | export interface ITracerPropagator { 14 | /** 15 | * Used for extracting traceId from message 16 | * 17 | * @param {IMessageBase} message the message coming from the server 18 | */ 19 | extractFromMessage(message: IMessageBase): Context | undefined; 20 | } 21 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "plugins": [ 4 | "@typescript-eslint", 5 | "prettier", 6 | "header", 7 | "import" 8 | ], 9 | "extends": [ 10 | "airbnb-typescript/base", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 14 | "prettier" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "project": "./tsconfig.json" 19 | }, 20 | "rules": require('../../eslint.rules.js') 21 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/data/camundaResponsePaginated2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 4 | "key": "message-event", 5 | "category": "http://bpmn.io/schema/bpmn", 6 | "description": null, 7 | "name": "Message event", 8 | "version": 1, 9 | "resource": "MESSAGE_EVENT.bpmn", 10 | "deploymentId": "ea1ac083-9b3e-11e9-ba13-0242ac110002", 11 | "diagram": null, 12 | "suspended": false, 13 | "tenantId": null, 14 | "versionTag": null, 15 | "historyTimeToLive": null, 16 | "startableInTasklist": true 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-supported-module/simple-module.js: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, "__esModule", { value: true }); 2 | const core_1 = require('../../../../../lib/src/plugin/basePlugin'); 3 | 4 | class SimpleModulePlugin extends core_1.BasePlugin { 5 | constructor(name) { 6 | super(`@villemontreal/plugin-${name}`); 7 | this.moduleName = name; 8 | } 9 | 10 | bind() { 11 | 12 | } 13 | 14 | unbind() { 15 | } 16 | } 17 | exports.SimpleModulePlugin = SimpleModulePlugin; 18 | const plugin = new SimpleModulePlugin(); 19 | plugin.supportedVersions = ['^0.0.1']; 20 | exports.plugin = plugin; 21 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/config/constants/params.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export const MAX_ERROR_CAUSE_LENGTH = Number(process.env.WORKIT_STEP_FUNCTION_MAX_ERROR_CAUSE_LENGTH) || 32768; 7 | export const MAX_PAYLOAD_LENGTH = Number(process.env.WORKIT_STEP_FUNCTION_MAX_PAYLOAD_LENGTH) || 262144; 8 | export const MAX_ERROR_CODE_LENGTH = Number(process.env.WORKIT_STEP_FUNCTION_MAX_ERROR_CODE_LENGTH) || 256; 9 | export const DISABLE_DATETIME_REVIVER = !!process.env.WORKIT_DISABLE_DATETIME_REVIVER; 10 | -------------------------------------------------------------------------------- /.circleci/checksum.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Usage: checksum.sh filename 4 | # 5 | # checksum.sh computes the checksum of the repo's top level `package.json` 6 | # and `package.json` files in package/, putting the hashes into a file in 7 | # alphabetical order. Must be run at the top level of the repository. 8 | 9 | 10 | if [ -z $1 ]; then 11 | echo "Usage: checksum.sh filename" 12 | exit 1 13 | fi 14 | 15 | FILE=$1 16 | 17 | # remove existing file 18 | if [ -f $FILE ]; then 19 | rm $FILE 20 | fi 21 | 22 | openssl md5 package.json >> $FILE 23 | 24 | find packages/*/package.json examples/*/package.json | xargs -I{} openssl md5 {} >> $FILE 25 | 26 | sort -o $FILE $FILE 27 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "plugins": [ 4 | "@typescript-eslint", 5 | "prettier", 6 | "header", 7 | "import" 8 | ], 9 | "extends": [ 10 | "airbnb-typescript/base", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 14 | "prettier" 15 | ], 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "project": "./tsconfig.json" 19 | }, 20 | "rules": require('../../eslint.rules.js') 21 | } -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/incident.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IIncident { 8 | id: string; 9 | processDefinitionId: string; 10 | processInstanceId: string; 11 | executionId: string; 12 | incidentTimestamp: string; 13 | incidentType: string; 14 | activityId: string; 15 | causeIncidentId: string; 16 | rootCauseIncidentId: string; 17 | configuration: string; 18 | incidentMessage?: string | null; 19 | tenantId?: string | null; 20 | jobDefinitionId?: string | null; 21 | } 22 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-notsupported-module/simple-module.js: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, "__esModule", { value: true }); 2 | const core_1 = require('../../../../../lib/plugin/basePlugin'); 3 | 4 | class SimpleModulePlugin extends core_1.BasePlugin { 5 | constructor(name) { 6 | super(`@villemontreal/plugin-${name}`); 7 | this.moduleName = name; 8 | } 9 | 10 | bind() { 11 | 12 | } 13 | 14 | unbind() { 15 | 16 | } 17 | } 18 | exports.SimpleModulePlugin = SimpleModulePlugin; 19 | const plugin = new SimpleModulePlugin('notsupported-module'); 20 | plugin.supportedVersions = ['1.0.0']; 21 | exports.plugin = plugin; 22 | -------------------------------------------------------------------------------- /examples/binding/src/deploy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 7 | import { IoC } from '@villedemontreal/workit-core'; 8 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 9 | 10 | (async (): Promise => { 11 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 12 | const path = `${process.cwd()}/workflow/camunda/BPMN_P_DEMO.bpmn`; 13 | await cm.deployWorkflow(path); 14 | console.log('Success!'); 15 | })(); 16 | -------------------------------------------------------------------------------- /examples/parallel/src/deploy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | const path = `${process.cwd()}/worklfow/camunda/BPMN_P_DEMO.bpmn`; 14 | await cm.deployWorkflow(path); 15 | console.log('Success!'); 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/plugin-metrics/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./lib", 7 | "rootDir": "./", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "declaration": true, 13 | "declarationMap": true, 14 | "sourceMap": true, 15 | "experimentalDecorators": true, 16 | "emitDecoratorMetadata": true, 17 | "resolveJsonModule": true 18 | }, 19 | "include": [ 20 | "src/**/*", 21 | "tasks/**/*" 22 | ], 23 | "exclude": [ 24 | "node_modules", 25 | "lib", 26 | "**/*.test.ts" 27 | ] 28 | } -------------------------------------------------------------------------------- /examples/opentelemetry/src/deploy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | const path = `${process.cwd()}/workflow/camunda/BPMN_P_DEMO.bpmn`; 14 | await cm.deployWorkflow(path); 15 | console.log('Success!'); 16 | })(); 17 | -------------------------------------------------------------------------------- /packages/workit/src/config/container.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { camundaLogger, logger } from '@villedemontreal/workit-bpm-client'; 8 | import { kernel } from '@villedemontreal/workit-core'; 9 | import { constants } from './constants'; 10 | import { SERVICE_IDENTIFIER } from './constants/identifiers'; 11 | 12 | kernel.bind(SERVICE_IDENTIFIER.logger).toConstantValue(camundaLogger).whenDefault(); 13 | Object.values(constants.envs).forEach((env) => { 14 | kernel.bind(SERVICE_IDENTIFIER.logger).toConstantValue(logger).whenNamed(env); 15 | }); 16 | -------------------------------------------------------------------------------- /examples/failure-strategy/src/deploy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | const path = `${process.cwd()}/workflow/camunda/BPMN_DEMO.bpmn`; 14 | await cm.deployWorkflow(path); 15 | console.log('Success!'); 16 | })(); 17 | -------------------------------------------------------------------------------- /packages/workit-types/src/aws/sqs/sqsConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export interface ISqsConfig { 7 | queueUrl: string; 8 | waitTimeSeconds?: number; 9 | /** 10 | * By default true, the consumer will NOT treat an empty object or array from either of the handlers as a acknowledgement of no messages and will delete those messages as a result. Set this to false to not always acknowledge all messages no matter the returned value. 11 | * We let the step function acknowledgement decide to requeue a message or not 12 | */ 13 | alwaysAcknowledge?: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/scripts/initIntTests.sh: -------------------------------------------------------------------------------- 1 | docker compose --file ./test/scripts/docker-compose.yml up -d 2 | 3 | if [ $? -eq 0 ] 4 | then 5 | echo "Successfully started docker" 6 | else 7 | echo "Could not start docker" >&2 8 | exit 1 9 | fi 10 | 11 | export AWS_ACCESS_KEY_ID="key" 12 | export AWS_SECRET_ACCESS_KEY="secret" 13 | export AWS_DEFAULT_REGION="eu-west-1" 14 | 15 | echo "Waiting for SQS, attempting every 5s" 16 | until $(aws --endpoint-url=http://localhost:4566 sqs get-queue-url --queue-name sqs-consumer-data --region eu-west-1 | grep "{ 17 | "QueueUrl": "http://localhost:4566/000000000000/sqs-consumer-data" 18 | }" > /dev/null); do 19 | printf '.' 20 | sleep 5 21 | done 22 | echo ' Service is up!' -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__snapshots__/camundaMessage.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`camundaMessage unmap 1`] = ` 4 | Variables { 5 | "get": [Function], 6 | "getAll": [Function], 7 | "getAllTyped": [Function], 8 | "getDirtyVariables": [Function], 9 | "getTyped": [Function], 10 | "set": [Function], 11 | "setAll": [Function], 12 | "setAllTyped": [Function], 13 | "setTransient": [Function], 14 | "setTyped": [Function], 15 | } 16 | `; 17 | 18 | exports[`camundaMessage wrap 1`] = ` 19 | { 20 | "errorDetails": "{"name":"error","message":"Oopps","retries":0,"retryTimeout":15000}", 21 | "errorMessage": "Oopps", 22 | "retries": 0, 23 | "retryTimeout": 15000, 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /examples/plugin-metrics/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [7.0.1](https://github.com/VilledeMontreal/workit/compare/v6.0.1...v7.0.1) (2025-10-28) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * behaviour and tests ([8b3b946](https://github.com/VilledeMontreal/workit/commit/8b3b946bd1e7845957f527d8d14607a5d4f171e1)) 12 | 13 | 14 | 15 | 16 | 17 | # [7.0.0](https://github.com/VilledeMontreal/workit/compare/v6.0.1...v7.0.0) (2025-10-28) 18 | 19 | 20 | ### Refactoring 21 | 22 | * behaviour and tests ([8b3b946](https://github.com/VilledeMontreal/workit/commit/8b3b946bd1e7845957f527d8d14607a5d4f171e1)) 23 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/camundaService.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage } from '../message'; 8 | import { FailureException } from './failureException'; 9 | 10 | export interface ICamundaService { 11 | hasBeenThreated: boolean; 12 | /** Complete the task with a success */ 13 | ack(message: IMessage): Promise; 14 | 15 | /** 16 | * Fail the task with an informative message as to the cause. Optionally pass in a value remaining retries. 17 | * Pass in 0 for retries to raise an incident 18 | */ 19 | nack(e: FailureException): Promise; 20 | } 21 | -------------------------------------------------------------------------------- /packages/workit-types/README.md: -------------------------------------------------------------------------------- 1 | # WorkIt API for Javascript 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) 4 | 5 | This package provides TypeScript interfaces and enums for the Workit models. 6 | 7 | ```bash 8 | npm i @villedemontreal/workit-types 9 | ``` 10 | 11 | ## Useful links 12 | - [Get started in 2 minutes](https://github.com/VilledeMontreal/workit/blob/master/getting-started). 13 | - [Examples](https://github.com/VilledeMontreal/workit/blob/master/examples). 14 | - [Documentation is available in this folder](https://github.com/VilledeMontreal/workit/tree/master/packages/workit/.docs) 15 | - Comprehensive API documentation is available [online](https://villedemontreal.github.io/workit/) and in the `docs` subdirectory 16 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/publishMessage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IPublishMessage { 8 | /** Should match the "Message Name" in a BPMN Message */ 9 | name: string; 10 | /* The value to match with the field specified as "Subscription Correlation Key" in BPMN 11 | * It's the correlationKeys for the bpmn platform. 12 | */ 13 | correlation: K; 14 | /** 15 | * Unique ID for this message. 16 | * It's the processInstanceId in the bpmn plateform. Optional if it's a message start event. 17 | */ 18 | messageId?: string; 19 | variables: T; 20 | } 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/regression.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💥 Regression Report 3 | labels: ':boom: Regression' 4 | about: Report unexpected behavior that worked in previous versions 5 | --- 6 | 7 | 8 | ## 💥 Regression Report 9 | 10 | A clear and concise description of what the regression is. 11 | 12 | ## Last working version 13 | 14 | Worked up to version: 15 | 16 | Stopped working in version: 17 | 18 | ## To Reproduce 19 | 20 | Steps to reproduce the behavior: 21 | 22 | ## Expected behavior 23 | 24 | A clear and concise description of what you expected to happen. 25 | 26 | ## Link to repl or repo (highly encouraged) 27 | 28 | Please provide either a [repl.it demo](https://repl.it) or a minimal repository on GitHub. 29 | 30 | Issues without a reproduction link are likely to stall. 31 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export * from './bpmnDeployResponse'; 8 | export * from './camundaClient'; 9 | export * from './camundaConfig'; 10 | export * from './camundaRepository'; 11 | export * from './camundaBpmCreateInstanceResponse'; 12 | export * from './incident'; 13 | export * from './payload'; 14 | export * from './processDefinition'; 15 | export * from './processXmlDefinition'; 16 | export * from './resolveIncident'; 17 | export * from './subscriptionOptions'; 18 | export * from './topicSubscription'; 19 | export * from './variables'; 20 | export * from './link'; 21 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/camundaClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IVariablePayload } from './payload'; 8 | import { ITopicSubscription } from './topicSubscription'; 9 | 10 | export interface ICamundaClient { 11 | executeTask(task: IVariablePayload): void; 12 | poll(): void; 13 | sanitizeOptions(customOptions: any): void; 14 | start(): void; 15 | stop(): void; 16 | subscribe(topic: string, handler: (obj: { task: IVariablePayload; taskService: any }) => void): ITopicSubscription; 17 | subscribe(topic: string, customOptions: any, handler: (obj: any) => void): ITopicSubscription; 18 | } 19 | -------------------------------------------------------------------------------- /packages/workit-core/src/specs/taskBase.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IMessage, ITask } from '@villedemontreal/workit-types'; 8 | import { injectable } from 'inversify'; 9 | import 'reflect-metadata'; 10 | 11 | @injectable() 12 | export abstract class TaskBase implements ITask { 13 | public get name() { 14 | return this.constructor.name; 15 | } 16 | 17 | /** 18 | * All your business logic related to the task should be executed here. 19 | * A task tends to be a controller, so you can inject services among other things in the ctor 20 | */ 21 | public abstract execute(model: I): Promise; 22 | } 23 | -------------------------------------------------------------------------------- /packages/workit/src/camundaBpm/camundaManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 8 | import { inject, injectable, named } from 'inversify'; 9 | import { ClientManager } from '../camunda-n-mq/clientManager'; 10 | import { SERVICE_IDENTIFIER } from '../config/constants/identifiers'; 11 | import { TAG } from '../config/constants/tag'; 12 | 13 | @injectable() 14 | export class CamundaManager extends ClientManager { 15 | constructor(@inject(SERVICE_IDENTIFIER.camunda_client) @named(TAG.camundaBpm) client: IWorkflowClient) { 16 | super(client); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/workit-core/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export * from './config/container'; 8 | export * from './config/constants/identifiers'; 9 | export * from './config/constants'; 10 | export * from './common/noopLogger'; 11 | 12 | export * from './processHandler/simpleCamundaProcessHandler'; 13 | export * from './interceptors'; 14 | 15 | export * from './specs/taskBase'; 16 | 17 | export * from './strategies/FailureStrategySimple'; 18 | export * from './strategies/SuccessStrategySimple'; 19 | 20 | export * from './IoC'; 21 | 22 | export * from './worker'; 23 | 24 | export * from './plugin'; 25 | 26 | export * from './utils/utils'; 27 | -------------------------------------------------------------------------------- /packages/workit/src/stepFunction/stepFunctionManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 8 | import { inject, injectable, named } from 'inversify'; 9 | import { ClientManager } from '../camunda-n-mq/clientManager'; 10 | import { SERVICE_IDENTIFIER } from '../config/constants/identifiers'; 11 | import { TAG } from '../config/constants/tag'; 12 | 13 | @injectable() 14 | export class StepFunctionManager extends ClientManager { 15 | constructor(@inject(SERVICE_IDENTIFIER.camunda_client) @named(TAG.stepFunction) client: IWorkflowClient) { 16 | super(client); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/createWorkflowInstance.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ICreateWorkflowInstance { 8 | // CamundaBPM can set process Definition id or key, since id include version, you don't need to set the version property. 9 | // In case you pass the definition key, the latest version of the bpmn will receive the instance. 10 | // Example: 11 | // CamundaBPM: bpmnProcessId can be "DEMO:2:dahjs-asdkjh-wqieq-wwwq" or "DEMO" 12 | bpmnProcessId: string; 13 | // Not used in camundaBpm due to API restriction and it's included in process Definition Id 14 | version?: number; 15 | variables: T; 16 | } 17 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "8.0.0", 3 | "version": "7.0.1", 4 | "packages": [ 5 | "examples/*", 6 | "packages/*" 7 | ], 8 | "command": { 9 | "publish": { 10 | "conventionalCommits": true, 11 | "registry": "https://registry.npmjs.org/", 12 | "ignoreChanges": [], 13 | "allowBranch": "master", 14 | "message": "chore(release): publish" 15 | } 16 | }, 17 | "changelog": { 18 | "repo": "VilledeMontreal/workit", 19 | "labels": { 20 | "breaking": ":boom: Breaking Change", 21 | "enhancement": ":rocket: (Enhancement)", 22 | "bug": ":bug: (Bug Fix)", 23 | "core": ":wrench: Core", 24 | "documentation": ":books: (Refine Doc)", 25 | "feat": ":sparkles: (Feature)" 26 | }, 27 | "cacheDir": ".changelog" 28 | }, 29 | "npmClient": "npm" 30 | } -------------------------------------------------------------------------------- /packages/workit-core/src/common/noopLogger.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { ILogger } from '@villedemontreal/workit-types'; 7 | 8 | /** No-op implementation of ILogger */ 9 | export class NoopLogger implements ILogger { 10 | // By default does nothing 11 | public debug(message: string, ...args: unknown[]) {} 12 | 13 | // By default does nothing 14 | public error(message: string, ...args: unknown[]) {} 15 | 16 | // By default does nothing 17 | public warn(message: string, ...args: unknown[]) {} 18 | 19 | // By default does nothing 20 | public info(message: string, ...args: unknown[]) {} 21 | } 22 | 23 | export const NOOP_LOGGER = new NoopLogger(); 24 | -------------------------------------------------------------------------------- /examples/parallel/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This example shows how to use [Workit](https://villedemontreal.github.io/workit/) to create a simple Node.js application - e.g. a worker that executes simple tasks. You will learn how to run parallel tasks. 4 | 5 | Have fun! 6 | 7 | ## Installation 8 | 9 | ```sh 10 | $ # from this directory 11 | $ npm install 12 | ``` 13 | and then 14 | ```sh 15 | $ # from this directory 16 | $ npm run build 17 | ``` 18 | 19 | ## Run the Application 20 | 21 | ```sh 22 | $ # from this directory 23 | $ # deploy a bpmn provided in the example 24 | $ npm deploy 25 | $ # create instance(s) 26 | $ npm create-instance 27 | $ # run worker 28 | $ npm worker 29 | ``` 30 | 31 | ## Useful links 32 | - For more information on workit, visit: 33 | 34 | ## LICENSE 35 | 36 | MIT 37 | -------------------------------------------------------------------------------- /packages/workit-types/src/process/processHandlerConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Interceptor } from '../core/interceptor'; 8 | import { ITracerPropagator } from '../tracer/tracerPropagator'; 9 | 10 | export interface IProcessHandlerConfig { 11 | /** 12 | * When we receive a payload from the client, we execute all interceptors. 13 | * Those interceptors return IMessage that is merged (Shallow copy for body and customHeaders). 14 | * This payload is passed to the task (bound to the IoC). 15 | */ 16 | interceptors?: Interceptor | Interceptor[]; 17 | /** 18 | * Used for extracting traceId from message 19 | */ 20 | propagation?: ITracerPropagator; 21 | } 22 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/incidentResponse.camunda.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "db94be11-5417-11e9-8953-0242ac110002", 4 | "processDefinitionId": "message-event:6:76bf01bc-5410-11e9-8953-0242ac110002", 5 | "processInstanceId": "76c913e7-5410-11e9-8953-0242ac110002", 6 | "executionId": "76c93afd-5410-11e9-8953-0242ac110002", 7 | "incidentTimestamp": "2019-04-01T00:48:25.645+0000", 8 | "incidentType": "failedExternalTask", 9 | "activityId": "Task_1effr2c", 10 | "causeIncidentId": "db94be11-5417-11e9-8953-0242ac110002", 11 | "rootCauseIncidentId": "db94be11-5417-11e9-8953-0242ac110002", 12 | "configuration": "76c93b00-5410-11e9-8953-0242ac110002", 13 | "incidentMessage": null, 14 | "tenantId": null, 15 | "jobDefinitionId": null 16 | } 17 | ] -------------------------------------------------------------------------------- /examples/failure-strategy/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This example shows how to use [Workit](https://villedemontreal.github.io/workit/) to create a simple Node.js application - e.g. a worker that executes a simple task. You will learn how to handle exceptions through Workit. 4 | 5 | Have fun! 6 | 7 | ## Installation 8 | 9 | ```sh 10 | $ # from this directory 11 | $ npm install 12 | ``` 13 | and then 14 | ```sh 15 | $ # from this directory 16 | $ npm run build 17 | ``` 18 | 19 | ## Run the Application 20 | 21 | ```sh 22 | $ # from this directory 23 | $ # deploy a bpmn provided in the example 24 | $ npm deploy 25 | $ # create instance(s) 26 | $ npm create-instance 27 | $ # run worker 28 | $ npm worker 29 | ``` 30 | 31 | ## Useful links 32 | - For more information on workit, visit: 33 | 34 | ## LICENSE 35 | 36 | MIT 37 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/incidentResponse.camunda.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "db94be11-5417-11e9-8953-0242ac110002", 4 | "processDefinitionId": "message-event:6:76bf01bc-5410-11e9-8953-0242ac110002", 5 | "processInstanceId": "76c913e7-5410-11e9-8953-0242ac110002", 6 | "executionId": "76c93afd-5410-11e9-8953-0242ac110002", 7 | "incidentTimestamp": "2019-04-01T00:48:25.645+0000", 8 | "incidentType": "failedExternalTask", 9 | "activityId": "Task_1effr2c", 10 | "causeIncidentId": "db94be11-5417-11e9-8953-0242ac110002", 11 | "rootCauseIncidentId": "db94be11-5417-11e9-8953-0242ac110002", 12 | "configuration": "76c93b00-5410-11e9-8953-0242ac110002", 13 | "incidentMessage": null, 14 | "tenantId": null, 15 | "jobDefinitionId": null 16 | } 17 | ] -------------------------------------------------------------------------------- /examples/binding/src/create-process-instances.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | for (let index = 0; index < 1; index += 1) { 14 | await cm.createWorkflowInstance({ 15 | bpmnProcessId: 'BPMN_P_DEMO', 16 | variables: { 17 | amount: 1000, 18 | hello: 'world', 19 | }, 20 | }); 21 | } 22 | console.log('Success!'); 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/parallel/src/create-process-instances.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | for (let index = 0; index < 1; index += 1) { 14 | await cm.createWorkflowInstance({ 15 | bpmnProcessId: 'BPMN_P_DEMO', 16 | variables: { 17 | amount: 1000, 18 | hello: 'world', 19 | }, 20 | }); 21 | } 22 | console.log('Success!'); 23 | })(); 24 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/utils/func-test.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Worker } from '@villedemontreal/workit-core'; 8 | import * as assert from 'assert'; 9 | import { readFileSync } from 'fs'; 10 | import * as path from 'path'; 11 | 12 | export const run = (worker: Worker, scoped: any, done: any, delay: number = 500) => { 13 | worker.start(); 14 | worker.run(); 15 | 16 | setTimeout(async () => { 17 | await worker.stop(); 18 | assert.ok(scoped.isDone()); 19 | done(); 20 | }, delay); 21 | }; 22 | 23 | export const readJsonFileSync = (filePath: string) => { 24 | const absPath = path.resolve(filePath); 25 | return JSON.parse(readFileSync(absPath).toString()); 26 | }; 27 | -------------------------------------------------------------------------------- /examples/binding/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This example shows how to use [Workit](https://villedemontreal.github.io/workit/) to create a simple Node.js application - e.g. a worker that executes a simple task. You will learn how to manage versioning through the IoC between tasks and BPMN 4 | 5 | Have fun! 6 | 7 | ## Installation 8 | 9 | ```sh 10 | $ # from this directory 11 | $ npm install 12 | ``` 13 | and then 14 | ```sh 15 | $ # from this directory 16 | $ npm run build 17 | ``` 18 | 19 | ## Run the Application 20 | 21 | ```sh 22 | $ # from this directory 23 | $ # deploy a bpmn provided in the example 24 | $ npm deploy 25 | $ # create instance(s) 26 | $ npm create-instance 27 | $ # run worker 28 | $ npm worker 29 | ``` 30 | 31 | ## Useful links 32 | - For more information on workit, visit: 33 | 34 | ## LICENSE 35 | 36 | MIT 37 | -------------------------------------------------------------------------------- /examples/opentelemetry/src/create-process-instances.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | for (let index = 0; index < 1; index += 1) { 14 | await cm.createWorkflowInstance({ 15 | bpmnProcessId: 'BPMN_P_DEMO', 16 | variables: { 17 | amount: 1000, 18 | hello: 'world', 19 | }, 20 | }); 21 | } 22 | console.log('Success!'); 23 | })(); 24 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "allowUnusedLabels": false, 5 | "declaration": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "module": "commonjs", 8 | "noEmitOnError": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "noImplicitReturns": true, 11 | "noUnusedLocals": true, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "strict": true, 15 | "strictNullChecks": true, 16 | "target": "ES2020", 17 | "incremental": true, 18 | "strictPropertyInitialization": false, 19 | "skipLibCheck": true, 20 | "alwaysStrict": true, 21 | "moduleResolution": "node", 22 | "allowSyntheticDefaultImports": true, 23 | "emitDecoratorMetadata": true, 24 | "experimentalDecorators": true 25 | }, 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /examples/failure-strategy/src/create-process-instances.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC } from '@villedemontreal/workit-core'; 9 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 10 | 11 | (async (): Promise => { 12 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, TAG.camundaBpm); 13 | for (let index = 0; index < 1; index += 1) { 14 | await cm.createWorkflowInstance({ 15 | bpmnProcessId: 'BPMN_DEMO', 16 | variables: { 17 | amount: 1000, 18 | hello: 'world', 19 | }, 20 | }); 21 | } 22 | 23 | console.log('Success!'); 24 | })(); 25 | -------------------------------------------------------------------------------- /examples/parallel/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC, Worker } from '@villedemontreal/workit-core'; 9 | import { HelloWorldTask } from '../tasks/helloWorldTask'; 10 | 11 | enum LOCAL_IDENTIFIER { 12 | activity1 = 'activity_1', 13 | activity2 = 'activity_2', 14 | activity3 = 'activity_3', 15 | } 16 | 17 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity1); 18 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity2); 19 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity3); 20 | 21 | const worker = IoC.get(CORE_IDENTIFIER.worker, TAG.camundaBpm); 22 | 23 | worker.start(); 24 | worker.run(); 25 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/config/container.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { kernel } from '@villedemontreal/workit-core'; 8 | import { ICamundaConfig } from '@villedemontreal/workit-types'; 9 | import { SERVICE_IDENTIFIER } from './constants/identifiers'; 10 | 11 | const configBase: ICamundaConfig = { 12 | workerId: 'demo', 13 | baseUrl: `__undefined__`, 14 | topicName: 'topic_demo', 15 | }; 16 | 17 | const bpmnPlatformClientConfig = { 18 | ...configBase, 19 | baseUrl: process.env.CAMUNDA_BPM_ADDRESS || `http://localhost:8080/engine-rest`, 20 | maxTasks: 32, 21 | autoPoll: false, 22 | }; 23 | 24 | kernel.bind(SERVICE_IDENTIFIER.camunda_external_config).toConstantValue(bpmnPlatformClientConfig); 25 | -------------------------------------------------------------------------------- /packages/workit-core/tests/utils/fake.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { ICamundaService, IMessage } from '@villedemontreal/workit-types'; 8 | import { TaskBase } from '../../src/specs/taskBase'; 9 | 10 | export class FakeTask extends TaskBase { 11 | constructor() { 12 | super(); 13 | } 14 | public execute(model: IMessage): Promise { 15 | return Promise.resolve(model); 16 | } 17 | } 18 | 19 | export class FakeClient { 20 | public subscribe(onMessageReceived: (message: IMessage, service: ICamundaService) => Promise): Promise { 21 | return Promise.resolve(); 22 | } 23 | public unsubscribe(): Promise { 24 | return Promise.resolve(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/getWorkflowsResult.json: -------------------------------------------------------------------------------- 1 | { 2 | "paging": { 3 | "from": 0, 4 | "size": 500 5 | }, 6 | "items": [ 7 | { 8 | "bpmnProcessId": "BPMN_P_DEMO", 9 | "workflowKey": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 10 | "resourceName": "BPMN_P_DEMO.bpmn", 11 | "version": 1 12 | }, 13 | { 14 | "bpmnProcessId": "invoice", 15 | "workflowKey": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 16 | "resourceName": "invoice.v1.bpmn", 17 | "version": 1 18 | }, 19 | { 20 | "bpmnProcessId": "invoice", 21 | "workflowKey": "invoice:2:65434362-9ad1-11e9-8102-0242ac110002", 22 | "resourceName": "invoice.v2.bpmn", 23 | "version": 2 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/getWorkflowsResult.json: -------------------------------------------------------------------------------- 1 | { 2 | "paging": { 3 | "from": 0, 4 | "size": 500 5 | }, 6 | "items": [ 7 | { 8 | "bpmnProcessId": "BPMN_P_DEMO", 9 | "workflowKey": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 10 | "resourceName": "BPMN_P_DEMO.bpmn", 11 | "version": 1 12 | }, 13 | { 14 | "bpmnProcessId": "invoice", 15 | "workflowKey": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 16 | "resourceName": "invoice.v1.bpmn", 17 | "version": 1 18 | }, 19 | { 20 | "bpmnProcessId": "invoice", 21 | "workflowKey": "invoice:2:65434362-9ad1-11e9-8102-0242ac110002", 22 | "resourceName": "invoice.v2.bpmn", 23 | "version": 2 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/utils/fake.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { ICamundaService, IMessage } from '@villedemontreal/workit-types'; 9 | 10 | export class FakeTask extends TaskBase { 11 | constructor() { 12 | super(); 13 | } 14 | public execute(model: IMessage): Promise { 15 | return Promise.resolve(model); 16 | } 17 | } 18 | 19 | export class FakeClient { 20 | public subscribe(onMessageReceived: (message: IMessage, service: ICamundaService) => Promise): Promise { 21 | return Promise.resolve(); 22 | } 23 | public unsubscribe(): Promise { 24 | return Promise.resolve(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/utils/fake.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { ICamundaService, IMessage } from '@villedemontreal/workit-types'; 9 | 10 | export class FakeTask extends TaskBase { 11 | constructor() { 12 | super(); 13 | } 14 | public execute(model: IMessage): Promise { 15 | return Promise.resolve(model); 16 | } 17 | } 18 | 19 | export class FakeClient { 20 | public subscribe(onMessageReceived: (message: IMessage, service: ICamundaService) => Promise): Promise { 21 | return Promise.resolve(); 22 | } 23 | public unsubscribe(): Promise { 24 | return Promise.resolve(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export * from './camundaService'; 8 | export * from './createWorkflowInstance'; 9 | export * from './createWorkflowInstanceResponse'; 10 | export * from './deployWorkflowResponse'; 11 | export * from './failureException'; 12 | export * from './incidentException'; 13 | export * from './workflowProps'; 14 | export * from './workflowPropsBase'; 15 | export * from './publishMessage'; 16 | export * from './updateWorkflowRetry'; 17 | export * from './updateWorkflowVariables'; 18 | export * from './workflow'; 19 | export * from './workflowClient'; 20 | export * from './workflowDefinition'; 21 | export * from './workflowOptions'; 22 | export * from './workflowResponse'; 23 | -------------------------------------------------------------------------------- /examples/failure-strategy/tasks/helloWorldTask.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTask extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(`Executing task: ${properties.activityId}`); 16 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 17 | 18 | // should throw for the purpose of this example 19 | await axios.get('https://jsonplaceholder.typicode.com/fake/1'); 20 | 21 | return message; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/binding/tasks/helloWorldTaskV3.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | 10 | export class HelloWorldTaskV3 extends TaskBase { 11 | public execute(message: IMessage): Promise { 12 | const { properties } = message; 13 | // -------------------------- 14 | console.log(); 15 | console.log(`Executing task: ${properties.activityId} with the class HelloWorldTaskV3`); 16 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 17 | console.log(`version: ${properties.workflowDefinitionVersion}`); 18 | 19 | return Promise.resolve(message); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/workit-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "lib", 6 | "skipLibCheck": true, 7 | "declaration": true, 8 | "alwaysStrict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "typeRoots": ["./types", "./node_modules/@types", "../../node_modules/@types"], 11 | "types": ["node", "jest"], 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "moduleResolution": "node", 15 | "allowSyntheticDefaultImports": true, 16 | "noUnusedLocals": true, 17 | "pretty": true, 18 | "sourceMap": true, 19 | "strictNullChecks": true, 20 | "incremental": true, 21 | }, 22 | "exclude": [ 23 | "lib", 24 | "temp", 25 | "node_modules", 26 | "output", 27 | "log", 28 | "mocha", 29 | ".*", 30 | "tests" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/tests/scripts/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | localstack: 4 | container_name: local_sqs_aws 5 | image: localstack/localstack:3.0.1@sha256:de413eee81c94bfd9b2206c016b82e83a3b2b8abd5775d05dbf829be2b02afb4 6 | environment: 7 | - AWS_DEFAULT_REGION=eu-west-1 8 | - EDGE_PORT=4566 9 | - SERVICES=sqs 10 | - AWS_ACCESS_KEY_ID=key 11 | - AWS_SECRET_ACCESS_KEY=secret 12 | - DOCKER_HOST=unix:///var/run/docker.sock 13 | - DEBUG=1 14 | ports: 15 | - "4566-4599:4566-4599" 16 | volumes: 17 | - '/var/run/docker.sock:/var/run/docker.sock' 18 | - ./localstack:/etc/localstack/init/ready.d 19 | healthcheck: 20 | test: curl http://localhost:4566/_localstack/health | jq '.services.sqs' | grep -q -x 'running' 21 | interval: 20s 22 | retries: 5 23 | start_period: 20s 24 | timeout: 10s -------------------------------------------------------------------------------- /examples/binding/tasks/helloWorldTask.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTask extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(); 16 | console.log(`Executing task: ${properties.activityId}`); 17 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 18 | 19 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1'); 20 | 21 | console.log('\ndata:'); 22 | console.log(response.data); 23 | 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/opentelemetry/tasks/helloWorldTask.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTask extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(); 16 | console.log(`Executing task: ${properties.activityId}`); 17 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 18 | 19 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1'); 20 | 21 | console.log('\ndata:'); 22 | console.log(response.data); 23 | 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/basic/tasks/helloWorldTask.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTask extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(`Executing task: ${properties.activityId}`); 16 | console.log(properties); 17 | console.log(`${properties.bpmnProcessId}::${properties.workflowInstanceKey} Servus!`); 18 | 19 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1'); 20 | 21 | console.log('\ndata:'); 22 | console.log(response.data); 23 | 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/basic/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "rules": { 19 | ...require('../../eslint.rules.js'), 20 | "no-console": "off", 21 | "@typescript-eslint/no-floating-promises": "off", 22 | "@typescript-eslint/restrict-template-expressions": "off", 23 | "@typescript-eslint/no-unsafe-member-access": "off", 24 | "@typescript-eslint/no-unsafe-assignment": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/binding/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "rules": { 19 | ...require('../../eslint.rules.js'), 20 | "no-console": "off", 21 | "@typescript-eslint/no-floating-promises": "off", 22 | "@typescript-eslint/restrict-template-expressions": "off", 23 | "@typescript-eslint/no-unsafe-member-access": "off", 24 | "@typescript-eslint/no-unsafe-assignment": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/parallel/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "rules": { 19 | ...require('../../eslint.rules.js'), 20 | "no-console": "off", 21 | "@typescript-eslint/no-floating-promises": "off", 22 | "@typescript-eslint/restrict-template-expressions": "off", 23 | "@typescript-eslint/no-unsafe-member-access": "off", 24 | "@typescript-eslint/no-unsafe-assignment": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/opentelemetry/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "rules": { 19 | ...require('../../eslint.rules.js'), 20 | "no-console": "off", 21 | "@typescript-eslint/no-floating-promises": "off", 22 | "@typescript-eslint/restrict-template-expressions": "off", 23 | "@typescript-eslint/no-unsafe-member-access": "off", 24 | "@typescript-eslint/no-unsafe-assignment": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/failure-strategy/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "rules": { 19 | ...require('../../eslint.rules.js'), 20 | "no-console": "off", 21 | "@typescript-eslint/no-floating-promises": "off", 22 | "@typescript-eslint/restrict-template-expressions": "off", 23 | "@typescript-eslint/no-unsafe-member-access": "off", 24 | "@typescript-eslint/no-unsafe-assignment": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/workit/src/camundaBpm/camundaBpmWorker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Worker } from '@villedemontreal/workit-core'; 8 | import { ICamundaService, IClient, IProcessHandler } from '@villedemontreal/workit-types'; 9 | import { inject, injectable, named } from 'inversify'; 10 | import { Client } from '../camunda-n-mq/client'; 11 | import { SERVICE_IDENTIFIER } from '../config/constants/identifiers'; 12 | import { TAG } from '../config/constants/tag'; 13 | 14 | @injectable() 15 | export class CamundaBpmWorker extends Worker { 16 | constructor( 17 | @inject(SERVICE_IDENTIFIER.camunda_client) @named(TAG.camundaBpm) client: Client>, 18 | @inject(SERVICE_IDENTIFIER.process_handler) processHandler: IProcessHandler, 19 | ) { 20 | super(client, processHandler); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/payload.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IVariableObject { 8 | type: string; 9 | value: string; 10 | valueInfo: any; 11 | } 12 | export interface IVariable { 13 | [custom: string]: any; 14 | } 15 | export interface IVariablePayload { 16 | activityId: string; 17 | activityInstanceId: string; 18 | errorMessage: string | null; 19 | errorDetails: any; 20 | executionId: string; 21 | id: string; 22 | lockExpirationTime: string; 23 | processDefinitionId: string; 24 | processDefinitionKey: string; 25 | processInstanceId: string; 26 | retries: number | null; 27 | suspended: boolean; 28 | workerId: string; 29 | topicName: string; 30 | tenantId: string | null; 31 | variables: IVariable; 32 | priority: number; 33 | businessKey: string | null; 34 | } 35 | -------------------------------------------------------------------------------- /packages/workit/src/stepFunction/stepFunctionWorker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { Worker } from '@villedemontreal/workit-core'; 8 | import { ICamundaService, IClient, IProcessHandler } from '@villedemontreal/workit-types'; 9 | import { inject, injectable, named } from 'inversify'; 10 | import { Client } from '../camunda-n-mq/client'; 11 | import { SERVICE_IDENTIFIER } from '../config/constants/identifiers'; 12 | import { TAG } from '../config/constants/tag'; 13 | 14 | @injectable() 15 | export class StepFunctionWorker extends Worker { 16 | constructor( 17 | @inject(SERVICE_IDENTIFIER.camunda_client) @named(TAG.stepFunction) client: Client>, 18 | @inject(SERVICE_IDENTIFIER.process_handler) processHandler: IProcessHandler, 19 | ) { 20 | super(client, processHandler); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/workit-core/tests/units/node_modules/@villemontreal/plugin-simple-module/simple-module.js: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, "__esModule", { value: true }); 2 | exports.plugin = void 0; 3 | const basePlugin_1 = require('../../../../../lib/src/plugin/basePlugin'); 4 | 5 | // Simple test task class that mimics what a real task would look like 6 | class SimpleTestTask { 7 | constructor() {} 8 | 9 | async execute(message) { 10 | return message; 11 | } 12 | } 13 | 14 | class SimpleModulePlugin extends basePlugin_1.BasePlugin { 15 | constructor(name) { 16 | super(`@villemontreal/plugin-${name}`); 17 | this._name = name; 18 | } 19 | get moduleName() { 20 | return this._name; 21 | } 22 | bind() { 23 | this._ioc.bindTask(SimpleTestTask, 'test', { bpmnProcessId: 'simple-process' }); 24 | } 25 | unbind() { 26 | this._ioc.unbind('test'); 27 | } 28 | } 29 | exports.plugin = new SimpleModulePlugin('simple-module'); 30 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/jest.setup.js: -------------------------------------------------------------------------------- 1 | // Jest setup for memory management in Node.js 20 2 | // Force garbage collection after each test to prevent memory buildup 3 | 4 | // Increase heap size warnings threshold 5 | if (typeof global.gc === 'function') { 6 | afterEach(() => { 7 | // Force garbage collection if available 8 | global.gc(); 9 | }); 10 | } 11 | 12 | // Set Node.js specific options for better memory handling 13 | process.setMaxListeners(0); 14 | 15 | // Handle large payload tests by limiting memory usage 16 | beforeAll(() => { 17 | // Set environment variable to reduce payload size for tests if not already set 18 | if (!process.env.WORKIT_STEP_FUNCTION_MAX_PAYLOAD_LENGTH) { 19 | process.env.WORKIT_STEP_FUNCTION_MAX_PAYLOAD_LENGTH = '65536'; // 64KB instead of 256KB 20 | } 21 | }); 22 | 23 | // Clean up after all tests 24 | afterAll(() => { 25 | // Clean up any remaining resources 26 | if (typeof global.gc === 'function') { 27 | global.gc(); 28 | } 29 | }); -------------------------------------------------------------------------------- /examples/parallel/tasks/helloWorldTask.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTask extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(); 16 | console.log(`Executing task: ${properties.activityId}`); 17 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 18 | 19 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1'); 20 | 21 | console.log('\ndata:'); 22 | console.log(response.data); 23 | 24 | return { 25 | body: {}, 26 | properties, 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/config/constants/identifiers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER } from '@villedemontreal/workit-core'; 7 | 8 | export const SERVICE_IDENTIFIER = { 9 | ...CORE_IDENTIFIER, 10 | /** 11 | * Bind the Camunda repository 12 | */ 13 | camunda_repository: Symbol('camunda_repository'), 14 | /** 15 | * Bind the Step function repository 16 | */ 17 | stepfunction_repository: Symbol('stepfunction_repository'), 18 | /** 19 | * Bind the Generic client you want to use 20 | */ 21 | camunda_client: Symbol('camunda_client'), 22 | /** 23 | * Bind the SQS configuration 24 | */ 25 | sqs_config: Symbol('sqs_config'), 26 | /** 27 | * Bind your own step function configuration 28 | */ 29 | stepfunction_config: Symbol('stepfunction_config'), 30 | }; 31 | -------------------------------------------------------------------------------- /packages/workit/tests/utils/fake.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { ICamundaService, IMessage } from '@villedemontreal/workit-types'; 9 | import { Client } from '../../src/camunda-n-mq/client'; 10 | 11 | export class FakeTask extends TaskBase { 12 | constructor() { 13 | super(); 14 | } 15 | public execute(model: IMessage): Promise { 16 | return Promise.resolve(model); 17 | } 18 | } 19 | 20 | export class FakeClient extends Client { 21 | constructor() { 22 | super({}); 23 | } 24 | public subscribe(onMessageReceived: (message: IMessage, service: ICamundaService) => Promise): Promise { 25 | return Promise.resolve(); 26 | } 27 | public unsubscribe(): Promise { 28 | return Promise.resolve(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | !packages/workit-core/tests/units/node_modules 3 | lerna-debug.log 4 | packages/*/lib 5 | .idea 6 | # Add any directories, files, or patterns you don't want to be tracked by version control 7 | npm-debug.log 8 | typings 9 | .tags* 10 | 11 | # OS generated files 12 | .DS_Store 13 | 14 | .nyc_output/ 15 | 16 | ### Node ### 17 | # Logs 18 | logs 19 | *.log 20 | log 21 | *.log.* 22 | npm-debug.log* 23 | 24 | # Runtime data 25 | pids 26 | *.pid 27 | *.seed 28 | 29 | # Directory for instrumented libs generated by jscoverage/JSCover 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | coverage 34 | 35 | # Optional npm cache directory 36 | .npm 37 | 38 | # Optional REPL history 39 | .node_repl_history 40 | 41 | # Created by docker/run 42 | /.cache.tgz 43 | /docker/.cache.tgzs 44 | /Running 45 | 46 | # Artillery reports 47 | /bin/artillery*report.json 48 | 49 | #ignore transpile code 50 | lib 51 | 52 | #lerna 53 | .changelog 54 | 55 | # VsCode configs 56 | .vscode 57 | 58 | yarn.lock 59 | -------------------------------------------------------------------------------- /packages/workit/.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /packages/workit-core/.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /packages/workit-types/.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /packages/workit-bpm-client/.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /packages/workit/src/config/constants/identifiers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CAMUNDA_BPM_IDENTIFIER } from '@villedemontreal/workit-bpm-client'; 8 | import { SERVICE_IDENTIFIER as STEP_FUNCTION_IDENTIFIER } from '@villedemontreal/workit-stepfunction-client'; 9 | 10 | export const SERVICE_IDENTIFIER = { 11 | ...STEP_FUNCTION_IDENTIFIER, 12 | ...CAMUNDA_BPM_IDENTIFIER, 13 | /** 14 | * Bind the Generic Camunda client you want to use 15 | */ 16 | camunda_client: Symbol('camunda_client'), 17 | 18 | /** 19 | * Bind your own generic client [[Client]] 20 | */ 21 | client: Symbol('client'), 22 | /** 23 | * Bind your own client manager [[ClientManager]] 24 | */ 25 | client_manager: Symbol('client_manager'), 26 | /** 27 | * Bind your own config for Camunda system 28 | */ 29 | camunda_config: Symbol('camunda_config'), 30 | }; 31 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | rules: 4 | header-max-length: [1, 'always', 72] 5 | type-enum: 6 | - 2 7 | - always 8 | - - ci 9 | - feat 10 | - fix 11 | - docs 12 | - style 13 | - refactor 14 | - perf 15 | - test 16 | - revert 17 | - chore 18 | help: | 19 | **Possible types**: 20 | `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) 21 | `feat`: Adds a new feature. 22 | `fix`: Solves a bug. 23 | `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) 24 | `style`: Improves formatting, white-space. 25 | `refactor`: Rewrites code without feature, performance or bug changes. 26 | `perf`: Improves performance. 27 | `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) 28 | `revert`: Changes that reverting other changes 29 | `chore`: (updating grunt tasks etc; no production code change) -------------------------------------------------------------------------------- /examples/binding/tasks/helloWorldTaskV2.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { TaskBase } from '@villedemontreal/workit-core'; 8 | import { IMessage } from '@villedemontreal/workit-types'; 9 | import axios from 'axios'; 10 | 11 | export class HelloWorldTaskV2 extends TaskBase { 12 | public async execute(message: IMessage): Promise { 13 | const { properties } = message; 14 | 15 | console.log(); 16 | console.log(`Executing task: ${properties.activityId} with the class HelloWorldTaskV2`); 17 | console.log(`${properties.bpmnProcessId}::${properties.processInstanceId} Servus!`); 18 | console.log(`version: ${properties.workflowDefinitionVersion}`); 19 | 20 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1'); 21 | 22 | console.log(); 23 | console.log('data:'); 24 | console.log(response.data); 25 | 26 | return message; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /examples/binding/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /examples/parallel/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/workit/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /examples/opentelemetry/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/workit-core/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/workit-types/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /examples/failure-strategy/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/workit-bpm-client/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/src/config/container.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { kernel } from '@villedemontreal/workit-core'; 8 | import { IAwsConfig } from '@villedemontreal/workit-types'; 9 | import { SERVICE_IDENTIFIER } from './constants/identifiers'; 10 | 11 | const env = process.env; 12 | 13 | const configBase: IAwsConfig = { 14 | region: env.AWS_REGION || '', 15 | credentials: { 16 | accessKeyId: env.AWS_ACCESS_KEY_ID || '', 17 | secretAccessKey: env.AWS_SECRET_ACCESS_KEY || '', 18 | }, 19 | }; 20 | 21 | const config = { 22 | ...configBase, 23 | queueUrl: env.AWS_SQS_QUEUE_URL || '', 24 | // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/StepFunctions.html 25 | apiVersion: env.AWS_API_VERSION || env.AWS_STEP_FUNCTION_API_VERSION || '2016-11-23', 26 | waitTimeSeconds: Number(env.AWS_SQS_WAIT_TIME_SECONDS) || undefined, 27 | }; 28 | 29 | kernel.bind(SERVICE_IDENTIFIER.stepfunction_config).toConstantValue(config); 30 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Examples show how to use [Workit](https://villedemontreal.github.io/workit/) to create a simple Node.js application - e.g. a worker that executes a simple task. 4 | 5 | You can also combine different examples into one - e.g you want to use [OpenTelemetry](opentelemetry) and [Camunda Cloud](camunda-cloud). 6 | 7 | Have fun! 8 | 9 | ## Installation 10 | 11 | ```sh 12 | $ # inside a directory 13 | $ npm install 14 | ``` 15 | 16 | (Optional) Setup, we can switch to `TAG.camundaBpm` or `TAG.stepFunction` in order to use both plateform (some comments are added in examples when BPMN is available see [basic example](basic)). 17 | 18 | ## Run the Application 19 | 20 | ```sh 21 | $ # inside a directory 22 | 23 | $ # deploy a bpmn provided in the example 24 | $ npm deploy 25 | $ # create instance(s) 26 | $ npm create-instance 27 | $ # run worker 28 | $ npm worker 29 | ``` 30 | 31 | ## Useful links 32 | - For more information on OpenTelemetry, visit: 33 | - For more information on workit, visit: 34 | 35 | ## LICENSE 36 | 37 | MIT 38 | -------------------------------------------------------------------------------- /packages/workit-stepfunction-client/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Ville de Montreal 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 7 | subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ville de Montréal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/bpmnDeployResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { ILink } from './link'; 8 | 9 | export interface IBpmnDeployResponse { 10 | links: ILink[]; 11 | id: string; 12 | name: string; 13 | source: string; 14 | deploymentTime: string; 15 | tenantId?: string; 16 | deployedProcessDefinitions: IDeployedProcessDefinitions; 17 | deployedCaseDefinitions?: string; 18 | deployedDecisionDefinitions?: any; 19 | deployedDecisionRequirementsDefinitions?: any; 20 | } 21 | 22 | export interface IDeployedProcessDefinitions { 23 | [cusom: string]: IBpmn; 24 | } 25 | 26 | export interface IBpmn { 27 | id: string; 28 | key: string; 29 | category: string; 30 | description?: string; 31 | name: string; 32 | version: number; 33 | resource: string; 34 | deploymentId: string; 35 | diagram?: any; 36 | suspended: boolean; 37 | tenantId?: string; 38 | versionTag?: any; 39 | historyTimeToLive: number; 40 | startableInTasklist: boolean; 41 | } 42 | -------------------------------------------------------------------------------- /packages/workit-core/src/plugin/basePlugin.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IIoC, ILogger, IPlugin, IPluginConfig } from '@villedemontreal/workit-types'; 8 | 9 | // TODO: add bpmn files and failures/success strategies as well 10 | 11 | export abstract class BasePlugin implements IPlugin { 12 | public supportedVersions?: string[]; 13 | 14 | public abstract readonly moduleName: string; 15 | 16 | public readonly version?: string; 17 | 18 | protected _ioc!: IIoC; 19 | 20 | protected _logger!: ILogger; 21 | 22 | protected _config!: IPluginConfig; 23 | 24 | constructor(protected readonly packageName: string) {} 25 | 26 | public enable(ioc: IIoC, logger: ILogger, config?: IPluginConfig): void { 27 | this._ioc = ioc; 28 | this._logger = logger; 29 | if (config) this._config = config; 30 | this.bind(); 31 | } 32 | 33 | public disable(): void { 34 | this.unbind(); 35 | } 36 | 37 | protected abstract bind(): void; 38 | 39 | protected abstract unbind(): void; 40 | } 41 | -------------------------------------------------------------------------------- /examples/basic/workflow/stepfunctions/WORKFLOW_DEMO.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment": "A description of my state machine", 3 | "StartAt": "Activity", 4 | "States": { 5 | "Activity": { 6 | "Type": "Task", 7 | "Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken", 8 | "Parameters": { 9 | "MessageBody": { 10 | "body.$": "$", 11 | "properties": { 12 | "activityId": "sample_activity", 13 | "retries.$": "$$.State.RetryCount", 14 | "bpmnProcessId.$": "$$.StateMachine.Id", 15 | "jobKey.$": "$$.Task.Token", 16 | "workflowInstanceKey.$": "$$.Execution.Id" 17 | } 18 | }, 19 | "QueueUrl": "" 20 | }, 21 | "End": true, 22 | "Retry": [ 23 | { 24 | "ErrorEquals": [ 25 | "States.ALL" 26 | ], 27 | "BackoffRate": 2, 28 | "IntervalSeconds": 1, 29 | "MaxAttempts": 5, 30 | "Comment": "Basic Retrier" 31 | } 32 | ], 33 | "HeartbeatSeconds": 30, 34 | "TimeoutSeconds": 200 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /examples/plugin-metrics/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "@typescript-eslint", 4 | "header" 5 | ], 6 | "extends": [ 7 | "airbnb-typescript/base", 8 | "plugin:@typescript-eslint/eslint-recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "plugin:import/recommended" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "project": "./tsconfig.json" 17 | }, 18 | "ignorePatterns": ["lib/**", "__tests__/**", "*.js"], 19 | "rules": { 20 | ...require('../../eslint.rules.js'), 21 | "no-console": "off", 22 | "@typescript-eslint/no-floating-promises": "off", 23 | "@typescript-eslint/restrict-template-expressions": "off", 24 | "@typescript-eslint/no-unsafe-member-access": "off", 25 | "@typescript-eslint/no-unsafe-assignment": "off", 26 | "@typescript-eslint/no-unsafe-argument": "off", 27 | "@typescript-eslint/no-unsafe-call": "off", 28 | "@typescript-eslint/no-unsafe-return": "off" 29 | } 30 | } -------------------------------------------------------------------------------- /examples/failure-strategy/workflow/stepfunctions/WORKFLOW_DEMO.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment": "A description of my state machine", 3 | "StartAt": "Activity", 4 | "States": { 5 | "Activity": { 6 | "Type": "Task", 7 | "Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken", 8 | "Parameters": { 9 | "MessageBody": { 10 | "body.$": "$", 11 | "properties": { 12 | "activityId": "sample_activity", 13 | "retries.$": "$$.State.RetryCount", 14 | "bpmnProcessId.$": "$$.StateMachine.Id", 15 | "jobKey.$": "$$.Task.Token", 16 | "workflowInstanceKey.$": "$$.Execution.Id" 17 | } 18 | }, 19 | "QueueUrl": "" 20 | }, 21 | "End": true, 22 | "Retry": [ 23 | { 24 | "ErrorEquals": [ 25 | "States.ALL" 26 | ], 27 | "BackoffRate": 2, 28 | "IntervalSeconds": 1, 29 | "MaxAttempts": 5, 30 | "Comment": "Basic Retrier" 31 | } 32 | ], 33 | "HeartbeatSeconds": 30, 34 | "TimeoutSeconds": 200 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /packages/workit-types/src/plugin/plugin.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { IIoC } from '../core/ioc'; 7 | import { ILogger } from '../commons/logger'; 8 | import { IPluginConfig } from './pluginConfig'; 9 | 10 | export interface IPlugin { 11 | /** 12 | * Contains all supported versions. 13 | * All versions must be compatible with [semver](https://semver.org/spec/v2.0.0.html) format. 14 | * If the version is not supported, we won't apply tasks (see `enable` method). 15 | * If omitted, all versions of the module will be used. 16 | * NOT IMPLEMENTED YET 17 | */ 18 | supportedVersions?: string[]; 19 | 20 | /** 21 | * Name of the module. 22 | */ 23 | moduleName: string; 24 | 25 | /** 26 | * Method that enables the tasks. 27 | * @param ioc ioc that let you bind tasks among other objects 28 | * @param logger a logger instance. 29 | * @param [config] an object to configure the plugin. 30 | */ 31 | enable(ioc: IIoC, logger: ILogger, config?: IPluginConfig): void; 32 | 33 | /** Method to disable the tasks */ 34 | disable(): void; 35 | } 36 | -------------------------------------------------------------------------------- /packages/workit/tests/data/camundaResponsePaginated.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 4 | "key": "BPMN_P_DEMO", 5 | "category": "http://bpmn.io/schema/bpmn", 6 | "description": null, 7 | "name": "Parallel workflow", 8 | "version": 1, 9 | "resource": "BPMN_P_DEMO.bpmn", 10 | "deploymentId": "eb53a68d-7769-11e9-84ff-0242ac110002", 11 | "diagram": null, 12 | "suspended": false, 13 | "tenantId": null, 14 | "versionTag": null, 15 | "historyTimeToLive": null, 16 | "startableInTasklist": true 17 | }, 18 | { 19 | "id": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 20 | "key": "invoice", 21 | "category": "http://www.omg.org/spec/BPMN/20100524/MODEL", 22 | "description": null, 23 | "name": "Invoice Receipt", 24 | "version": 1, 25 | "resource": "invoice.v1.bpmn", 26 | "deploymentId": "64a46b44-9ad1-11e9-8102-0242ac110002", 27 | "diagram": null, 28 | "suspended": false, 29 | "tenantId": null, 30 | "versionTag": "V1.0", 31 | "historyTimeToLive": 30, 32 | "startableInTasklist": true 33 | } 34 | ] -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/data/camundaResponsePaginated.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 4 | "key": "BPMN_P_DEMO", 5 | "category": "http://bpmn.io/schema/bpmn", 6 | "description": null, 7 | "name": "Parallel workflow", 8 | "version": 1, 9 | "resource": "BPMN_P_DEMO.bpmn", 10 | "deploymentId": "eb53a68d-7769-11e9-84ff-0242ac110002", 11 | "diagram": null, 12 | "suspended": false, 13 | "tenantId": null, 14 | "versionTag": null, 15 | "historyTimeToLive": null, 16 | "startableInTasklist": true 17 | }, 18 | { 19 | "id": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 20 | "key": "invoice", 21 | "category": "http://www.omg.org/spec/BPMN/20100524/MODEL", 22 | "description": null, 23 | "name": "Invoice Receipt", 24 | "version": 1, 25 | "resource": "invoice.v1.bpmn", 26 | "deploymentId": "64a46b44-9ad1-11e9-8102-0242ac110002", 27 | "diagram": null, 28 | "suspended": false, 29 | "tenantId": null, 30 | "versionTag": "V1.0", 31 | "historyTimeToLive": 30, 32 | "startableInTasklist": true 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowDefinition.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface IWorkflowDefinition extends IWorkflowProcessIdDefinition, IWorkflowDefinitionKey { 8 | version: number; 9 | resourceName: string; 10 | bpmnXml: string; 11 | } 12 | 13 | export type IWorkflowDefinitionRequest = IWorkflowProcessIdDefinition | IWorkflowDefinitionKey; 14 | 15 | export interface IWorkflowProcessIdDefinition { 16 | /** 17 | * Warning: Camunda BPM platform is not compatible with "version" property due to API restriction, 18 | * please use workflowKey. Because workflowKey includes "version" in Camunda BPM plateform 19 | */ 20 | version?: number; 21 | 22 | /** 23 | * See your BPMN process id on your BPMN file 24 | * 25 | * Example: 26 | * - CamundaBPM: "DEMO" not compatible with version property due to API restriction, please use workflowKey 27 | */ 28 | bpmnProcessId: string; 29 | } 30 | 31 | export interface IWorkflowDefinitionKey { 32 | /** 33 | * Example: 34 | * - CamundaBPM: "DEMO:2:weqw-qweweqw-fhdjfh-sjjss" 35 | */ 36 | workflowKey: string; 37 | } 38 | -------------------------------------------------------------------------------- /packages/workit-core/src/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export const isFunction = (f: any) => typeof f === 'function'; 8 | export const isObject = (o: any) => typeof o === 'object'; 9 | /** 10 | * Applied test function on each element on the array and ANDs the results 11 | */ 12 | export const andArrayWith = (arr: T[], test: (param: T) => boolean) => 13 | arr.reduce((bool, current) => bool && test(current), true); 14 | /** 15 | * Checks if parameter is an array of functions 16 | */ 17 | export const isArrayOfFunctions = (a: any): boolean => Array.isArray(a) && a.length > 0 && andArrayWith(a, isFunction); 18 | export const isEmptyArray = (a: any): boolean => Array.isArray(a) && a.length === 0; 19 | 20 | export function parseCommaSeparatedBaggage(baggage: any, values: string): void { 21 | values.split(',').forEach((keyVal) => { 22 | const splitKeyVal: string[] = keyVal.trim().split('='); 23 | if (splitKeyVal.length === 2) { 24 | const [key, val] = splitKeyVal; 25 | // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-unsafe-member-access 26 | baggage[key] = val; 27 | } 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /examples/failure-strategy/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC, Worker } from '@villedemontreal/workit-core'; 9 | import { HelloWorldTask } from '../tasks/helloWorldTask'; 10 | import { AxiosNotFoundHandler, FailureStrategySimple } from './failure-strategy'; 11 | 12 | enum LOCAL_IDENTIFIER { 13 | sampleActivity = 'sample_activity', 14 | } 15 | 16 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.sampleActivity); 17 | IoC.bindToObject(new FailureStrategySimple([new AxiosNotFoundHandler()]), CORE_IDENTIFIER.failure_strategy); 18 | 19 | const worker = IoC.get(CORE_IDENTIFIER.worker, TAG.camundaBpm); 20 | 21 | const stop = () => { 22 | console.info('SIGTERM signal received.'); 23 | console.log('Closing worker'); 24 | worker 25 | .stop() 26 | .then(() => { 27 | console.log('worker closed'); 28 | process.exit(0); 29 | }) 30 | .catch((e: Error) => { 31 | console.log(e); 32 | process.exit(1); 33 | }); 34 | }; 35 | 36 | worker.start(); 37 | worker.run(); 38 | 39 | process.on('SIGINT', stop); 40 | process.on('SIGTERM', stop); 41 | -------------------------------------------------------------------------------- /examples/basic/src/create-process-instances.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | // you can pass value here or an another (safer) way 8 | // process.env.AWS_REGION = 'us-east-1'; 9 | // process.env.AWS_ACCESS_KEY_ID = ''; 10 | // process.env.AWS_SECRET_ACCESS_KEY = ''; 11 | // process.env.AWS_SQS_WAIT_TIME_SECONDS = '20'; 12 | 13 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 14 | import { IoC } from '@villedemontreal/workit-core'; 15 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 16 | 17 | (async (): Promise => { 18 | const platform = TAG.stepFunction; 19 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, platform); 20 | for (let index = 0; index < 1; index += 1) { 21 | await cm.createWorkflowInstance({ 22 | bpmnProcessId: 23 | platform === TAG.camundaBpm 24 | ? 'BPMN_DEMO' 25 | : `arn:aws:states:${process.env.AWS_REGION}::stateMachine:Basic-Example`, 26 | variables: { 27 | amount: 1000, 28 | hello: 'world', 29 | }, 30 | }); 31 | } 32 | 33 | console.info('Success!'); 34 | })(); 35 | -------------------------------------------------------------------------------- /examples/basic/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | // process.env.AWS_REGION = 'us-east-1'; 7 | // process.env.AWS_ACCESS_KEY_ID = ''; 8 | // process.env.AWS_SECRET_ACCESS_KEY = ''; 9 | // process.env.AWS_SQS_WAIT_TIME_SECONDS = '20'; 10 | 11 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 12 | import { IoC, Worker } from '@villedemontreal/workit-core'; 13 | import { HelloWorldTask } from '../tasks/helloWorldTask'; 14 | 15 | enum LOCAL_IDENTIFIER { 16 | sampleActivity = 'sample_activity', 17 | } 18 | 19 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.sampleActivity); 20 | const worker = IoC.get(CORE_IDENTIFIER.worker, TAG.camundaBpm); 21 | 22 | const stop = (): void => { 23 | console.info('SIGTERM signal received.'); 24 | console.log('Closing worker'); 25 | worker 26 | .stop() 27 | .then(() => { 28 | console.log('worker closed'); 29 | process.exit(0); 30 | }) 31 | .catch((e: Error) => { 32 | console.log(e); 33 | process.exit(1); 34 | }); 35 | }; 36 | 37 | worker.start(); 38 | worker.run(); 39 | 40 | process.on('SIGINT', stop); 41 | process.on('SIGTERM', stop); 42 | -------------------------------------------------------------------------------- /packages/workit-types/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export * from './commons/customHeaders'; 8 | export * from './commons/pagination'; 9 | export * from './commons/paginationOptions'; 10 | export * from './commons/paging'; 11 | export * from './commons/logLevel'; 12 | export * from './commons/logger'; 13 | 14 | // ProcessHandler 15 | export * from './process/process'; 16 | export * from './process/processHandler'; 17 | export * from './process/processHandlerConfig'; 18 | 19 | // Utils 20 | export * from './utils/validation'; 21 | 22 | // Core 23 | export * from './core/interceptor'; 24 | export * from './core/message'; 25 | export * from './core/client'; 26 | export * from './core/successStrategy'; 27 | export * from './core/failureStrategy'; 28 | export * from './core/camunda'; 29 | export * from './core/ioc'; 30 | 31 | // Task 32 | export * from './tasks/task'; 33 | 34 | // Plugin 35 | export * from './plugin'; 36 | 37 | // Tracer 38 | export * from './tracer/tracerPropagator'; 39 | 40 | // Http 41 | export * from './http/headers'; 42 | export * from './http/httpOptions'; 43 | export * from './http/httpResponse'; 44 | 45 | // Clients 46 | export * from './camundaBpm'; 47 | export * from './aws'; 48 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__mocks__/deployResponse.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": [ 3 | { 4 | "method": "GET", 5 | "href": "http://localhost:8080/engine-rest/deployment/8e5e6b98-53fb-11e9-8953-0242ac110002", 6 | "rel": "self" 7 | } 8 | ], 9 | "id": "8e5e6b98-53fb-11e9-8953-0242ac110002", 10 | "name": "Deploy from demo", 11 | "source": null, 12 | "deploymentTime": "2019-03-31T21:25:50.196+0000", 13 | "tenantId": null, 14 | "deployedProcessDefinitions": { 15 | "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002": { 16 | "id": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 17 | "key": "message-event", 18 | "category": "http://bpmn.io/schema/bpmn", 19 | "description": null, 20 | "name": "Message event", 21 | "version": 5, 22 | "resource": "MESSAGE_EVENT.bpmn", 23 | "deploymentId": "8e5e6b98-53fb-11e9-8953-0242ac110002", 24 | "diagram": null, 25 | "suspended": false, 26 | "tenantId": null, 27 | "versionTag": null, 28 | "historyTimeToLive": null, 29 | "startableInTasklist": true 30 | } 31 | }, 32 | "deployedCaseDefinitions": null, 33 | "deployedDecisionDefinitions": null, 34 | "deployedDecisionRequirementsDefinitions": null 35 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__mocks__/deployResponse.camunda.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": [ 3 | { 4 | "method": "GET", 5 | "href": "http://localhost:8080/engine-rest/deployment/8e5e6b98-53fb-11e9-8953-0242ac110002", 6 | "rel": "self" 7 | } 8 | ], 9 | "id": "8e5e6b98-53fb-11e9-8953-0242ac110002", 10 | "name": "Deploy from demo", 11 | "source": null, 12 | "deploymentTime": "2019-03-31T21:25:50.196+0000", 13 | "tenantId": null, 14 | "deployedProcessDefinitions": { 15 | "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002": { 16 | "id": "message-event:5:8e65496a-53fb-11e9-8953-0242ac110002", 17 | "key": "message-event", 18 | "category": "http://bpmn.io/schema/bpmn", 19 | "description": null, 20 | "name": "Message event", 21 | "version": 5, 22 | "resource": "MESSAGE_EVENT.bpmn", 23 | "deploymentId": "8e5e6b98-53fb-11e9-8953-0242ac110002", 24 | "diagram": null, 25 | "suspended": false, 26 | "tenantId": null, 27 | "versionTag": null, 28 | "historyTimeToLive": null, 29 | "startableInTasklist": true 30 | } 31 | }, 32 | "deployedCaseDefinitions": null, 33 | "deployedDecisionDefinitions": null, 34 | "deployedDecisionRequirementsDefinitions": null 35 | } -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/config/constants/identifiers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER } from '@villedemontreal/workit-core'; 7 | 8 | export const SERVICE_IDENTIFIER = { 9 | ...CORE_IDENTIFIER, 10 | /** 11 | * Bind auth info for your Camunda server 12 | * Check tests for more info 13 | */ 14 | camunda_oauth_info: Symbol('camunda_oauth'), 15 | /** 16 | * Bind the Camunda repository that standard REST API 17 | */ 18 | camunda_repository: Symbol('camunda_repository'), 19 | /** 20 | * Bind the Camunda service that use the camunda_repository service identifier 21 | */ 22 | camunda_service: Symbol('camunda_service'), 23 | /** 24 | * Bind the Generic Camunda client you want to use 25 | */ 26 | camunda_client: Symbol('camunda_client'), 27 | /** 28 | * Bind the Camunda BPMN Workflow Engine client you want to use (for external tasks) 29 | */ 30 | camunda_external_client: Symbol('camunda_external_client'), 31 | /** 32 | * Bind the Camunda BPMN Workflow Engine configuration 33 | */ 34 | camunda_external_config: Symbol('camunda_external_config'), 35 | /** 36 | * Bind your own config for Camunda system 37 | */ 38 | camunda_config: Symbol('camunda_config'), 39 | }; 40 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/units/camundaMessage.spec.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2019 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { CamundaMessage } from '../../src/camundaMessage'; 8 | 9 | describe('Camunda Message', () => { 10 | describe('Unwrap', () => { 11 | it('unwrap body message', () => { 12 | const cDate = new Date(); 13 | const message = { 14 | body: { a: 1, b: true, c: cDate, d: { d1: new Date() }, e: [] }, 15 | properties: { customHeaders: {} } as any, 16 | }; 17 | const variables = CamundaMessage.unwrap(message); 18 | const data: any = variables.getAll(); 19 | 20 | expect(data.a).toStrictEqual(1); 21 | expect(data.b).toBeTruthy(); 22 | expect((data.c as Date).toUTCString()).toStrictEqual(cDate.toUTCString()); 23 | expect(typeof data.d).toStrictEqual('object'); 24 | expect(data._meta).toBeUndefined(); 25 | }); 26 | 27 | it('should unwrap customHeaders in properties message to _meta field in variable object', () => { 28 | const message = { body: {}, properties: { customHeaders: { a: 1 } } as any }; 29 | const variables = CamundaMessage.unwrap(message); 30 | const data: any = variables.getAll(); 31 | 32 | expect(data._meta.customHeaders.a).toStrictEqual(1); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/ioc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export interface IIoC { 7 | bindToObject(obj: T, serviceIdentifier: symbol | string, named?: string): void; 8 | unbind(name: string | symbol): boolean; 9 | bindTo( 10 | ctor: new (...args: any[]) => T, 11 | serviceIdentifier: string | symbol, 12 | dependencies?: (symbol | string)[], 13 | named?: string | symbol | null, 14 | singletonMode?: boolean, 15 | ): void; 16 | bind( 17 | serviceIdentifier: string, 18 | ctor: new (...args: any[]) => T, 19 | targetNamed: string, 20 | singletonMode?: boolean, 21 | ): void; 22 | get(serviceIdentifier: symbol | string, named?: string | symbol): T; 23 | /** 24 | * Useful for getting task instance for a specific workflow. 25 | * It can check if there is a task for a specific workflow version or it will rollback to the serviceIdentifier if nothing is boundNamed. 26 | * Otherwise it will throw an error 27 | */ 28 | getTask(serviceIdentifier: symbol | string, workflow?: { bpmnProcessId: string; version: number }): T; 29 | 30 | bindTask( 31 | ctor: any, 32 | serviceIdentifier: string | symbol, 33 | workflow: { bpmnProcessId: string; version?: number }, 34 | dependencies?: (symbol | string)[], 35 | singletonMode?: boolean, 36 | ): void; 37 | } 38 | -------------------------------------------------------------------------------- /packages/workit-core/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IClient, IProcess, IProcessHandler } from '@villedemontreal/workit-types'; 8 | import { EventEmitter } from 'events'; 9 | import { injectable, unmanaged } from 'inversify'; 10 | import 'reflect-metadata'; 11 | 12 | import debug = require('debug'); 13 | 14 | const log = debug('workit:worker'); 15 | 16 | @injectable() 17 | export class Worker extends EventEmitter implements IProcess { 18 | protected readonly _processHandler: IProcessHandler; 19 | 20 | protected readonly _client: IClient; 21 | 22 | constructor(@unmanaged() client: IClient, @unmanaged() processHandler: IProcessHandler) { 23 | super(); 24 | this._client = client; 25 | this._processHandler = processHandler; 26 | } 27 | 28 | public start(): void { 29 | log('starting worker'); 30 | this.emit('starting'); 31 | log('started worker'); 32 | } 33 | 34 | public run(): Promise { 35 | log('running worker'); 36 | // eslint-disable-next-line @typescript-eslint/unbound-method 37 | return this._client.subscribe(this._processHandler.handle); 38 | } 39 | 40 | public async stop(): Promise { 41 | this.emit('stopping'); 42 | await this._client.unsubscribe(); 43 | this.emit('stopped'); 44 | } 45 | 46 | public getProcessHandler(): IProcessHandler { 47 | return this._processHandler; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/basic/src/deploy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | // you can pass value here or an another (safer) way 8 | // process.env.AWS_REGION = 'us-east-1'; 9 | // process.env.AWS_ACCESS_KEY_ID = ''; 10 | // process.env.AWS_SECRET_ACCESS_KEY = ''; 11 | // process.env.AWS_SQS_WAIT_TIME_SECONDS = '20'; 12 | 13 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 14 | import { IoC } from '@villedemontreal/workit-core'; 15 | import { IWorkflowClient } from '@villedemontreal/workit-types'; 16 | 17 | (async (): Promise => { 18 | const platform = TAG.camundaBpm; 19 | const cm = IoC.get(CORE_IDENTIFIER.client_manager, platform); 20 | const path = 21 | platform === TAG.camundaBpm 22 | ? `${process.cwd()}/workflow/camunda/BPMN_DEMO.bpmn` 23 | : `${process.cwd()}/workflow/stepfunction/WORKFLOW_DEMO.json`; 24 | const result = 25 | platform === TAG.camundaBpm 26 | ? await cm.deployWorkflow(path) 27 | : await cm.deployWorkflow(path, { 28 | name: 'Basic-Example', 29 | roleArn: 'arn:aws:iam:::role/service-role/', 30 | }); 31 | console.info('Success!'); 32 | console.warn( 33 | `Please, provide the following value "${result.workflows[0].bpmnProcessId}" to bpmnProcessId variable in create-process-instances.ts file for creating an instance`, 34 | ); 35 | })(); 36 | -------------------------------------------------------------------------------- /packages/workit-core/src/config/constants/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export class Constants { 7 | private static _instance: Readonly; 8 | 9 | private _envs: { dev: string; accept: string; prod: string }; 10 | 11 | private constructor() { 12 | this._envs = { 13 | // ========================================== 14 | // "development" seems to be the standard Node label, not "dev". 15 | // The node-config library uses this : 16 | // https://github.com/lorenwest/node-config/wiki/Configuration-Files#default-node_env 17 | // ========================================== 18 | dev: 'development', 19 | accept: 'acceptation', 20 | // ========================================== 21 | // "production" seems to be the standard Node label, not "prod". 22 | // ========================================== 23 | prod: 'production', 24 | }; 25 | } 26 | 27 | /** 28 | * Singleton 29 | * @readonly 30 | * @static 31 | * @type {Constants} 32 | * @memberof Constants 33 | */ 34 | public static get instance(): Readonly { 35 | if (!this._instance) { 36 | this._instance = Object.freeze(new Constants()); 37 | } 38 | return this._instance; 39 | } 40 | 41 | /** 42 | * Known environment types 43 | * @readonly 44 | * @memberof Constants 45 | */ 46 | public get envs() { 47 | return this._envs; 48 | } 49 | } 50 | 51 | export const constants: Readonly = Constants.instance; 52 | -------------------------------------------------------------------------------- /packages/workit/src/config/constants/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | export class Constants { 7 | private static _instance: Readonly; 8 | 9 | private _envs: { dev: string; accept: string; prod: string }; 10 | 11 | private constructor() { 12 | this._envs = { 13 | // ========================================== 14 | // "development" seems to be the standard Node label, not "dev". 15 | // The node-config library uses this : 16 | // https://github.com/lorenwest/node-config/wiki/Configuration-Files#default-node_env 17 | // ========================================== 18 | dev: 'development', 19 | accept: 'acceptation', 20 | // ========================================== 21 | // "production" seems to be the standard Node label, not "prod". 22 | // ========================================== 23 | prod: 'production', 24 | }; 25 | } 26 | 27 | /** 28 | * Singleton 29 | * @readonly 30 | * @static 31 | * @type {Constants} 32 | * @memberof Constants 33 | */ 34 | public static get instance(): Readonly { 35 | if (!this._instance) { 36 | this._instance = Object.freeze(new Constants()); 37 | } 38 | return this._instance; 39 | } 40 | 41 | /** 42 | * Known environment types 43 | * @readonly 44 | * @memberof Constants 45 | */ 46 | public get envs(): { dev: string; accept: string; prod: string } { 47 | return this._envs; 48 | } 49 | } 50 | 51 | export const constants: Readonly = Constants.instance; 52 | -------------------------------------------------------------------------------- /packages/workit/tests/functionals/__snapshots__/camundaManager.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result 1`] = ` 4 | { 5 | "items": [ 6 | { 7 | "bpmnProcessId": "BPMN_P_DEMO", 8 | "resourceName": "BPMN_P_DEMO.bpmn", 9 | "version": 1, 10 | "workflowKey": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 11 | }, 12 | { 13 | "bpmnProcessId": "invoice", 14 | "resourceName": "invoice.v1.bpmn", 15 | "version": 1, 16 | "workflowKey": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 17 | }, 18 | ], 19 | "paging": { 20 | "from": 0, 21 | "size": 2, 22 | "totalCount": 3, 23 | }, 24 | } 25 | `; 26 | 27 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result and searching a specific workflow 1`] = ` 28 | { 29 | "items": [ 30 | { 31 | "bpmnProcessId": "message-event", 32 | "resourceName": "MESSAGE_EVENT.bpmn", 33 | "version": 1, 34 | "workflowKey": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 35 | }, 36 | ], 37 | "paging": { 38 | "from": 0, 39 | "size": 2, 40 | "totalCount": 1, 41 | }, 42 | } 43 | `; 44 | 45 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result and skipping 2 workflows 1`] = ` 46 | { 47 | "items": [ 48 | { 49 | "bpmnProcessId": "message-event", 50 | "resourceName": "MESSAGE_EVENT.bpmn", 51 | "version": 1, 52 | "workflowKey": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 53 | }, 54 | ], 55 | "paging": { 56 | "from": 3, 57 | "size": 2, 58 | "totalCount": 4, 59 | }, 60 | } 61 | `; 62 | -------------------------------------------------------------------------------- /examples/binding/src/worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { SERVICE_IDENTIFIER as CORE_IDENTIFIER, TAG } from '@villedemontreal/workit'; 8 | import { IoC, Worker } from '@villedemontreal/workit-core'; 9 | import { HelloWorldTask } from '../tasks/helloWorldTask'; 10 | import { HelloWorldTaskV2 } from '../tasks/helloWorldTaskV2'; 11 | import { HelloWorldTaskV3 } from '../tasks/helloWorldTaskV3'; 12 | 13 | enum LOCAL_IDENTIFIER { 14 | activity1 = 'activity_1', 15 | activity2 = 'activity_2', 16 | activity3 = 'activity_3', 17 | } 18 | 19 | const BPMN_PROCESS_ID = 'BPMN_P_DEMO'; 20 | 21 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity1); 22 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity2); 23 | IoC.bindTo(HelloWorldTask, LOCAL_IDENTIFIER.activity3); 24 | 25 | IoC.bindTask(HelloWorldTaskV2, LOCAL_IDENTIFIER.activity1, { bpmnProcessId: BPMN_PROCESS_ID, version: 2 }); 26 | IoC.bindTask(HelloWorldTaskV2, LOCAL_IDENTIFIER.activity2, { bpmnProcessId: BPMN_PROCESS_ID, version: 2 }); 27 | IoC.bindTask(HelloWorldTaskV2, LOCAL_IDENTIFIER.activity3, { bpmnProcessId: BPMN_PROCESS_ID, version: 2 }); 28 | 29 | IoC.bindTask(HelloWorldTaskV3, LOCAL_IDENTIFIER.activity1, { bpmnProcessId: BPMN_PROCESS_ID, version: 3 }); 30 | IoC.bindTask(HelloWorldTaskV3, LOCAL_IDENTIFIER.activity2, { bpmnProcessId: BPMN_PROCESS_ID, version: 3 }); 31 | IoC.bindTask(HelloWorldTaskV3, LOCAL_IDENTIFIER.activity3, { bpmnProcessId: BPMN_PROCESS_ID, version: 3 }); 32 | 33 | const worker = IoC.get(CORE_IDENTIFIER.worker, TAG.camundaBpm); 34 | 35 | worker.start(); 36 | worker.run(); 37 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/src/utils/paginationUtils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | /* eslint @typescript-eslint/no-redundant-type-constituents: 0 */ 7 | 8 | import { IPaginationOptions, IPaging, IWorkflowOptions } from '@villedemontreal/workit-types'; 9 | 10 | export class PaginationUtils { 11 | public static setCamundaBpmPaginationParams( 12 | params: T, 13 | options?: Partial, 14 | ) { 15 | if (!options) { 16 | return params; 17 | } 18 | // make no sens to set size to 0 19 | return { ...params, firstResult: options.from, maxResults: options.size || PaginationUtils._DEFAULT_SIZE_ITEMS }; 20 | } 21 | 22 | public static getPagingFromOptions(totalCount: number, options?: (any & IPaginationOptions) | undefined): IPaging { 23 | // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-from-size.html 24 | if (!options) { 25 | return { 26 | from: 0, 27 | size: PaginationUtils._DEFAULT_SIZE_ITEMS, 28 | totalCount, 29 | }; 30 | } 31 | return { 32 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment 33 | from: typeof options.from === 'number' ? options.from : 0, 34 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment 35 | size: options.size || PaginationUtils._DEFAULT_SIZE_ITEMS, 36 | totalCount, 37 | }; 38 | } 39 | 40 | private static _DEFAULT_SIZE_ITEMS = 500; 41 | } 42 | -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/functionals/__snapshots__/camundaManager.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result 1`] = ` 4 | { 5 | "items": [ 6 | { 7 | "bpmnProcessId": "BPMN_P_DEMO", 8 | "resourceName": "BPMN_P_DEMO.bpmn", 9 | "version": 1, 10 | "workflowKey": "BPMN_P_DEMO:1:eb55f07f-7769-11e9-84ff-0242ac110002", 11 | }, 12 | { 13 | "bpmnProcessId": "invoice", 14 | "resourceName": "invoice.v1.bpmn", 15 | "version": 1, 16 | "workflowKey": "invoice:1:64beaa08-9ad1-11e9-8102-0242ac110002", 17 | }, 18 | ], 19 | "paging": { 20 | "from": 0, 21 | "size": 2, 22 | "totalCount": 3, 23 | }, 24 | } 25 | `; 26 | 27 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result and searching a specific workflow 1`] = ` 28 | { 29 | "items": [ 30 | { 31 | "bpmnProcessId": "message-event", 32 | "resourceName": "MESSAGE_EVENT.bpmn", 33 | "version": 1, 34 | "workflowKey": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 35 | }, 36 | ], 37 | "paging": { 38 | "from": 0, 39 | "size": 2, 40 | "totalCount": 1, 41 | }, 42 | } 43 | `; 44 | 45 | exports[`Client Manager (Camunda BPM) Get Workflows by limiting the result and skipping 2 workflows 1`] = ` 46 | { 47 | "items": [ 48 | { 49 | "bpmnProcessId": "message-event", 50 | "resourceName": "MESSAGE_EVENT.bpmn", 51 | "version": 1, 52 | "workflowKey": "message-event:1:ea268055-9b3e-11e9-ba13-0242ac110002", 53 | }, 54 | ], 55 | "paging": { 56 | "from": 3, 57 | "size": 2, 58 | "totalCount": 4, 59 | }, 60 | } 61 | `; 62 | -------------------------------------------------------------------------------- /packages/workit/src/camunda-n-mq/client.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IClient, IMessage } from '@villedemontreal/workit-types'; 8 | import { inject, injectable } from 'inversify'; 9 | import 'reflect-metadata'; 10 | import { SERVICE_IDENTIFIER } from '../config/constants/identifiers'; 11 | 12 | @injectable() 13 | export class Client { 14 | protected _onMessageReceived!: (message: IMessage, service: unknown) => Promise; 15 | 16 | protected readonly _client: TClient; 17 | 18 | constructor(@inject(SERVICE_IDENTIFIER.camunda_client) client: TClient) { 19 | this._client = client; 20 | } 21 | 22 | public async subscribe(handler: (message: IMessage, service: unknown) => Promise): Promise { 23 | if (handler != null) { 24 | this._onMessageReceived = handler; 25 | await this._startSubscriber(); 26 | } 27 | } 28 | 29 | public async unsubscribe(): Promise { 30 | await this._execute((x) => x.unsubscribe()); 31 | } 32 | 33 | private async _execute( 34 | action: (client: TClient) => Promise, 35 | onException?: (client: TClient) => Promise, 36 | ): Promise { 37 | try { 38 | return await action(this._client); 39 | } catch (ex) { 40 | if (!onException) { 41 | return Promise.resolve(); 42 | } 43 | return onException(this._client); 44 | } 45 | } 46 | 47 | private async _startSubscriber(): Promise { 48 | if (this._client != null) { 49 | await this._execute((x) => x.subscribe(this._onMessageReceived)); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/subscriptionOptions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | export interface ISubscriptionOptions { 8 | /** 9 | * Defines a subset of variables available in the handler. 10 | */ 11 | variables: (keyof T)[]; 12 | /** 13 | * A value which allows to filter tasks based on process instance business key 14 | */ 15 | businessKey: string; 16 | /** 17 | * A value which allows to filter tasks based on process definition id 18 | */ 19 | processDefinitionId: string; 20 | /** 21 | * A value which allows to filter tasks based on process definition ids 22 | */ 23 | processDefinitionIdIn: string; 24 | /** 25 | * A value which allows to filter tasks based on process definition key 26 | */ 27 | processDefinitionKey: string; 28 | /** 29 | * A value which allows to filter tasks based on process definition keys 30 | */ 31 | processDefinitionKeyIn: string; 32 | /** 33 | * A value which allows to filter tasks based on process definition Version Tag 34 | */ 35 | processDefinitionVersionTag: string; 36 | /** 37 | * A JSON object used for filtering tasks based on process instance variable values. A property name of the object represents a process variable name, while the property value represents the process variable value to filter tasks by. 38 | */ 39 | processVariables: Partial; 40 | /** 41 | * A value which allows to filter tasks based on tenant ids 42 | */ 43 | withoutTenantId: string; 44 | /** 45 | * A value which allows to filter tasks without tenant id 46 | */ 47 | tenantIdIn: string; 48 | } 49 | -------------------------------------------------------------------------------- /packages/workit-types/src/camundaBpm/camundaRepository.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IHttpResponse } from '../http/httpResponse'; 8 | import { IBpmn, IBpmnDeployResponse } from './bpmnDeployResponse'; 9 | import { ICamundaBpmCreateInstanceResponse } from './camundaBpmCreateInstanceResponse'; 10 | import { IProcessDefinition } from './processDefinition'; 11 | import { IProcessXmlDefinition } from './processXmlDefinition'; 12 | 13 | export interface ICamundaRepository { 14 | deployWorkflow(deployName: string, absPath: string): Promise>; 15 | getWorkflows(options?: { params: Record }): Promise>; 16 | getWorkflowCount(options?: { params: Record }): Promise>; 17 | getWorkflow(idOrKey: string): Promise; 18 | updateVariables(processInstanceId: string, variables: T): Promise>; 19 | updateJobRetries(id: string, retries: number): Promise>; 20 | createWorkflowInstance( 21 | idOrKey: string, 22 | variables: T, 23 | ): Promise>; 24 | publishMessage({ 25 | messageName, 26 | processInstanceId, 27 | variables, 28 | correlationKeys, 29 | }: { 30 | messageName: string; 31 | processInstanceId: string; 32 | variables: T; 33 | correlationKeys: K; 34 | }): Promise; 35 | resolveIncident(incidentKey: string): Promise; 36 | cancelWorkflowInstance(id: string): Promise; 37 | } 38 | -------------------------------------------------------------------------------- /packages/workit-types/src/core/camunda/workflowClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ville de Montreal. All rights reserved. 3 | * Licensed under the MIT license. 4 | * See LICENSE file in the project root for full license information. 5 | */ 6 | 7 | import { IPagination } from '../../commons/pagination'; 8 | import { IPaginationOptions } from '../../commons/paginationOptions'; 9 | import { ICreateWorkflowInstance } from './createWorkflowInstance'; 10 | import { ICreateWorkflowInstanceResponse } from './createWorkflowInstanceResponse'; 11 | import { IDeployWorkflowResponse } from './deployWorkflowResponse'; 12 | import { IPublishMessage } from './publishMessage'; 13 | import { IUpdateWorkflowRetry } from './updateWorkflowRetry'; 14 | import { IUpdateWorkflowVariables } from './updateWorkflowVariables'; 15 | import { IWorkflow } from './workflow'; 16 | import { IWorkflowDefinition, IWorkflowDefinitionRequest } from './workflowDefinition'; 17 | import { IWorkflowOptions } from './workflowOptions'; 18 | 19 | export interface IWorkflowClient { 20 | deployWorkflow(absPath: string, override?: T): Promise>; 21 | getWorkflows(options?: Partial): Promise>; 22 | updateVariables(payload: IUpdateWorkflowVariables): Promise; 23 | updateJobRetries(payload: IUpdateWorkflowRetry): Promise; 24 | publishMessage(payload: IPublishMessage): Promise; 25 | cancelWorkflowInstance(instance: number | string): Promise; 26 | createWorkflowInstance(payload: ICreateWorkflowInstance): Promise; 27 | resolveIncident(incidentKey: string): Promise; 28 | getWorkflow(payload: IWorkflowDefinitionRequest): Promise; 29 | } 30 | -------------------------------------------------------------------------------- /examples/basic/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This example shows how to use [Workit](https://villedemontreal.github.io/workit/) to create a simple Node.js application - e.g. a worker that executes a simple task. You will learn how to use Camunda BPM platform as well as AWS Step function 4 | 5 | Have fun! 6 | 7 | ## Installation 8 | 9 | ```sh 10 | $ # from this directory 11 | $ npm install 12 | ``` 13 | 14 | ### Configuring Step function 15 | 16 | #### Deploying new workflow 17 | 18 | ##### Use CloudFormation and the AWS CDK (recommanded) 19 | 20 | Todo: provide steps 21 | 22 | ##### Manually 23 | 24 | In `examples/basic/workflow/stepfunction/WORKFLOW_DEMO.json`, you will need to specify the `QueueUrl` and in `examples/basic/src/deploy.ts` , you must specify the `roleArn` to use for deploying the new workflow. 25 | 26 | Notice that you can skip this step if you deploy the workflow through the AWS Step function UI and it won't be necessary to run `npm run deploy` 27 | 28 | ### For All files 29 | 30 | You must specify the following environment variables : 31 | 32 | - AWS_REGION 33 | - AWS_ACCESS_KEY_ID 34 | - AWS_SECRET_ACCESS_KEY 35 | - AWS_SQS_QUEUE_URL 36 | - AWS_SQS_WAIT_TIME_SECONDS (Optional) 37 | 38 | (Optional) Setup, we can switch to `TAG.camundaBpm` or `TAG.stepFunction` in order to use both platforms (some comments are added in the example). 39 | 40 | ```sh 41 | $ # from this directory 42 | $ npm run build 43 | ``` 44 | 45 | ## Run the Application 46 | 47 | ```sh 48 | $ # from this directory 49 | $ # deploy the workflow provided in the example 50 | $ npm run deploy 51 | $ # create instance(s) 52 | $ npm run create-instance 53 | $ # run worker 54 | $ npm run worker 55 | ``` 56 | 57 | ## Useful links 58 | - For more information on workit, visit: 59 | 60 | ## LICENSE 61 | 62 | MIT 63 | -------------------------------------------------------------------------------- /packages/workit/tests/data/camunda-response.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "activityId": "sample_activity", 4 | "activityInstanceId": "sample_activity:37a6adef-c4c2-11e8-a64b-0242ac110002", 5 | "errorMessage": null, 6 | "errorDetails": null, 7 | "executionId": "37a6adee-c4c2-11e8-a64b-0242ac110002", 8 | "id": "37a72320-c4c2-11e8-a64b-0242ac110002", 9 | "lockExpirationTime": "2018-09-30T15:06:17.714+0000", 10 | "processDefinitionId": "BPMN_DEMO:1:de79f138-c020-11e8-970d-0242ac110002", 11 | "processDefinitionKey": "BPMN_DEMO", 12 | "processInstanceId": "37a4d921-c4c2-11e8-a64b-0242ac110002", 13 | "retries": null, 14 | "suspended": false, 15 | "workerId": "some-random-id", 16 | "topicName": "topic_demo", 17 | "tenantId": null, 18 | "variables": { 19 | "internalStatus": { 20 | "type": "String", 21 | "value": "completed", 22 | "valueInfo": {} 23 | }, 24 | "serviceType": { 25 | "type": "String", 26 | "value": "pet-licensing", 27 | "valueInfo": {} 28 | }, 29 | "requestInfo": { 30 | "type": "Json", 31 | "value": "{\"jwtAccessToken\":\"dc79a8db-24c9-4246-a8ce-53185e72e2d9\",\"jwtInum\":\"\",\"jwtUserName\":\"srvAccBPM\",\"jwtUserType\":\"serviceAccount\",\"xUser\": \"Olivier1537469226875\",\"acceptLanguage\":\"fr-CA\",\"xCorrelationId\":\"CID-Test-726\"}", 32 | "valueInfo": {} 33 | }, 34 | "id": { 35 | "type": "String", 36 | "value": "5535", 37 | "valueInfo": {} 38 | } 39 | }, 40 | "priority": 0, 41 | "businessKey": null 42 | } 43 | ] -------------------------------------------------------------------------------- /eslint.rules.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // prettier conflicts 3 | "no-underscore-dangle": "off", 4 | "max-len": "off", 5 | "max-classes-per-file": "off", 6 | "class-methods-use-this": "off", 7 | "no-await-in-loop": "off", 8 | "import/prefer-default-export": "off", 9 | "comma-dangle": "off", 10 | "object-curly-newline": "off", 11 | "arrow-parens": "off", 12 | "implicit-arrow-linebreak": "off", 13 | "prettier/prettier": "error", 14 | "@typescript-eslint/no-unused-vars": "off", 15 | "@typescript-eslint/no-useless-constructor": "off", // not good with inversify 16 | "@typescript-eslint/no-misused-promises": "off", 17 | "@typescript-eslint/no-explicit-any": "off", 18 | "import/named": "off", // not working properly 19 | "@typescript-eslint/naming-convention": [ 20 | "error", 21 | { 22 | "selector": "interface", 23 | "format": ["PascalCase"], 24 | "custom": { 25 | "regex": "^I[A-Z]", 26 | "match": true 27 | } 28 | } 29 | ], 30 | "@typescript-eslint/explicit-member-accessibility": ["error", { 31 | "accessibility": "explicit", 32 | "overrides": { 33 | "accessors": "explicit", 34 | "constructors": "no-public", 35 | "methods": "explicit", 36 | "properties": "explicit", 37 | "parameterProperties": "explicit" 38 | } 39 | }], 40 | "@typescript-eslint/naming-convention": [ 41 | "error", 42 | { 43 | "selector": "memberLike", 44 | "modifiers": ["private"], 45 | "format": ["camelCase", "UPPER_CASE"], 46 | "leadingUnderscore": "require" 47 | } 48 | ], 49 | "header/header": [2, "block", [ 50 | `\n * Copyright (c) ${new Date().getFullYear()} Ville de Montreal. All rights reserved.\n * Licensed under the MIT license.\n * See LICENSE file in the project root for full license information.\n ` 51 | ]] 52 | }; -------------------------------------------------------------------------------- /packages/workit-bpm-client/tests/data/camunda-response.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "activityId": "sample_activity", 4 | "activityInstanceId": "sample_activity:37a6adef-c4c2-11e8-a64b-0242ac110002", 5 | "errorMessage": null, 6 | "errorDetails": null, 7 | "executionId": "37a6adee-c4c2-11e8-a64b-0242ac110002", 8 | "id": "37a72320-c4c2-11e8-a64b-0242ac110002", 9 | "lockExpirationTime": "2018-09-30T15:06:17.714+0000", 10 | "processDefinitionId": "BPMN_DEMO:1:de79f138-c020-11e8-970d-0242ac110002", 11 | "processDefinitionKey": "BPMN_DEMO", 12 | "processInstanceId": "37a4d921-c4c2-11e8-a64b-0242ac110002", 13 | "retries": null, 14 | "suspended": false, 15 | "workerId": "some-random-id", 16 | "topicName": "topic_demo", 17 | "tenantId": null, 18 | "variables": { 19 | "internalStatus": { 20 | "type": "String", 21 | "value": "completed", 22 | "valueInfo": {} 23 | }, 24 | "serviceType": { 25 | "type": "String", 26 | "value": "pet-licensing", 27 | "valueInfo": {} 28 | }, 29 | "requestInfo": { 30 | "type": "Json", 31 | "value": "{\"jwtAccessToken\":\"dc79a8db-24c9-4246-a8ce-53185e72e2d9\",\"jwtInum\":\"\",\"jwtUserName\":\"srvAccBPM\",\"jwtUserType\":\"serviceAccount\",\"xUser\": \"Olivier1537469226875\",\"acceptLanguage\":\"fr-CA\",\"xCorrelationId\":\"CID-Test-726\"}", 32 | "valueInfo": {} 33 | }, 34 | "id": { 35 | "type": "String", 36 | "value": "5535", 37 | "valueInfo": {} 38 | } 39 | }, 40 | "priority": 0, 41 | "businessKey": null 42 | } 43 | ] 44 | --------------------------------------------------------------------------------