This commit is contained in:
wukun
2025-11-13 01:06:33 +08:00
commit 3dca415827
24 changed files with 1679 additions and 0 deletions

47
.gitignore vendored Normal file
View File

@@ -0,0 +1,47 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
ejx4api
ejx4base
ejx4msg
.vscode
.idea
tmp
/target
/.classpath
/.settings
/bin
/maven-eclipse.xml
/.externalToolBuilders
.project
.gradle
.idea
.vscode
out
build
.flattened-pom.xml

74
README.md Normal file
View File

@@ -0,0 +1,74 @@
这是 eax 示例工程
- conf 是 nodejs 配置代码
- 其他的部分,是标准的 java 工程。
## java 部分特别说明
运行时,需要额外依赖
```xml
<dependency>
<groupId>com.tienon.eax</groupId>
<artifactId>eax4core</artifactId>
<version>1.0.0</version>
</dependency>
```
若只开发 service只需要依赖
```xml
<dependency>
<groupId>com.tienon.eax</groupId>
<artifactId>eax4api</artifactId>
<version>1.0.0</version>
</dependency>
```
## conf 说明
```sh
cd conf
npm install
npm postinstall
```
### xbuid
若没有错误,然后运行
```sh
% npx xbuild
加载 .env 文件成功: .env => /Users/wukun/dev/eax4java/exapp/conf/.env
Usage: xbuild [options] [command]
A CLI with subcommands
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
load [options] [basePackage] 导出所有组件定义
dump [options] [filePath] 导出测试部署的流程图文件到 java 工程
deploy [flowId] 部署工作流
run [options] <flowId> 运行工作流
info 获取调试信息
test [options] <flowId> 测试工作流: 部署并运行工作流
release <version> 发布新版本的配置信息
help [command] display help for command
```
### 编辑 .env
```ini
XBUILD_DIR=/Users/wukun/dev/eax4java/exapp/conf
# java
CLASS_PATH=/Users/wukun/dev/eax4java/exapp/target/classes
BASE_PACKAGE=com.tienon.eax.example
# 配置文件
RESOURCE_FILE=/Users/wukun/dev/eax4java/exapp/src/main/resources/workflows.json
# api
OPS_API_URL=http://localhost:8080
RUN_API_URL=http://localhost:8080
```

8
conf/.env.example Normal file
View File

@@ -0,0 +1,8 @@
XBUILD_DIR=/Users/wukun/dev/eax4java/devtool/example
# java
CLASS_PATH=/Users/wukun/dev/eax4java/eax4dev/target/classes
BASE_PACKAGE=com.tienon.eax.example
RESOURCE_FILE=/Users/wukun/dev/eax4java/exapp/src/main/resources/workflow.json
# api
OPS_API_URL=http://localhost:8080
RUN_API_URL=http://localhost:8080

3
conf/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
cache
.env
node_modules

3
conf/.npmrc Normal file
View File

@@ -0,0 +1,3 @@
registry=http://mirrors.cloud.tencent.com/npm/
@xui:registry=http://gitea.reactgo.cn/api/packages/anyone/npm/
//gitea.reactgo.cn/api/packages/anyone/npm/:_authToken=d1c17ba3407303cef87ddd07cdc4ad7b005255d2

3
conf/Makefile Normal file
View File

@@ -0,0 +1,3 @@
all:
npx xbuild run example1 -j '{"name":"wk"}'

23
conf/package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "@xui/example",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "xbuild load",
"start": "tsx src/main/run_workflow1.ts",
"postinstall": "node node_modules/@xui/eax4tool/scripts/postinstall.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@xui/common": "^1.0.0",
"@xui/eax4tool": "^1.0.1",
"@xui/xbuild": "^1.0.4",
"zod": "^3.25.76"
},
"devDependencies": {
"tsx": "^4.20.5",
"typescript": "^5"
}
}

871
conf/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,871 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@xui/common':
specifier: ^1.0.0
version: 1.0.0
'@xui/eax4tool':
specifier: ^1.0.1
version: 1.0.1
'@xui/xbuild':
specifier: ^1.0.4
version: 1.0.4
zod:
specifier: ^3.25.76
version: 3.25.76
devDependencies:
tsx:
specifier: ^4.20.5
version: 4.20.6
typescript:
specifier: ^5
version: 5.9.3
packages:
'@esbuild/aix-ppc64@0.25.12':
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.25.12':
resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.25.12':
resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.25.12':
resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.25.12':
resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.25.12':
resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.25.12':
resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.25.12':
resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.25.12':
resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.25.12':
resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.25.12':
resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.25.12':
resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.25.12':
resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.25.12':
resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.25.12':
resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.25.12':
resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.25.12':
resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.25.12':
resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.25.12':
resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.25.12':
resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.25.12':
resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.25.12':
resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.25.12':
resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.25.12':
resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.25.12':
resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.25.12':
resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@isaacs/balanced-match@4.0.1':
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
engines: {node: 20 || >=22}
'@isaacs/brace-expansion@5.0.0':
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
engines: {node: 20 || >=22}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
'@xui/common@1.0.0':
resolution: {integrity: sha512-3oCDEKvf/Y6toXnNkW+JHBLcT6FhK6t3iSiSYBchSNvbl0zjVKvBl3dlWjxP3SjVt19m75QE+SRK2Du0fl+2QA==, tarball: https://gitea.reactgo.cn/api/packages/anyone/npm/%40xui%2Fcommon/-/1.0.0/common-1.0.0.tgz}
'@xui/eax4tool@1.0.1':
resolution: {integrity: sha512-3KDSZnUCgDgycwkMLnD47aRzORJP7D+5D7XVKhSS7Y8fWqsONVNJPjmkui4ZBUUw74JlsIczcXv5tK1HtoLSZw==, tarball: https://gitea.reactgo.cn/api/packages/anyone/npm/%40xui%2Feax4tool/-/1.0.1/eax4tool-1.0.1.tgz}
hasBin: true
'@xui/xbuild@1.0.4':
resolution: {integrity: sha512-NO1VYEIgMesZ+mVtYJ0B4SohqCwpD95c1VKqks5XaZvwMZ+KlLz6BokKkpjjF42AtA0n7F3+yinK58pHbD71eA==, tarball: https://gitea.reactgo.cn/api/packages/anyone/npm/%40xui%2Fxbuild/-/1.0.4/xbuild-1.0.4.tgz}
hasBin: true
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
axios@1.13.2:
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
commander@14.0.2:
resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==}
engines: {node: '>=20'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
dotenv@16.6.1:
resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
engines: {node: '>=12'}
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
es-object-atoms@1.1.1:
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
engines: {node: '>= 0.4'}
es-set-tostringtag@2.1.0:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
esbuild@0.25.12:
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
engines: {node: '>=18'}
hasBin: true
follow-redirects@1.15.11:
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
foreground-child@3.3.1:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
form-data@4.0.4:
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
engines: {node: '>= 6'}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
get-tsconfig@4.13.0:
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
glob@11.0.3:
resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==}
engines: {node: 20 || >=22}
hasBin: true
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
has-tostringtag@1.0.2:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
jackspeak@4.1.1:
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
engines: {node: 20 || >=22}
json-schema-to-zod@2.6.1:
resolution: {integrity: sha512-uiHmWH21h9FjKJkRBntfVGTLpYlCZ1n98D0izIlByqQLqpmkQpNTBtfbdP04Na6+43lgsvrShFh2uWLkQDKJuQ==}
hasBin: true
lru-cache@11.2.2:
resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==}
engines: {node: 20 || >=22}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
minimatch@10.1.1:
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
engines: {node: 20 || >=22}
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
mustache@4.2.0:
resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
hasBin: true
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-scurry@2.0.1:
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
engines: {node: 20 || >=22}
prettier@3.6.2:
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
engines: {node: '>=14'}
hasBin: true
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.1.2:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
tsx@4.20.6:
resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==}
engines: {node: '>=18.0.0'}
hasBin: true
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
uuid@13.0.0:
resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==}
hasBin: true
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
zod-to-json-schema@3.24.6:
resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==}
peerDependencies:
zod: ^3.24.1
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
snapshots:
'@esbuild/aix-ppc64@0.25.12':
optional: true
'@esbuild/android-arm64@0.25.12':
optional: true
'@esbuild/android-arm@0.25.12':
optional: true
'@esbuild/android-x64@0.25.12':
optional: true
'@esbuild/darwin-arm64@0.25.12':
optional: true
'@esbuild/darwin-x64@0.25.12':
optional: true
'@esbuild/freebsd-arm64@0.25.12':
optional: true
'@esbuild/freebsd-x64@0.25.12':
optional: true
'@esbuild/linux-arm64@0.25.12':
optional: true
'@esbuild/linux-arm@0.25.12':
optional: true
'@esbuild/linux-ia32@0.25.12':
optional: true
'@esbuild/linux-loong64@0.25.12':
optional: true
'@esbuild/linux-mips64el@0.25.12':
optional: true
'@esbuild/linux-ppc64@0.25.12':
optional: true
'@esbuild/linux-riscv64@0.25.12':
optional: true
'@esbuild/linux-s390x@0.25.12':
optional: true
'@esbuild/linux-x64@0.25.12':
optional: true
'@esbuild/netbsd-arm64@0.25.12':
optional: true
'@esbuild/netbsd-x64@0.25.12':
optional: true
'@esbuild/openbsd-arm64@0.25.12':
optional: true
'@esbuild/openbsd-x64@0.25.12':
optional: true
'@esbuild/openharmony-arm64@0.25.12':
optional: true
'@esbuild/sunos-x64@0.25.12':
optional: true
'@esbuild/win32-arm64@0.25.12':
optional: true
'@esbuild/win32-ia32@0.25.12':
optional: true
'@esbuild/win32-x64@0.25.12':
optional: true
'@isaacs/balanced-match@4.0.1': {}
'@isaacs/brace-expansion@5.0.0':
dependencies:
'@isaacs/balanced-match': 4.0.1
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
strip-ansi: 7.1.2
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
'@xui/common@1.0.0':
dependencies:
zod: 3.25.76
zod-to-json-schema: 3.24.6(zod@3.25.76)
'@xui/eax4tool@1.0.1': {}
'@xui/xbuild@1.0.4':
dependencies:
'@xui/common': 1.0.0
'@xui/eax4tool': 1.0.1
axios: 1.13.2
commander: 14.0.2
dotenv: 16.6.1
esbuild: 0.25.12
glob: 11.0.3
json-schema-to-zod: 2.6.1
mustache: 4.2.0
prettier: 3.6.2
uuid: 13.0.0
zod: 3.25.76
transitivePeerDependencies:
- debug
ansi-regex@5.0.1: {}
ansi-regex@6.2.2: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansi-styles@6.2.3: {}
asynckit@0.4.0: {}
axios@1.13.2:
dependencies:
follow-redirects: 1.15.11
form-data: 4.0.4
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
commander@14.0.2: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
delayed-stream@1.0.0: {}
dotenv@16.6.1: {}
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
es-object-atoms@1.1.1:
dependencies:
es-errors: 1.3.0
es-set-tostringtag@2.1.0:
dependencies:
es-errors: 1.3.0
get-intrinsic: 1.3.0
has-tostringtag: 1.0.2
hasown: 2.0.2
esbuild@0.25.12:
optionalDependencies:
'@esbuild/aix-ppc64': 0.25.12
'@esbuild/android-arm': 0.25.12
'@esbuild/android-arm64': 0.25.12
'@esbuild/android-x64': 0.25.12
'@esbuild/darwin-arm64': 0.25.12
'@esbuild/darwin-x64': 0.25.12
'@esbuild/freebsd-arm64': 0.25.12
'@esbuild/freebsd-x64': 0.25.12
'@esbuild/linux-arm': 0.25.12
'@esbuild/linux-arm64': 0.25.12
'@esbuild/linux-ia32': 0.25.12
'@esbuild/linux-loong64': 0.25.12
'@esbuild/linux-mips64el': 0.25.12
'@esbuild/linux-ppc64': 0.25.12
'@esbuild/linux-riscv64': 0.25.12
'@esbuild/linux-s390x': 0.25.12
'@esbuild/linux-x64': 0.25.12
'@esbuild/netbsd-arm64': 0.25.12
'@esbuild/netbsd-x64': 0.25.12
'@esbuild/openbsd-arm64': 0.25.12
'@esbuild/openbsd-x64': 0.25.12
'@esbuild/openharmony-arm64': 0.25.12
'@esbuild/sunos-x64': 0.25.12
'@esbuild/win32-arm64': 0.25.12
'@esbuild/win32-ia32': 0.25.12
'@esbuild/win32-x64': 0.25.12
follow-redirects@1.15.11: {}
foreground-child@3.3.1:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
form-data@4.0.4:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
es-set-tostringtag: 2.1.0
hasown: 2.0.2
mime-types: 2.1.35
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
es-object-atoms: 1.1.1
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
hasown: 2.0.2
math-intrinsics: 1.1.0
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
get-tsconfig@4.13.0:
dependencies:
resolve-pkg-maps: 1.0.0
glob@11.0.3:
dependencies:
foreground-child: 3.3.1
jackspeak: 4.1.1
minimatch: 10.1.1
minipass: 7.1.2
package-json-from-dist: 1.0.1
path-scurry: 2.0.1
gopd@1.2.0: {}
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
dependencies:
has-symbols: 1.1.0
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
is-fullwidth-code-point@3.0.0: {}
isexe@2.0.0: {}
jackspeak@4.1.1:
dependencies:
'@isaacs/cliui': 8.0.2
json-schema-to-zod@2.6.1: {}
lru-cache@11.2.2: {}
math-intrinsics@1.1.0: {}
mime-db@1.52.0: {}
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
minimatch@10.1.1:
dependencies:
'@isaacs/brace-expansion': 5.0.0
minipass@7.1.2: {}
mustache@4.2.0: {}
package-json-from-dist@1.0.1: {}
path-key@3.1.1: {}
path-scurry@2.0.1:
dependencies:
lru-cache: 11.2.2
minipass: 7.1.2
prettier@3.6.2: {}
proxy-from-env@1.1.0: {}
resolve-pkg-maps@1.0.0: {}
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
shebang-regex@3.0.0: {}
signal-exit@4.1.0: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string-width@5.1.2:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.1.2
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-ansi@7.1.2:
dependencies:
ansi-regex: 6.2.2
tsx@4.20.6:
dependencies:
esbuild: 0.25.12
get-tsconfig: 4.13.0
optionalDependencies:
fsevents: 2.3.3
typescript@5.9.3: {}
uuid@13.0.0: {}
which@2.0.2:
dependencies:
isexe: 2.0.0
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@8.1.0:
dependencies:
ansi-styles: 6.2.3
string-width: 5.1.2
strip-ansi: 7.1.2
zod-to-json-schema@3.24.6(zod@3.25.76):
dependencies:
zod: 3.25.76
zod@3.25.76: {}

3
conf/pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,3 @@
ignoredBuiltDependencies:
- '@xui/eax4tool'
- esbuild

View File

@@ -0,0 +1,29 @@
import { createWorkflowChain, andThen } from '@xui/xbuild'
import z from 'zod'
import { exampleService } from '../beans/exampleService'
const example1 = createWorkflowChain({
id: 'example1',
name: 'Example1 Workflow',
description: '一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。',
input: z.object({ name: z.string() }),
result: z.object({ greeting: z.string() }),
})
.andTask({
id: 'processServiceTask',
task: exampleService.processServiceTask,
execute: ({ data }) => {
return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` }
},
})
.andThen({
id: 'final',
execute: ({ data , getStepResult}) => {
const result = getStepResult('processServiceTask')
console.log('result', result)
return { greeting: `status=${data.status} mesasge=${data.message} !` }
},
})
.toWorkflow()
export default example1

View File

@@ -0,0 +1,43 @@
import { createWorkflowChain, andThen } from '@xui/xbuild'
import z from 'zod'
import { exampleService } from '../beans/exampleService'
const example2 = createWorkflowChain({
id: 'example2',
name: 'Example2 Workflow',
description: '一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。',
input: z.object({ name: z.string() }),
result: z.object({ greeting: z.string() }),
})
.andWhen({
id: "conditional",
condition: ({ data }) => data.name === 'wk',
step: andThen({
id: 'isConditionalThen',
// task: exampleService.processOutboundTask,
execute: ({ data }) => {
return { taskName: '获取用户信息', description: 'TODO: 外呼, 获取用户详细信息' }
},
}),
})
.andTask({
id: 'processServiceTask',
task: exampleService.processServiceTask,
execute: ({ data }) => {
if ('taskName' in data) {
return { taskName: data.taskName, description: data.description }
}
return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` }
},
})
.andThen({
id: 'final',
execute: ({ data, getStepResult }) => {
const result = getStepResult('processServiceTask')
console.log('result', result)
return { greeting: `status=${data.status} mesasge=${data.message} !` }
},
})
.toWorkflow()
export default example2

View File

@@ -0,0 +1,2 @@
import workflow from '../flows/example1'
await workflow.runTest({ name: 'wk' }, { verbose: true })

View File

@@ -0,0 +1,10 @@
import fs from 'fs'
import workflow from '../flows/example2'
import { XBUILD_DIR } from '@xui/xbuild'
const element = workflow.buildElement()
// console.log(JSON.stringify(element, null, 2))
// write json to file example1.json
const filePath = `${XBUILD_DIR}/cache/${element.id}.json`
fs.writeFileSync(filePath, JSON.stringify(element, null, 2))
console.log(`Written to ${filePath}`)

19
conf/tsconfig.json Normal file
View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "build"]
}

106
pom.xml Normal file
View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 使用 Spring Boot 官方父 POM它提供了默认配置和依赖管理 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tienon</groupId>
<artifactId>example-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<spring-boot.version>3.4.7</spring-boot.version>
<mybatis-plus.version>3.5.14</mybatis-plus.version>
<slf4j.version>2.0.7</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.tienon.eax</groupId>
<artifactId>eax4core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring Boot Web 启动器,包含 Web 开发所需的核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Jakarta Bean Validation support (e.g., @NotNull, @Min) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- MyBatis-Plus 启动器,简化数据库操作 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- MySQL 连接驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope> <!-- 运行时依赖 -->
</dependency>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Lombok 库,用于简化 Java 代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope> <!-- 编译时提供,不需要打包到最终 JAR 中 -->
<!-- <version>${lombok.version}</version> --> <!-- 通常由父 POM 管理 -->
</dependency>
</dependencies>
<!-- my gitea repository -->
<repositories>
<repository>
<id>gitea</id>
<url>https://gitea.reactgo.cn/api/packages/anyone/maven</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<!-- <executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions> -->
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,91 @@
package com.tienon.eax.example;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import com.tienon.eax.spring.EaxSpringConfig;
@SpringBootApplication(scanBasePackages = {
// "com.tienon.eax.example",
})
@Import({EaxSpringConfig.class,
// BaseMybatisPlusConfig.class
})
public class ExApp {
// public static void main(String[] args) {
// SpringApplication.run(ExApp.class, args);
// }
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(ExApp.class, args);
printControllerUrls(ctx);
}
private static void printControllerUrls(ConfigurableApplicationContext ctx) {
// 打印全部的Controller url
try {
RequestMappingHandlerMapping mapping = ctx.getBean(RequestMappingHandlerMapping.class);
List<String> urlInfos = new ArrayList<>();
mapping.getHandlerMethods().forEach((info, method) -> {
String m = info.getMethodsCondition().isEmpty()
? "[*]"
: info.getMethodsCondition().getMethods().toString();
String httpMethods = String.format("%-6s", m);
PathPatternsRequestCondition pathPatterns = info.getPathPatternsCondition();
if (pathPatterns != null && !pathPatterns.getPatternValues().isEmpty()) {
pathPatterns.getPatternValues().forEach(p -> {
String urlInfo = httpMethods + " " + p + " -> "
+ method.getMethod().getDeclaringClass().getSimpleName()
+ "#" + method.getMethod().getName();
urlInfos.add(urlInfo);
});
} else {
PatternsRequestCondition patterns = info.getPatternsCondition();
if (patterns != null && !patterns.getPatterns().isEmpty()) {
patterns.getPatterns().forEach(p -> {
String urlInfo = httpMethods + " " + p + " -> "
+ method.getMethod().getDeclaringClass().getSimpleName()
+ "#" + method.getMethod().getName();
urlInfos.add(urlInfo);
});
}
}
});
// 按 URI 路径排序
urlInfos.sort(Comparator.comparing(s -> {
// [GET] /admin/bean/search -> AdminController#beanSearch
// 提取 URI 路径部分(在 " -> " 之前的部分)
int arrowIndex = s.indexOf(" -> ");
if (arrowIndex > 0) {
String beforeArrow = s.substring(0, arrowIndex);
// 提取路径部分(在 HTTP 方法之后)
int spaceIndex = beforeArrow.indexOf(' ');
if (spaceIndex > 0) {
String uri = beforeArrow.substring(spaceIndex + 1);
return uri.trim();
}
}
return s;
}));
// 打印排序后的结果
urlInfos.forEach(System.out::println);
} catch (Exception e) {
System.out.println("[INFO] 无法打印 Controller URL可能未启用 WebMVC 或未注册映射:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,92 @@
package com.tienon.eax.example.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tienon.eax.ebp.EbpEngine;
import com.tienon.eax.internal.pvm.definition.ProcessDefinitionImpl;
import com.tienon.eax.tool.ExtractSchema;
import com.tienon.eax.tool.ExtractorTool;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Builder;
import lombok.Data;
@RestController
@RequestMapping("/console")
public class ConsoleController {
@Autowired
private EbpEngine engine;
@Data
public static class Input {
@NotEmpty(message = "流程定义 flows is required")
private String[] process;
}
@Data
@Builder
public static class Output {
private String[] ids;
}
@PostMapping("/deploy")
public ResponseEntity<Output> deploy(@Valid @RequestBody Input input) {
var deploymentCache = engine.getConfig().getDeploymentCache();
List<String> processIds = new ArrayList<>();
for (String process : input.getProcess()) {
ProcessDefinitionImpl def = deploymentCache.parseProcess(process);
processIds.add(def.getId());
}
return ResponseEntity.ok(new Output(processIds.toArray(new String[0])));
}
@Data
public static class ExecuteInput {
@NotBlank(message = "流程定义 ID key is required")
private String key;
private Map<String, Object> variables;
}
@PostMapping("/run")
public ResponseEntity<Object> execute(@Valid @RequestBody ExecuteInput input) {
Object output = engine.run(input.getKey(), input.getVariables());
return ResponseEntity.ok(output);
}
@Data
@Builder
public static class ExtractInput {
@NotBlank(message = "类路径或者jar文件名 classPath is required")
private String classPath;
@NotBlank(message = "基础包名或者类名 basePackage is required")
private String basePackage;
}
/**
* 调试信息
*/
@GetMapping("/info")
public ResponseEntity<Object> extract() {
try {
Object result = engine.getConfig().getDeploymentCache().toDebugString();
return ResponseEntity.ok(result);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,13 @@
package com.tienon.eax.example.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot 3.4.7!";
}
}

View File

@@ -0,0 +1,12 @@
package com.tienon.eax.example.service;
import com.tienon.eax.annotation.ServiceKind;
import com.tienon.eax.annotation.Kind;
@ServiceKind({
@Kind(kind = "group1", name = "分组1", description = "分组1的描述"),
@Kind(kind = "group2", name = "分组2", description = "分组2的描述")
})
public class ExampleKind {
}

View File

@@ -0,0 +1,83 @@
package com.tienon.eax.example.service;
import org.springframework.stereotype.Service;
import com.tienon.eax.annotation.ServiceComponent;
import com.tienon.eax.annotation.ServiceMethod;
import com.tienon.eax.annotation.ServiceType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* 演示如何使用枚举类型的 ServiceMethod 注解
*
* @author wukun
*/
@Slf4j
@Service
@ServiceComponent(name = "枚举示例服务", description = "演示如何使用枚举类型的ServiceMethod注解", taskType = ServiceType.serviceTask)
public class ExampleService {
@Data
public static class TaskRequest {
@Size(min = 2, max = 10, message = "name 长度必须在 2-10 之间")
private String taskName;
@NotEmpty(message = "description 不能为空")
private String description;
}
@Data
public static class TaskResponse {
@NotBlank(message = "taskId 不能为空")
private String taskId;
@NotEmpty(message = "status 不能为空")
private String status;
private String message;
}
/**
* 服务任务示例 - 使用默认的 SERVICE_TASK 类型
*/
@ServiceMethod(name = "处理服务任务", description = "处理服务任务的示例方法")
public TaskResponse processServiceTask(TaskRequest request) {
log.info("处理服务任务: {}", request.getTaskName());
TaskResponse response = new TaskResponse();
response.setTaskId("service-" + System.currentTimeMillis());
response.setStatus("completed");
response.setMessage("服务任务处理完成");
return response;
}
/**
* 出站任务示例 - 显式指定 OUTBOUND_TASK 类型
*/
@ServiceMethod(name = "处理出站任务", description = "处理出站任务的示例方法")
public TaskResponse processOutboundTask(TaskRequest request) {
log.info("处理出站任务: {}", request.getTaskName());
TaskResponse response = new TaskResponse();
response.setTaskId("outbound-" + System.currentTimeMillis());
response.setStatus("completed");
response.setMessage("出站任务处理完成");
return response;
}
/**
* 作业任务示例 - 显式指定 JOB_TASK 类型
*/
@ServiceMethod(name = "处理作业任务", description = "处理作业任务的示例方法")
public TaskResponse processJobTask(TaskRequest request) {
log.info("处理作业任务: {}", request.getTaskName());
TaskResponse response = new TaskResponse();
response.setTaskId("job-" + System.currentTimeMillis());
response.setStatus("completed");
response.setMessage("作业任务处理完成");
return response;
}
}

View File

@@ -0,0 +1,47 @@
package com.tienon.eax.example.service;
import com.tienon.eax.annotation.ServiceMethod;
import com.tienon.eax.annotation.ServiceType;
import com.tienon.eax.annotation.ServiceComponent;
import org.springframework.stereotype.Service;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* 作业任务服务示例
*
* @author wukun
*/
@Slf4j
@Service
@ServiceComponent(name = "作业任务服务", description = "处理作业任务的示例服务", taskType = ServiceType.jobTask)
public class JobTaskService {
@Data
public static class JobRequest {
private String jobName;
private String parameters;
}
@Data
public static class JobResponse {
private String jobId;
private String status;
private String result;
}
/**
* 执行批处理作业
*/
@ServiceMethod(name = "执行批处理作业", description = "执行批处理作业任务")
public JobResponse executeBatchJob(JobRequest request) {
log.info("执行批处理作业: {}, 参数: {}", request.getJobName(), request.getParameters());
JobResponse response = new JobResponse();
response.setJobId("job-" + System.currentTimeMillis());
response.setStatus("completed");
response.setResult("批处理作业 " + request.getJobName() + " 执行完成");
return response;
}
}

View File

@@ -0,0 +1,45 @@
package com.tienon.eax.example.service;
import com.tienon.eax.annotation.ServiceMethod;
import com.tienon.eax.annotation.ServiceType;
import com.tienon.eax.annotation.ServiceComponent;
import org.springframework.stereotype.Service;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* 出站任务服务示例
*
* @author wukun
*/
@Slf4j
@Service
@ServiceComponent(name = "出站任务服务", description = "处理出站任务的示例服务", taskType = ServiceType.outboundTask)
public class OutboundTaskService {
@Data
public static class OutboundRequest {
private String target;
private String message;
}
@Data
public static class OutboundResponse {
private String status;
private String result;
}
/**
* 发送消息到外部系统
*/
@ServiceMethod(name = "发送消息", description = "向外部系统发送消息")
public OutboundResponse sendMessage(OutboundRequest request) {
log.info("发送消息到: {}, 内容: {}", request.getTarget(), request.getMessage());
OutboundResponse response = new OutboundResponse();
response.setStatus("sent");
response.setResult("消息已发送到 " + request.getTarget());
return response;
}
}

View File

@@ -0,0 +1,28 @@
# 设置日志级别为 debug
logging.level.root=INFO
logging.level.com.tienon.eax=DEBUG
# 控制台日志格式(彩色)
logging.pattern.console=%clr(%d{HH:mm:ss.SSS}){faint} %clr([%15.15thread]){faint} %clr(%-5level) %clr(---){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx
# # 文件日志配置(可选)
# logging.file.name=logs/application.log
# logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
# SHOW VARIABLES LIKE '%time_zone%'; system_time_zone = UTC
spring.datasource.url=jdbc:mysql://124.220.20.177:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=your_strong_password
# spring.datasource.url=jdbc:p6spy:mysql://124.220.20.177:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
# spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
# MyBatis Plus
mybatis-plus.mapper-locations=classpath:mybatis/*.xml
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.mapperPackage=com.tienon.eax.boot.mapper
# mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

View File

@@ -0,0 +1,24 @@
{
"flows": [
{
"id": "example2",
"kind": "default",
"name": "Example2 Workflow",
"description": "一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。",
"pos": "",
"content": "{\"id\":\"example2\",\"name\":\"Example2 Workflow\",\"description\":\"一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"}},\"required\":[\"name\"],\"additionalProperties\":false},\"outputSchema\":{\"type\":\"object\",\"properties\":{\"greeting\":{\"type\":\"string\"}},\"required\":[\"greeting\"],\"additionalProperties\":false},\"elements\":[{\"id\":\"conditional\",\"stepType\":\"conditional-when\",\"taskType\":\"scriptTask\",\"mapping\":\"({ data }) => {\\n return { taskName: \\\"\\\\u83B7\\\\u53D6\\\\u7528\\\\u6237\\\\u4FE1\\\\u606F\\\", description: \\\"TODO: \\\\u5916\\\\u547C, \\\\u83B7\\\\u53D6\\\\u7528\\\\u6237\\\\u8BE6\\\\u7EC6\\\\u4FE1\\\\u606F\\\" };\\n};\\n\",\"condition\":\"({ data }) => data.name === \\\"wk\\\";\\n\"},{\"id\":\"processServiceTask\",\"stepType\":\"func\",\"taskType\":\"serviceTask\",\"name\":\"处理服务任务\",\"description\":\"处理服务任务的示例方法\",\"bean\":\"exampleService\",\"method\":\"processServiceTask\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\",\"minLength\":1,\"description\":\"description 不能为空\"},\"taskName\":{\"type\":\"string\",\"minLength\":2,\"maxLength\":10,\"description\":\"name 长度必须在 2-10 之间\"}},\"required\":[\"description\"],\"additionalProperties\":false},\"outputSchema\":{\"type\":\"object\",\"properties\":{\"message\":{\"type\":\"string\"},\"status\":{\"type\":\"string\",\"minLength\":1,\"description\":\"status 不能为空\"},\"taskId\":{\"type\":\"string\",\"minLength\":1,\"description\":\"taskId 不能为空\"}},\"required\":[\"status\",\"taskId\"],\"additionalProperties\":false},\"mapping\":\"({ data }) => {\\n if (\\\"taskName\\\" in data) {\\n return { taskName: data.taskName, description: data.description };\\n }\\n return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` };\\n};\\n\"},{\"id\":\"final\",\"stepType\":\"func\",\"taskType\":\"scriptTask\",\"name\":\"\",\"description\":\"\",\"mapping\":\"({ data, getStepResult }) => {\\n const result = getStepResult(\\\"processServiceTask\\\");\\n console.log(\\\"result\\\", result);\\n return { greeting: `status=${data.status} mesasge=${data.message} !` };\\n};\\n\"}]}",
"code": "import { createWorkflowChain, andThen } from '@xui/xbuild'\nimport z from 'zod'\nimport { exampleService } from '../beans/exampleService'\n\nconst example2 = createWorkflowChain({\n id: 'example2',\n name: 'Example2 Workflow',\n description: '一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。',\n input: z.object({ name: z.string() }),\n result: z.object({ greeting: z.string() }),\n})\n .andWhen({\n id: \"conditional\",\n condition: ({ data }) => data.name === 'wk',\n step: andThen({\n id: 'isConditionalThen',\n // task: exampleService.processOutboundTask,\n execute: ({ data }) => {\n return { taskName: '获取用户信息', description: 'TODO: 外呼, 获取用户详细信息' }\n },\n }),\n })\n .andTask({\n id: 'processServiceTask',\n task: exampleService.processServiceTask,\n execute: ({ data }) => {\n if ('taskName' in data) {\n return { taskName: data.taskName, description: data.description }\n }\n return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` }\n },\n })\n .andThen({\n id: 'final',\n execute: ({ data, getStepResult }) => {\n const result = getStepResult('processServiceTask')\n console.log('result', result)\n return { greeting: `status=${data.status} mesasge=${data.message} !` }\n },\n })\n .toWorkflow()\n\nexport default example2\n",
"file": "example2.ts"
},
{
"id": "example1",
"kind": "default",
"name": "Example1 Workflow",
"description": "一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。",
"pos": "",
"content": "{\"id\":\"example1\",\"name\":\"Example1 Workflow\",\"description\":\"一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"}},\"required\":[\"name\"],\"additionalProperties\":false},\"outputSchema\":{\"type\":\"object\",\"properties\":{\"greeting\":{\"type\":\"string\"}},\"required\":[\"greeting\"],\"additionalProperties\":false},\"elements\":[{\"id\":\"processServiceTask\",\"stepType\":\"func\",\"taskType\":\"serviceTask\",\"name\":\"处理服务任务\",\"description\":\"处理服务任务的示例方法\",\"bean\":\"exampleService\",\"method\":\"processServiceTask\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"description\":{\"type\":\"string\",\"minLength\":1,\"description\":\"description 不能为空\"},\"taskName\":{\"type\":\"string\",\"minLength\":2,\"maxLength\":10,\"description\":\"name 长度必须在 2-10 之间\"}},\"required\":[\"description\"],\"additionalProperties\":false},\"outputSchema\":{\"type\":\"object\",\"properties\":{\"message\":{\"type\":\"string\"},\"status\":{\"type\":\"string\",\"minLength\":1,\"description\":\"status 不能为空\"},\"taskId\":{\"type\":\"string\",\"minLength\":1,\"description\":\"taskId 不能为空\"}},\"required\":[\"status\",\"taskId\"],\"additionalProperties\":false},\"mapping\":\"({ data }) => {\\n return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` };\\n};\\n\"},{\"id\":\"final\",\"stepType\":\"func\",\"taskType\":\"scriptTask\",\"name\":\"\",\"description\":\"\",\"mapping\":\"({ data, getStepResult }) => {\\n const result = getStepResult(\\\"processServiceTask\\\");\\n console.log(\\\"result\\\", result);\\n return { greeting: `status=${data.status} mesasge=${data.message} !` };\\n};\\n\"}]}",
"code": "import { createWorkflowChain, andThen } from '@xui/xbuild'\nimport z from 'zod'\nimport { exampleService } from '../beans/exampleService'\n\nconst example1 = createWorkflowChain({\n id: 'example1',\n name: 'Example1 Workflow',\n description: '一个简单的示例工作流,用于调用 exampleService 的 processServiceTask 方法。',\n input: z.object({ name: z.string() }),\n result: z.object({ greeting: z.string() }),\n})\n .andTask({\n id: 'processServiceTask',\n task: exampleService.processServiceTask,\n execute: ({ data }) => {\n return { taskName: `Hello, ${data.name}!`, description: `Hello, ${data.name}!` }\n },\n })\n .andThen({\n id: 'final',\n execute: ({ data , getStepResult}) => {\n const result = getStepResult('processServiceTask')\n console.log('result', result)\n return { greeting: `status=${data.status} mesasge=${data.message} !` }\n },\n })\n .toWorkflow()\n\nexport default example1\n",
"file": "example1.ts"
}
]
}