@kaleido-io/workflow-engine-sdk 0.0.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +1121 -0
- package/bin/init.js +200 -0
- package/bin/wesdk.js +57 -0
- package/dist/package.json +3 -0
- package/dist/src/client/client.d.ts +24 -0
- package/dist/src/client/client.d.ts.map +1 -0
- package/dist/src/client/client.js +58 -0
- package/dist/src/client/client.js.map +1 -0
- package/dist/src/client/rest-client.d.ts +222 -0
- package/dist/src/client/rest-client.d.ts.map +1 -0
- package/dist/src/client/rest-client.js +242 -0
- package/dist/src/client/rest-client.js.map +1 -0
- package/dist/src/config/config.d.ts +60 -0
- package/dist/src/config/config.d.ts.map +1 -0
- package/dist/src/config/config.js +117 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/factories/event_source.d.ts +54 -0
- package/dist/src/factories/event_source.d.ts.map +1 -0
- package/dist/src/factories/event_source.js +170 -0
- package/dist/src/factories/event_source.js.map +1 -0
- package/dist/src/factories/transaction_handler.d.ts +27 -0
- package/dist/src/factories/transaction_handler.d.ts.map +1 -0
- package/dist/src/factories/transaction_handler.js +66 -0
- package/dist/src/factories/transaction_handler.js.map +1 -0
- package/dist/src/helpers/stage_director.d.ts +42 -0
- package/dist/src/helpers/stage_director.d.ts.map +1 -0
- package/dist/src/helpers/stage_director.js +304 -0
- package/dist/src/helpers/stage_director.js.map +1 -0
- package/dist/src/i18n/errors.d.ts +61 -0
- package/dist/src/i18n/errors.d.ts.map +1 -0
- package/dist/src/i18n/errors.js +90 -0
- package/dist/src/i18n/errors.js.map +1 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +85 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces/handlers.d.ts +112 -0
- package/dist/src/interfaces/handlers.d.ts.map +1 -0
- package/dist/src/interfaces/handlers.js +18 -0
- package/dist/src/interfaces/handlers.js.map +1 -0
- package/dist/src/interfaces/messages.d.ts +6 -0
- package/dist/src/interfaces/messages.d.ts.map +1 -0
- package/dist/src/interfaces/messages.js +18 -0
- package/dist/src/interfaces/messages.js.map +1 -0
- package/dist/src/log/logger.d.ts +8 -0
- package/dist/src/log/logger.d.ts.map +1 -0
- package/dist/src/log/logger.js +39 -0
- package/dist/src/log/logger.js.map +1 -0
- package/dist/src/runtime/engine_client.d.ts +37 -0
- package/dist/src/runtime/engine_client.d.ts.map +1 -0
- package/dist/src/runtime/engine_client.js +99 -0
- package/dist/src/runtime/engine_client.js.map +1 -0
- package/dist/src/runtime/handler_runtime.d.ts +124 -0
- package/dist/src/runtime/handler_runtime.d.ts.map +1 -0
- package/dist/src/runtime/handler_runtime.js +623 -0
- package/dist/src/runtime/handler_runtime.js.map +1 -0
- package/dist/src/types/core.d.ts +258 -0
- package/dist/src/types/core.d.ts.map +1 -0
- package/dist/src/types/core.js +71 -0
- package/dist/src/types/core.js.map +1 -0
- package/dist/src/types/flows.d.ts +144 -0
- package/dist/src/types/flows.d.ts.map +1 -0
- package/dist/src/types/flows.js +30 -0
- package/dist/src/types/flows.js.map +1 -0
- package/dist/src/utils/errors.d.ts +2 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +23 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/patch.d.ts +9 -0
- package/dist/src/utils/patch.d.ts.map +1 -0
- package/dist/src/utils/patch.js +99 -0
- package/dist/src/utils/patch.js.map +1 -0
- package/dist-esm/src/client/client.js +54 -0
- package/dist-esm/src/client/client.js.map +1 -0
- package/dist-esm/src/client/rest-client.js +238 -0
- package/dist-esm/src/client/rest-client.js.map +1 -0
- package/dist-esm/src/config/config.js +113 -0
- package/dist-esm/src/config/config.js.map +1 -0
- package/dist-esm/src/factories/event_source.js +167 -0
- package/dist-esm/src/factories/event_source.js.map +1 -0
- package/dist-esm/src/factories/transaction_handler.js +63 -0
- package/dist-esm/src/factories/transaction_handler.js.map +1 -0
- package/dist-esm/src/helpers/stage_director.js +298 -0
- package/dist-esm/src/helpers/stage_director.js.map +1 -0
- package/dist-esm/src/i18n/errors.js +85 -0
- package/dist-esm/src/i18n/errors.js.map +1 -0
- package/dist-esm/src/index.js +51 -0
- package/dist-esm/src/index.js.map +1 -0
- package/dist-esm/src/interfaces/handlers.js +17 -0
- package/dist-esm/src/interfaces/handlers.js.map +1 -0
- package/dist-esm/src/interfaces/messages.js +17 -0
- package/dist-esm/src/interfaces/messages.js.map +1 -0
- package/dist-esm/src/log/logger.js +36 -0
- package/dist-esm/src/log/logger.js.map +1 -0
- package/dist-esm/src/runtime/engine_client.js +95 -0
- package/dist-esm/src/runtime/engine_client.js.map +1 -0
- package/dist-esm/src/runtime/handler_runtime.js +586 -0
- package/dist-esm/src/runtime/handler_runtime.js.map +1 -0
- package/dist-esm/src/types/core.js +68 -0
- package/dist-esm/src/types/core.js.map +1 -0
- package/dist-esm/src/types/flows.js +27 -0
- package/dist-esm/src/types/flows.js.map +1 -0
- package/dist-esm/src/utils/errors.js +19 -0
- package/dist-esm/src/utils/errors.js.map +1 -0
- package/dist-esm/src/utils/patch.js +56 -0
- package/dist-esm/src/utils/patch.js.map +1 -0
- package/package.json +79 -11
- package/template/.env.sample +14 -0
- package/template/.vscode/launch.json +23 -0
- package/template/README.md +37 -0
- package/template/package.json +36 -0
- package/template/src/connect.ts +58 -0
- package/template/src/provider.ts +24 -0
- package/template/src/samples/event-source/README.md +50 -0
- package/template/src/samples/event-source/echo-handler.ts +65 -0
- package/template/src/samples/event-source/event-processor.ts +46 -0
- package/template/src/samples/event-source/event-source.ts +70 -0
- package/template/src/samples/event-source/stream.ts +34 -0
- package/template/src/samples/hello/README.md +52 -0
- package/template/src/samples/hello/flow.ts +74 -0
- package/template/src/samples/hello/handlers.test.ts +147 -0
- package/template/src/samples/hello/handlers.ts +72 -0
- package/template/src/samples/hello/transaction.ts +24 -0
- package/template/src/samples/http-invoke/README.md +42 -0
- package/template/src/samples/http-invoke/flow.ts +63 -0
- package/template/src/samples/http-invoke/handlers.ts +66 -0
- package/template/src/samples/http-invoke/transaction.ts +22 -0
- package/template/src/samples/snap/README.md +98 -0
- package/template/src/samples/snap/event-source.ts +104 -0
- package/template/src/samples/snap/flow.ts +85 -0
- package/template/src/samples/snap/snap-handler.ts +84 -0
- package/template/src/samples/snap/stream.ts +26 -0
- package/template/src/samples/snap/transaction.ts +26 -0
- package/template/src/utils/post-stream.ts +67 -0
- package/template/src/utils/post-transaction.ts +64 -0
- package/template/src/utils/post-workflow.ts +63 -0
- package/template/tsconfig.json +24 -0
- package/template/vitest.config.ts +42 -0
- package/CODEOWNERS +0 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import { EventSourceConf, EventSourceEvent, newEventSource, newLogger, WSEventStreamInfo } from "@kaleido-io/workflow-engine-sdk";
|
|
19
|
+
|
|
20
|
+
const log = newLogger('event-source');
|
|
21
|
+
|
|
22
|
+
// Example event source handler using the factory
|
|
23
|
+
interface MyEventSourceConfig {
|
|
24
|
+
pollingInterval: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface MyEventSourceCheckpoint {
|
|
28
|
+
lastPollTime: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface MyEventData {
|
|
32
|
+
message: string;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const eventSource = newEventSource<MyEventSourceCheckpoint, MyEventSourceConfig, MyEventData>(
|
|
37
|
+
'my-listener',
|
|
38
|
+
async (config: EventSourceConf<MyEventSourceConfig>, checkpoint: MyEventSourceCheckpoint | null) => {
|
|
39
|
+
log.info('Polling for events with config:', config.config);
|
|
40
|
+
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
let lastPollTime = checkpoint?.lastPollTime || now;
|
|
43
|
+
const events: EventSourceEvent<MyEventData>[] = [];
|
|
44
|
+
if (now - lastPollTime > 10000) {
|
|
45
|
+
const timestamp = now;
|
|
46
|
+
events.push({
|
|
47
|
+
idempotencyKey: `event-${timestamp}`,
|
|
48
|
+
topic: 'my-topic',
|
|
49
|
+
data: { message: `Hello from event source at ${new Date(timestamp).toISOString()}`, timestamp }
|
|
50
|
+
});
|
|
51
|
+
lastPollTime = now;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
checkpointOut: { lastPollTime },
|
|
56
|
+
events
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
.withInitialCheckpoint(async () => ({
|
|
61
|
+
lastPollTime: 0
|
|
62
|
+
}))
|
|
63
|
+
.withConfigParser(async (_, config: MyEventSourceConfig) => {
|
|
64
|
+
return {
|
|
65
|
+
pollingInterval: config.pollingInterval || 5000
|
|
66
|
+
};
|
|
67
|
+
})
|
|
68
|
+
.withDeleteFn(async (info: WSEventStreamInfo) => {
|
|
69
|
+
log.info(`Cleaning up event source ${info.streamName} (${info.streamId})`);
|
|
70
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import provider from '../../provider.js';
|
|
19
|
+
|
|
20
|
+
export const stream = {
|
|
21
|
+
"name": "event-echo-stream",
|
|
22
|
+
"description": "Listen for events from the custom event source and pass them to the echo event processor",
|
|
23
|
+
"type": "event_stream",
|
|
24
|
+
"config": {
|
|
25
|
+
"pollingInterval": "2s"
|
|
26
|
+
},
|
|
27
|
+
"listenerHandler": "my-listener",
|
|
28
|
+
"listenerHandlerProvider": provider.name,
|
|
29
|
+
"eventHandler": "echo",
|
|
30
|
+
"eventHandlerProvider": provider.name,
|
|
31
|
+
"postFilter": {
|
|
32
|
+
"jsonata": "true"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Hello sample
|
|
2
|
+
|
|
3
|
+
This example demonstrates a simple transaction handler that processes input data and returns a greeting message.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The hello sample consists of two main components:
|
|
8
|
+
|
|
9
|
+
1. **Handler** (`handlers.ts`) - Processes a name input and returns a personalized greeting
|
|
10
|
+
2. **Workflow** (`flow.ts`) - Defines the workflow that invokes the hello handler
|
|
11
|
+
|
|
12
|
+
## How it works
|
|
13
|
+
|
|
14
|
+
### Handler
|
|
15
|
+
|
|
16
|
+
The hello handler (`handlers.ts`) accepts a transaction with a `name` field in the input. It:
|
|
17
|
+
|
|
18
|
+
- Validates that the `name` field is provided
|
|
19
|
+
- Returns a personalized greeting message in the output
|
|
20
|
+
- Emits an event with the greeting message to demonstrate event emission from handlers
|
|
21
|
+
|
|
22
|
+
If the `name` field is missing, the handler returns a hard failure with an error message.
|
|
23
|
+
|
|
24
|
+
### Workflow
|
|
25
|
+
|
|
26
|
+
The `hello-flow` workflow (`flow.ts`) defines a simple asynchronous operation that:
|
|
27
|
+
|
|
28
|
+
- Accepts an input with a required `name` string field
|
|
29
|
+
- Invokes the hello handler to process the input
|
|
30
|
+
- Returns the greeting message in the output
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
1. Register the hello handler in your provider's main file:
|
|
35
|
+
```typescript
|
|
36
|
+
const helloHandler = newDirectedTransactionHandler('hello', helloActionMap);
|
|
37
|
+
client.registerTransactionHandler('hello', helloHandler);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Start your application to register your provider and handlers with the workflow engine.
|
|
41
|
+
|
|
42
|
+
3. Post the workflow to the workflow engine using the utility script:
|
|
43
|
+
```bash
|
|
44
|
+
npm run create-workflow src/samples/hello/flow.ts
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
4. Create a transaction to test the handler:
|
|
48
|
+
```bash
|
|
49
|
+
npm run create-transaction src/samples/hello/transaction.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The handler will process the transaction and return a greeting message. A transaction event will also be created.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import provider from '../../provider.js';
|
|
19
|
+
export const flow = {
|
|
20
|
+
"name": "hello-flow",
|
|
21
|
+
"description": "",
|
|
22
|
+
"labels": {},
|
|
23
|
+
"handlerBindings": {
|
|
24
|
+
"hello": {
|
|
25
|
+
"provider": provider.name,
|
|
26
|
+
"providerHandler": "hello"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"version": "1.0.0",
|
|
30
|
+
"operations": [
|
|
31
|
+
{
|
|
32
|
+
"name": "hello",
|
|
33
|
+
"description": "Hello",
|
|
34
|
+
"type": "asynchronous",
|
|
35
|
+
"stage": "my-beginning-state",
|
|
36
|
+
"stateUpdates": null,
|
|
37
|
+
"inputSchema": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"properties": {
|
|
40
|
+
"name": {
|
|
41
|
+
"type": [
|
|
42
|
+
"string"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"required": [
|
|
47
|
+
"name"
|
|
48
|
+
],
|
|
49
|
+
"additionalProperties": false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"stages": [
|
|
54
|
+
{
|
|
55
|
+
"name": "my-beginning-state",
|
|
56
|
+
"type": "pending",
|
|
57
|
+
"handler": "hello",
|
|
58
|
+
"inputMap": {
|
|
59
|
+
"jsonata": "{\n \"action\": \"hello\",\n \"invoke\": {\n \"input\": state.input\n },\n \"nextStage\": \"end\",\n \"failureStage\": \"failure\",\n \"outputPath\": \"/output\"\n}\n"
|
|
60
|
+
},
|
|
61
|
+
"fullState": true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "end",
|
|
65
|
+
"type": "success",
|
|
66
|
+
"handler": ""
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "failure",
|
|
70
|
+
"type": "failure",
|
|
71
|
+
"handler": ""
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import { describe, it, expect } from 'vitest';
|
|
19
|
+
import { EvalResult, WSEvaluateTransaction } from '@kaleido-io/workflow-engine-sdk';
|
|
20
|
+
import { actionMap } from './handlers';
|
|
21
|
+
|
|
22
|
+
describe('Hello handlers', () => {
|
|
23
|
+
it('should return a greeting when name is provided', async () => {
|
|
24
|
+
const handler = actionMap.get('hello');
|
|
25
|
+
expect(handler).toBeDefined();
|
|
26
|
+
|
|
27
|
+
if (!handler || !handler.handler) {
|
|
28
|
+
throw new Error('Handler not found');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const mockRequest: Partial<WSEvaluateTransaction> = {
|
|
32
|
+
state: {
|
|
33
|
+
input: {
|
|
34
|
+
name: 'World'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const mockInput = {
|
|
40
|
+
stageDirector: {
|
|
41
|
+
action: 'hello',
|
|
42
|
+
outputPath: '/output',
|
|
43
|
+
nextStage: 'end',
|
|
44
|
+
failureStage: 'failed'
|
|
45
|
+
},
|
|
46
|
+
getStageDirector: () => mockInput.stageDirector,
|
|
47
|
+
name: () => 'hello'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const result = await handler.handler(mockRequest as WSEvaluateTransaction, mockInput as any);
|
|
51
|
+
|
|
52
|
+
expect(result.result).toBe(EvalResult.COMPLETE);
|
|
53
|
+
expect(result.output).toEqual({
|
|
54
|
+
greeting: 'Hello World!'
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return HARD_FAILURE when name is missing', async () => {
|
|
59
|
+
const handler = actionMap.get('hello');
|
|
60
|
+
expect(handler).toBeDefined();
|
|
61
|
+
|
|
62
|
+
if (!handler || !handler.handler) {
|
|
63
|
+
throw new Error('Handler not found');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const mockRequest: Partial<WSEvaluateTransaction> = {
|
|
67
|
+
state: {
|
|
68
|
+
input: {}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const mockInput = {
|
|
73
|
+
stageDirector: {
|
|
74
|
+
action: 'hello',
|
|
75
|
+
outputPath: '/output',
|
|
76
|
+
nextStage: 'end',
|
|
77
|
+
failureStage: 'failed'
|
|
78
|
+
},
|
|
79
|
+
getStageDirector: () => mockInput.stageDirector,
|
|
80
|
+
name: () => 'hello'
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const result = await handler.handler(mockRequest as WSEvaluateTransaction, mockInput as any);
|
|
84
|
+
|
|
85
|
+
expect(result.result).toBe(EvalResult.HARD_FAILURE);
|
|
86
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
87
|
+
expect(result.error?.message).toBe('Name is required');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should return HARD_FAILURE when state.input is undefined', async () => {
|
|
91
|
+
const handler = actionMap.get('hello');
|
|
92
|
+
expect(handler).toBeDefined();
|
|
93
|
+
|
|
94
|
+
if (!handler || !handler.handler) {
|
|
95
|
+
throw new Error('Handler not found');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const mockRequest: Partial<WSEvaluateTransaction> = {
|
|
99
|
+
state: {}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const mockInput = {
|
|
103
|
+
stageDirector: {
|
|
104
|
+
action: 'hello',
|
|
105
|
+
outputPath: '/output',
|
|
106
|
+
nextStage: 'end',
|
|
107
|
+
failureStage: 'failed'
|
|
108
|
+
},
|
|
109
|
+
getStageDirector: () => mockInput.stageDirector,
|
|
110
|
+
name: () => 'hello'
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const result = await handler.handler(mockRequest as WSEvaluateTransaction, mockInput as any);
|
|
114
|
+
|
|
115
|
+
expect(result.result).toBe(EvalResult.HARD_FAILURE);
|
|
116
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
117
|
+
expect(result.error?.message).toBe('Name is required');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should return HARD_FAILURE when state is undefined', async () => {
|
|
121
|
+
const handler = actionMap.get('hello');
|
|
122
|
+
expect(handler).toBeDefined();
|
|
123
|
+
|
|
124
|
+
if (!handler || !handler.handler) {
|
|
125
|
+
throw new Error('Handler not found');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const mockRequest: Partial<WSEvaluateTransaction> = {};
|
|
129
|
+
|
|
130
|
+
const mockInput = {
|
|
131
|
+
stageDirector: {
|
|
132
|
+
action: 'hello',
|
|
133
|
+
outputPath: '/output',
|
|
134
|
+
nextStage: 'end',
|
|
135
|
+
failureStage: 'failed'
|
|
136
|
+
},
|
|
137
|
+
getStageDirector: () => mockInput.stageDirector,
|
|
138
|
+
name: () => 'hello'
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const result = await handler.handler(mockRequest as WSEvaluateTransaction, mockInput as any);
|
|
142
|
+
|
|
143
|
+
expect(result.result).toBe(EvalResult.HARD_FAILURE);
|
|
144
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
145
|
+
expect(result.error?.message).toBe('Name is required');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import { BasicStageDirector, DirectedActionConfig, EvalResult, InvocationMode, WithStageDirector, WSEvaluateTransaction } from "@kaleido-io/workflow-engine-sdk";
|
|
19
|
+
|
|
20
|
+
class MyHandlerInput implements WithStageDirector {
|
|
21
|
+
public stageDirector: BasicStageDirector;
|
|
22
|
+
public action1?: { inputA: string };
|
|
23
|
+
public action2?: { inputB: string };
|
|
24
|
+
public customData?: any;
|
|
25
|
+
|
|
26
|
+
constructor(data: any) {
|
|
27
|
+
this.stageDirector = new BasicStageDirector(
|
|
28
|
+
data.action || 'hello',
|
|
29
|
+
data.outputPath || '/output',
|
|
30
|
+
data.nextStage || 'end',
|
|
31
|
+
data.failureStage || 'failed'
|
|
32
|
+
);
|
|
33
|
+
this.customData = data.customData;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getStageDirector(): BasicStageDirector {
|
|
37
|
+
return this.stageDirector;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
name(): string {
|
|
41
|
+
return 'hello';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const map: Map<string, DirectedActionConfig<MyHandlerInput>> = new Map([
|
|
46
|
+
["hello", {
|
|
47
|
+
invocationMode: InvocationMode.PARALLEL, handler: async (transaction: WSEvaluateTransaction) => {
|
|
48
|
+
if (transaction.state?.input?.name === undefined) {
|
|
49
|
+
return {
|
|
50
|
+
result: EvalResult.HARD_FAILURE,
|
|
51
|
+
error: new Error('Name is required')
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
return {
|
|
55
|
+
result: EvalResult.COMPLETE,
|
|
56
|
+
output: {
|
|
57
|
+
greeting: `Hello ${transaction.state.input.name}!`,
|
|
58
|
+
},
|
|
59
|
+
events: [
|
|
60
|
+
{
|
|
61
|
+
idempotencyKey: transaction.idempotencyKey,
|
|
62
|
+
topic: 'greeting',
|
|
63
|
+
data: `Hello ${transaction.state.input.name}!`
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}],
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
export const actionMap = map;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export const transaction = {
|
|
19
|
+
"input": {
|
|
20
|
+
"name": "workflow engine developer"
|
|
21
|
+
},
|
|
22
|
+
"operation": "hello",
|
|
23
|
+
"workflow": "hello-flow"
|
|
24
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# HTTP invoke sample
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to make HTTP requests to external APIs from within a transaction handler.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The http-invoke sample consists of two main components:
|
|
8
|
+
|
|
9
|
+
1. **Handler** (`handlers.ts`) - Makes an HTTP request to an external API and returns the response
|
|
10
|
+
2. **Workflow** (`flow.ts`) - Defines the workflow that invokes the http-invoke handler
|
|
11
|
+
|
|
12
|
+
## How it works
|
|
13
|
+
|
|
14
|
+
### Handler
|
|
15
|
+
|
|
16
|
+
The http-invoke handler (`handlers.ts`) demonstrates a handler making an async request and providing a response to the transaction when the request has completed.
|
|
17
|
+
|
|
18
|
+
### Workflow
|
|
19
|
+
|
|
20
|
+
The `http-invoke-flow` workflow (`flow.ts`) is a simple flow that completes once the HTTP response has been returned by the handler.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
1. Register the http-invoke handler in your provider's main file:
|
|
25
|
+
```typescript
|
|
26
|
+
const httpInvokeHandler = newDirectedTransactionHandler('http-invoke', httpInvokeActionMap);
|
|
27
|
+
client.registerTransactionHandler('http-invoke', httpInvokeHandler);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. Start your application to register your provider and handlers with the workflow engine.
|
|
31
|
+
|
|
32
|
+
4. Post the workflow to the workflow engine using the utility script:
|
|
33
|
+
```bash
|
|
34
|
+
npm run create-workflow src/samples/http-invoke/flow.ts
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
5. Create a transaction to test the handler:
|
|
38
|
+
```bash
|
|
39
|
+
npm run create-transaction src/samples/http-invoke/transaction.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The handler will make the HTTP request and return the response.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import provider from '../../provider.js';
|
|
19
|
+
export const flow = {
|
|
20
|
+
"name": "http-invoke-flow",
|
|
21
|
+
"description": "",
|
|
22
|
+
"labels": {},
|
|
23
|
+
"handlerBindings": {
|
|
24
|
+
"http-invoke": {
|
|
25
|
+
"provider": provider.name,
|
|
26
|
+
"providerHandler": "http-invoke"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"version": "1.0.0",
|
|
30
|
+
"operations": [
|
|
31
|
+
{
|
|
32
|
+
"name": "http-invoke",
|
|
33
|
+
"description": "HTTP Invoke",
|
|
34
|
+
"type": "asynchronous",
|
|
35
|
+
"stage": "start",
|
|
36
|
+
"inputSchema": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"additionalProperties": true
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"stages": [
|
|
43
|
+
{
|
|
44
|
+
"name": "start",
|
|
45
|
+
"type": "pending",
|
|
46
|
+
"handler": "http-invoke",
|
|
47
|
+
"inputMap": {
|
|
48
|
+
"jsonata": "{\n \"action\": \"http-invoke\",\n \"invoke\": {\n \"input\": state.input\n },\n \"nextStage\": \"end\",\n \"failureStage\": \"failure\",\n \"outputPath\": \"/output\"\n}\n"
|
|
49
|
+
},
|
|
50
|
+
"fullState": true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "end",
|
|
54
|
+
"type": "success",
|
|
55
|
+
"handler": ""
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "failure",
|
|
59
|
+
"type": "failure",
|
|
60
|
+
"handler": ""
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import { BasicStageDirector, DirectedActionConfig, EvalResult, InvocationMode, WithStageDirector } from "@kaleido-io/workflow-engine-sdk";
|
|
19
|
+
|
|
20
|
+
class HTTPInvokeHandlerInput implements WithStageDirector {
|
|
21
|
+
public stageDirector: BasicStageDirector;
|
|
22
|
+
public action1?: { inputA: string };
|
|
23
|
+
public action2?: { inputB: string };
|
|
24
|
+
public customData?: any;
|
|
25
|
+
|
|
26
|
+
constructor(data: any) {
|
|
27
|
+
this.stageDirector = new BasicStageDirector(
|
|
28
|
+
data.action || 'http-invoke',
|
|
29
|
+
data.outputPath || '/output',
|
|
30
|
+
data.nextStage || 'end',
|
|
31
|
+
data.failureStage || 'failed'
|
|
32
|
+
);
|
|
33
|
+
this.customData = data.customData;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getStageDirector(): BasicStageDirector {
|
|
37
|
+
return this.stageDirector;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
name(): string {
|
|
41
|
+
return 'hello';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const url = 'https://httpbin.org/get';
|
|
46
|
+
const map: Map<string, DirectedActionConfig<HTTPInvokeHandlerInput>> = new Map([
|
|
47
|
+
["http-invoke", {
|
|
48
|
+
invocationMode: InvocationMode.PARALLEL, handler: async () => {
|
|
49
|
+
const response = await fetch(url, {
|
|
50
|
+
headers: {
|
|
51
|
+
'X-API-KEY': process.env.API_KEY ?? '',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
const body = await response.json();
|
|
55
|
+
return {
|
|
56
|
+
result: EvalResult.COMPLETE,
|
|
57
|
+
output: {
|
|
58
|
+
body,
|
|
59
|
+
status: response.status,
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}],
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
export const actionMap = map;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright © 2026 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export const transaction = {
|
|
19
|
+
"input": {},
|
|
20
|
+
"operation": "http-invoke",
|
|
21
|
+
"workflow": "http-invoke-flow"
|
|
22
|
+
}
|