@gadmin2n/schematics 0.0.72 → 0.0.74

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.
Files changed (173) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/job.prisma +62 -0
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +0 -21
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +171 -0
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +60 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +1 -1
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +62 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +62 -0
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +62 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +5 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -4
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +14 -7
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +4 -0
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +49 -3
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +746 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +786 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +6 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +79 -0
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +20 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.ts +145 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.module.ts +10 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/{canvas/canvas.service.spec.ts → agendaJob/agendaJob.service.spec.ts} +71 -65
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.service.ts +83 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.module.ts +9 -0
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +100 -0
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -0
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +43 -0
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +317 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +16 -0
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.service.ts +13 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +220 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +82 -0
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +16 -0
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +505 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +22 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +147 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +10 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +356 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +110 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +22 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +216 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.module.ts +10 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +356 -0
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +168 -0
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +22 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +199 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.module.ts +10 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +348 -0
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.ts +106 -0
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +579 -1082
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +278 -0
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +5 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +25 -0
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +13 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +87 -0
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +7 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +122 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +4285 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +28 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/code-execute.test.ts +44 -0
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/http-request.test.ts +87 -0
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/helpers.test.ts +225 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/node-type-consistency.test.ts +101 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +51 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +85 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +35 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +54 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +6 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +62 -0
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +47 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +13 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +101 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +58 -0
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +184 -0
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +133 -0
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +57 -0
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +77 -0
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +36 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +226 -0
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +411 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +19 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +8 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +1905 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package-lock.json +17555 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +5 -2
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +1 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +5 -1
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +1 -1
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +63 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +91 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -2
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +43 -2
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +14 -9
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +14 -9
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +309 -56
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/show.tsx +1 -3
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/create.tsx +108 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/edit.tsx +124 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/index.tsx +4 -0
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +245 -0
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/show.tsx +70 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +0 -1
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +160 -2
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +120 -148
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +74 -181
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +15 -13
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +2 -2
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +338 -3
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +18 -17
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +10 -4
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +10 -4
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/{ChartViewerConfigModal.tsx → MultiChartConfigModal.tsx} +30 -18
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/MultiChartDataSourceModal.tsx +427 -0
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +10 -4
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +6 -14
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +10 -4
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +10 -4
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/canvasModalProps.ts +24 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +45 -63
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +99 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExportModal.tsx +87 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +322 -0
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ImportModal.tsx +175 -0
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeEditModal.tsx +60 -0
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +1150 -0
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +101 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +198 -0
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +81 -0
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +566 -0
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +224 -0
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +524 -0
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +343 -0
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +243 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +363 -0
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/DynamicConfigForm.tsx +154 -0
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +176 -0
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +77 -0
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +112 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +305 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +282 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +469 -0
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +92 -0
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +111 -0
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +127 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +4 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +254 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +74 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1501 -1199
  151. package/package.json +1 -1
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.spec.ts +0 -22
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +0 -896
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +0 -219
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +0 -159
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +0 -192
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +0 -1034
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +0 -8
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +0 -509
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +0 -66
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +0 -552
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +0 -263
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +0 -35
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +0 -207
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +0 -382
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +0 -135
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +0 -53
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +0 -8
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +0 -1
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +0 -31
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +0 -9
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +0 -39349
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/metric-info-tooltip/index.tsx +0 -19
@@ -0,0 +1,54 @@
1
+ import axios, { AxiosRequestConfig } from 'axios';
2
+
3
+ export interface HttpRequestInput {
4
+ url: string;
5
+ method: string;
6
+ headers?: Record<string, string>;
7
+ body?: any;
8
+ timeout?: number;
9
+ authentication?: string;
10
+ followRedirects?: boolean;
11
+ responseFormat?: 'json' | 'text' | 'binary';
12
+ ignoreSslErrors?: boolean;
13
+ }
14
+
15
+ export interface HttpRequestOutput {
16
+ status: number;
17
+ data: any;
18
+ headers: Record<string, string>;
19
+ }
20
+
21
+ /**
22
+ * Execute an HTTP request activity.
23
+ */
24
+ export async function httpRequest(input: HttpRequestInput): Promise<HttpRequestOutput> {
25
+ const axiosConfig: AxiosRequestConfig = {
26
+ url: input.url,
27
+ method: input.method.toLowerCase() as any,
28
+ headers: input.headers || {},
29
+ timeout: input.timeout || 30000,
30
+ maxRedirects: input.followRedirects === false ? 0 : 5,
31
+ validateStatus: () => true, // Don't throw on non-2xx
32
+ };
33
+
34
+ if (input.body && ['post', 'put', 'patch'].includes(axiosConfig.method as string)) {
35
+ axiosConfig.data = input.body;
36
+ }
37
+
38
+ if (input.ignoreSslErrors) {
39
+ const https = await import('https');
40
+ axiosConfig.httpsAgent = new https.Agent({ rejectUnauthorized: false });
41
+ }
42
+
43
+ if (input.responseFormat === 'binary') {
44
+ axiosConfig.responseType = 'arraybuffer';
45
+ }
46
+
47
+ const response = await axios(axiosConfig);
48
+
49
+ return {
50
+ status: response.status,
51
+ data: response.data,
52
+ headers: response.headers as Record<string, string>,
53
+ };
54
+ }
@@ -0,0 +1,6 @@
1
+ export { httpRequest } from './http-request';
2
+ export { dbQuery } from './db-query';
3
+ export { dbExecute } from './db-execute';
4
+ export { sendNotification } from './send-notification';
5
+ export { codeExecute } from './code-execute';
6
+ export { reportNodeStatus, reportWorkflowStatus } from './reporting';
@@ -0,0 +1,62 @@
1
+ import { Pool } from 'pg';
2
+ import { config } from '../config';
3
+ import { ReportNodeStatusInput, ReportWorkflowStatusInput } from '../dsl/types';
4
+
5
+ const pool = new Pool({ connectionString: config.database.url });
6
+
7
+ /**
8
+ * Report a node's execution status to the database.
9
+ */
10
+ export async function reportNodeStatus(input: ReportNodeStatusInput): Promise<void> {
11
+ const { instanceId, nodeId, nodeType, nodeLabel, status, input: nodeInput, output, error } = input;
12
+
13
+ if (status === 'RUNNING') {
14
+ // Create or update node execution record with RUNNING status
15
+ await pool.query(
16
+ `INSERT INTO t_workflow_node_execution (instance_id, node_id, node_type, node_label, status, input, started_at, created_at, updated_at)
17
+ VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW(), NOW())
18
+ ON CONFLICT (instance_id, node_id) DO UPDATE SET
19
+ status = $5, input = $6, started_at = NOW(), updated_at = NOW()`,
20
+ [instanceId, nodeId, nodeType, nodeLabel || null, status, nodeInput ? JSON.stringify(nodeInput) : null],
21
+ );
22
+ } else {
23
+ // Update with final status
24
+ await pool.query(
25
+ `UPDATE t_workflow_node_execution
26
+ SET status = $1, output = $2, error = $3, finished_at = NOW(), updated_at = NOW()
27
+ WHERE instance_id = $4 AND node_id = $5`,
28
+ [status, output ? JSON.stringify(output) : null, error ? JSON.stringify(error) : null, instanceId, nodeId],
29
+ );
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Report overall workflow execution status.
35
+ */
36
+ export async function reportWorkflowStatus(input: ReportWorkflowStatusInput): Promise<void> {
37
+ const { instanceId, status, result } = input;
38
+
39
+ const updates: string[] = ['status = $1', 'updated_at = NOW()'];
40
+ const values: any[] = [status];
41
+ let paramIdx = 2;
42
+
43
+ if (status === 'RUNNING') {
44
+ updates.push(`started_at = NOW()`);
45
+ }
46
+
47
+ if (status === 'COMPLETED' || status === 'FAILED' || status === 'CANCELLED') {
48
+ updates.push(`finished_at = NOW()`);
49
+ }
50
+
51
+ if (result !== undefined) {
52
+ updates.push(`result = $${paramIdx}`);
53
+ values.push(JSON.stringify(result));
54
+ paramIdx++;
55
+ }
56
+
57
+ values.push(instanceId);
58
+ await pool.query(
59
+ `UPDATE t_workflow_instance SET ${updates.join(', ')} WHERE id = $${paramIdx}`,
60
+ values,
61
+ );
62
+ }
@@ -0,0 +1,47 @@
1
+ export interface SendNotificationInput {
2
+ channel: 'email' | 'slack' | 'webhook' | 'dingtalk' | 'wecom';
3
+ recipients: string[];
4
+ subject?: string;
5
+ message: string;
6
+ templateId?: string;
7
+ }
8
+
9
+ export interface SendNotificationOutput {
10
+ sent: boolean;
11
+ messageId: string;
12
+ }
13
+
14
+ /**
15
+ * Send a notification via the configured channel.
16
+ * Currently stubs — implement actual integrations as needed.
17
+ */
18
+ export async function sendNotification(input: SendNotificationInput): Promise<SendNotificationOutput> {
19
+ const { channel, recipients, subject, message } = input;
20
+
21
+ console.log(`[Notification] channel=${channel} recipients=${recipients.join(',')} subject=${subject || ''}`);
22
+ console.log(`[Notification] message: ${message}`);
23
+
24
+ // TODO: Implement actual notification channels
25
+ // For now, log and return success
26
+ switch (channel) {
27
+ case 'webhook': {
28
+ // For webhook channel, POST to each recipient URL
29
+ const axios = (await import('axios')).default;
30
+ for (const url of recipients) {
31
+ await axios.post(url, { subject, message });
32
+ }
33
+ break;
34
+ }
35
+ case 'email':
36
+ case 'slack':
37
+ case 'dingtalk':
38
+ case 'wecom':
39
+ // Stub: log only
40
+ break;
41
+ }
42
+
43
+ return {
44
+ sent: true,
45
+ messageId: `notif_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
46
+ };
47
+ }
@@ -0,0 +1,13 @@
1
+ import * as dotenv from 'dotenv';
2
+ dotenv.config();
3
+
4
+ export const config = {
5
+ temporal: {
6
+ address: process.env.TEMPORAL_ADDRESS || 'localhost:7233',
7
+ namespace: process.env.TEMPORAL_NAMESPACE || 'default',
8
+ taskQueue: process.env.TEMPORAL_TASK_QUEUE || 'workflow-execution',
9
+ },
10
+ database: {
11
+ url: process.env.DATABASE_URL || 'postgresql://kavenma:kavenma@127.0.0.1:5432/gadmin_demo?schema=public',
12
+ },
13
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Condition evaluation for if_else and switch nodes.
3
+ */
4
+
5
+ export interface ConditionRule {
6
+ field: string;
7
+ operator: string;
8
+ value: string;
9
+ }
10
+
11
+ /**
12
+ * Evaluate a single condition rule against a context value.
13
+ */
14
+ export function evaluateRule(fieldValue: any, operator: string, compareValue: string): boolean {
15
+ switch (operator) {
16
+ case 'equals':
17
+ case '==':
18
+ return String(fieldValue) === compareValue;
19
+ case 'notEquals':
20
+ case '!=':
21
+ return String(fieldValue) !== compareValue;
22
+ case 'contains':
23
+ return String(fieldValue).includes(compareValue);
24
+ case 'notContains':
25
+ return !String(fieldValue).includes(compareValue);
26
+ case 'startsWith':
27
+ return String(fieldValue).startsWith(compareValue);
28
+ case 'endsWith':
29
+ return String(fieldValue).endsWith(compareValue);
30
+ case 'greaterThan':
31
+ case '>':
32
+ return Number(fieldValue) > Number(compareValue);
33
+ case 'lessThan':
34
+ case '<':
35
+ return Number(fieldValue) < Number(compareValue);
36
+ case 'greaterThanOrEqual':
37
+ case '>=':
38
+ return Number(fieldValue) >= Number(compareValue);
39
+ case 'lessThanOrEqual':
40
+ case '<=':
41
+ return Number(fieldValue) <= Number(compareValue);
42
+ case 'isEmpty':
43
+ return fieldValue == null || fieldValue === '' || (Array.isArray(fieldValue) && fieldValue.length === 0);
44
+ case 'isNotEmpty':
45
+ return fieldValue != null && fieldValue !== '' && !(Array.isArray(fieldValue) && fieldValue.length === 0);
46
+ case 'regex':
47
+ try {
48
+ return new RegExp(compareValue).test(String(fieldValue));
49
+ } catch {
50
+ return false;
51
+ }
52
+ default:
53
+ return false;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Evaluate multiple condition rules with AND/OR combinator.
59
+ */
60
+ export function evaluateConditions(
61
+ conditions: ConditionRule[],
62
+ contextData: Record<string, any>,
63
+ combineOperation: 'AND' | 'OR' = 'AND',
64
+ ): boolean {
65
+ if (conditions.length === 0) return true;
66
+
67
+ const results = conditions.map((rule) => {
68
+ const fieldValue = getNestedValue(contextData, rule.field);
69
+ return evaluateRule(fieldValue, rule.operator, rule.value);
70
+ });
71
+
72
+ return combineOperation === 'AND'
73
+ ? results.every(Boolean)
74
+ : results.some(Boolean);
75
+ }
76
+
77
+ /**
78
+ * Evaluate a switch node — returns the matched case value or "default".
79
+ */
80
+ export function evaluateSwitch(
81
+ field: string,
82
+ cases: Array<{ value: string; label: string }>,
83
+ contextData: Record<string, any>,
84
+ ): string {
85
+ const fieldValue = String(getNestedValue(contextData, field) ?? '');
86
+ const matched = cases.find((c) => c.value === fieldValue);
87
+ return matched ? matched.value : 'default';
88
+ }
89
+
90
+ /**
91
+ * Get a nested value from an object using dot-notation path.
92
+ */
93
+ function getNestedValue(obj: Record<string, any>, path: string): any {
94
+ const parts = path.split('.');
95
+ let current: any = obj;
96
+ for (const part of parts) {
97
+ if (current == null) return undefined;
98
+ current = current[part];
99
+ }
100
+ return current;
101
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Workflow execution context — a shared data store that flows between nodes.
3
+ * Each node can read from context and write its output back.
4
+ */
5
+ export class ExecutionContext {
6
+ private data: Record<string, any>;
7
+
8
+ constructor(initialData: Record<string, any> = {}) {
9
+ this.data = { ...initialData };
10
+ }
11
+
12
+ /** Get a value by dot-notation path (e.g. "node1.data.email") */
13
+ get(path: string): any {
14
+ const parts = path.split('.');
15
+ let current: any = this.data;
16
+ for (const part of parts) {
17
+ if (current == null) return undefined;
18
+ current = current[part];
19
+ }
20
+ return current;
21
+ }
22
+
23
+ /** Set a value by key */
24
+ set(key: string, value: any): void {
25
+ this.data[key] = value;
26
+ }
27
+
28
+ /** Merge node output into context under the node's ID */
29
+ mergeNodeOutput(nodeId: string, output: Record<string, any>): void {
30
+ this.data[nodeId] = output;
31
+ }
32
+
33
+ /** Get the full context object */
34
+ toJSON(): Record<string, any> {
35
+ return { ...this.data };
36
+ }
37
+
38
+ /** Resolve template strings like "{{node1.data.email}}" within a value */
39
+ resolveTemplates(value: any): any {
40
+ if (typeof value === 'string') {
41
+ return value.replace(/\{\{(.+?)\}\}/g, (_, path) => {
42
+ const resolved = this.get(path.trim());
43
+ return resolved !== undefined ? String(resolved) : '';
44
+ });
45
+ }
46
+ if (Array.isArray(value)) {
47
+ return value.map((v) => this.resolveTemplates(v));
48
+ }
49
+ if (value && typeof value === 'object') {
50
+ const result: Record<string, any> = {};
51
+ for (const [k, v] of Object.entries(value)) {
52
+ result[k] = this.resolveTemplates(v);
53
+ }
54
+ return result;
55
+ }
56
+ return value;
57
+ }
58
+ }
@@ -0,0 +1,184 @@
1
+ import { DslNode, DslEdge, WorkflowDSL } from './types';
2
+
3
+ /**
4
+ * DAG representation of a workflow DSL.
5
+ * Provides topological ordering and graph traversal utilities.
6
+ */
7
+ export interface GraphNode {
8
+ node: DslNode;
9
+ inEdges: DslEdge[];
10
+ outEdges: DslEdge[];
11
+ }
12
+
13
+ export interface ExecutionLevel {
14
+ nodes: DslNode[];
15
+ }
16
+
17
+ /**
18
+ * Build a graph (adjacency list) from DSL nodes + edges.
19
+ */
20
+ export function buildGraph(dsl: WorkflowDSL): Map<string, GraphNode> {
21
+ const graph = new Map<string, GraphNode>();
22
+
23
+ for (const node of dsl.nodes) {
24
+ graph.set(node.id, { node, inEdges: [], outEdges: [] });
25
+ }
26
+
27
+ for (const edge of dsl.edges) {
28
+ const sourceNode = graph.get(edge.source);
29
+ const targetNode = graph.get(edge.target);
30
+ if (sourceNode) sourceNode.outEdges.push(edge);
31
+ if (targetNode) targetNode.inEdges.push(edge);
32
+ }
33
+
34
+ return graph;
35
+ }
36
+
37
+ /**
38
+ * Find trigger nodes (nodes with category-type starting with *_trigger or no incoming edges).
39
+ */
40
+ export function findTriggerNodes(dsl: WorkflowDSL): DslNode[] {
41
+ const graph = buildGraph(dsl);
42
+ const triggers: DslNode[] = [];
43
+
44
+ for (const [, gn] of graph) {
45
+ if (
46
+ gn.node.type.endsWith('_trigger') ||
47
+ gn.inEdges.length === 0
48
+ ) {
49
+ triggers.push(gn.node);
50
+ }
51
+ }
52
+
53
+ return triggers;
54
+ }
55
+
56
+ /**
57
+ * Get successor node IDs from a given node, optionally filtering by sourceHandle (for branches).
58
+ */
59
+ export function getSuccessors(
60
+ dsl: WorkflowDSL,
61
+ nodeId: string,
62
+ branchHandle?: string,
63
+ ): string[] {
64
+ return dsl.edges
65
+ .filter((e) => {
66
+ if (e.source !== nodeId) return false;
67
+ if (branchHandle !== undefined) return e.sourceHandle === branchHandle;
68
+ return true;
69
+ })
70
+ .map((e) => e.target);
71
+ }
72
+
73
+ /**
74
+ * Topological sort using Kahn's algorithm.
75
+ * Returns nodes in execution order. Nodes at the same "level" can be executed in parallel.
76
+ */
77
+ export function topologicalSort(dsl: WorkflowDSL, startNodeIds: string[]): ExecutionLevel[] {
78
+ const graph = buildGraph(dsl);
79
+ const levels: ExecutionLevel[] = [];
80
+
81
+ // Calculate in-degree (only count edges from nodes that are reachable from start)
82
+ const reachable = getReachableNodes(dsl, startNodeIds);
83
+ const inDegree = new Map<string, number>();
84
+
85
+ for (const id of reachable) {
86
+ inDegree.set(id, 0);
87
+ }
88
+
89
+ for (const edge of dsl.edges) {
90
+ if (reachable.has(edge.source) && reachable.has(edge.target)) {
91
+ inDegree.set(edge.target, (inDegree.get(edge.target) || 0) + 1);
92
+ }
93
+ }
94
+
95
+ // Start with provided start nodes (triggers already fired)
96
+ let currentLevel = startNodeIds.filter((id) => reachable.has(id));
97
+
98
+ while (currentLevel.length > 0) {
99
+ const levelNodes: DslNode[] = [];
100
+ const nextLevel: string[] = [];
101
+
102
+ for (const nodeId of currentLevel) {
103
+ const gn = graph.get(nodeId);
104
+ if (gn) levelNodes.push(gn.node);
105
+
106
+ // Decrease in-degree of successors
107
+ const successors = dsl.edges
108
+ .filter((e) => e.source === nodeId && reachable.has(e.target))
109
+ .map((e) => e.target);
110
+
111
+ for (const succ of successors) {
112
+ const deg = (inDegree.get(succ) || 0) - 1;
113
+ inDegree.set(succ, deg);
114
+ if (deg === 0) {
115
+ nextLevel.push(succ);
116
+ }
117
+ }
118
+ }
119
+
120
+ if (levelNodes.length > 0) {
121
+ levels.push({ nodes: levelNodes });
122
+ }
123
+
124
+ currentLevel = [...new Set(nextLevel)];
125
+ }
126
+
127
+ return levels;
128
+ }
129
+
130
+ /**
131
+ * Get all node IDs reachable from a set of start nodes via BFS.
132
+ */
133
+ export function getReachableNodes(dsl: WorkflowDSL, startNodeIds: string[]): Set<string> {
134
+ const visited = new Set<string>();
135
+ const queue = [...startNodeIds];
136
+
137
+ while (queue.length > 0) {
138
+ const current = queue.shift()!;
139
+ if (visited.has(current)) continue;
140
+ visited.add(current);
141
+
142
+ const successors = dsl.edges
143
+ .filter((e) => e.source === current)
144
+ .map((e) => e.target);
145
+
146
+ for (const succ of successors) {
147
+ if (!visited.has(succ)) queue.push(succ);
148
+ }
149
+ }
150
+
151
+ return visited;
152
+ }
153
+
154
+ /**
155
+ * Get the sub-graph (nodes + edges) reachable from given start nodes,
156
+ * stopping at a set of boundary nodes.
157
+ */
158
+ export function getSubGraph(
159
+ dsl: WorkflowDSL,
160
+ startNodeIds: string[],
161
+ stopNodeIds: Set<string> = new Set(),
162
+ ): WorkflowDSL {
163
+ const visited = new Set<string>();
164
+ const queue = [...startNodeIds];
165
+
166
+ while (queue.length > 0) {
167
+ const current = queue.shift()!;
168
+ if (visited.has(current) || stopNodeIds.has(current)) continue;
169
+ visited.add(current);
170
+
171
+ const successors = dsl.edges
172
+ .filter((e) => e.source === current)
173
+ .map((e) => e.target);
174
+
175
+ for (const succ of successors) {
176
+ if (!visited.has(succ) && !stopNodeIds.has(succ)) queue.push(succ);
177
+ }
178
+ }
179
+
180
+ return {
181
+ nodes: dsl.nodes.filter((n) => visited.has(n.id)),
182
+ edges: dsl.edges.filter((e) => visited.has(e.source) && visited.has(e.target)),
183
+ };
184
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Pure helper functions for the DSL workflow interpreter.
3
+ *
4
+ * These functions are deterministic and have no side effects,
5
+ * making them safe to import in Temporal workflow code and easy to unit test.
6
+ */
7
+ import type { WorkflowDSL, DslNode } from './types';
8
+
9
+ // ─── Template Resolution ─────────────────────────────────────────────────────
10
+
11
+ /**
12
+ * Recursively resolve {{path}} template variables in an object.
13
+ */
14
+ export function resolveTemplates(obj: any, ctx: Record<string, any>): any {
15
+ if (typeof obj === 'string') {
16
+ return obj.replace(/\{\{(.+?)\}\}/g, (_, path) => {
17
+ const val = getNestedValue(ctx, path.trim());
18
+ return val !== undefined ? String(val) : '';
19
+ });
20
+ }
21
+ if (Array.isArray(obj)) return obj.map((v) => resolveTemplates(v, ctx));
22
+ if (obj && typeof obj === 'object') {
23
+ const result: Record<string, any> = {};
24
+ for (const [k, v] of Object.entries(obj)) {
25
+ result[k] = resolveTemplates(v, ctx);
26
+ }
27
+ return result;
28
+ }
29
+ return obj;
30
+ }
31
+
32
+ /**
33
+ * Resolve a simple path expression against the context.
34
+ * If the path resolves to a value, return it; otherwise return the raw string.
35
+ */
36
+ export function resolveExpression(expr: string, ctx: Record<string, any>): any {
37
+ const value = getNestedValue(ctx, expr);
38
+ if (value !== undefined) return value;
39
+ return expr;
40
+ }
41
+
42
+ // ─── Object Path Access ──────────────────────────────────────────────────────
43
+
44
+ /**
45
+ * Get a nested value from an object using dot notation.
46
+ * e.g. getNestedValue({ a: { b: 1 } }, "a.b") → 1
47
+ */
48
+ export function getNestedValue(obj: Record<string, any>, path: string): any {
49
+ const parts = path.split('.');
50
+ let current: any = obj;
51
+ for (const part of parts) {
52
+ if (current == null) return undefined;
53
+ current = current[part];
54
+ }
55
+ return current;
56
+ }
57
+
58
+ // ─── Condition Evaluation ────────────────────────────────────────────────────
59
+
60
+ /**
61
+ * Evaluate multiple condition rules with AND/OR combining.
62
+ */
63
+ export function evaluateConditions(
64
+ conditions: Array<{ field: string; operator: string; value: string }>,
65
+ ctx: Record<string, any>,
66
+ combineOp: 'AND' | 'OR',
67
+ ): boolean {
68
+ if (conditions.length === 0) return true;
69
+ const results = conditions.map((rule) => {
70
+ const fieldValue = getNestedValue(ctx, rule.field);
71
+ return evaluateRule(fieldValue, rule.operator, rule.value);
72
+ });
73
+ return combineOp === 'AND' ? results.every(Boolean) : results.some(Boolean);
74
+ }
75
+
76
+ /**
77
+ * Evaluate a single condition rule.
78
+ */
79
+ export function evaluateRule(fieldValue: any, operator: string, compareValue: string): boolean {
80
+ switch (operator) {
81
+ case 'equals':
82
+ case '==':
83
+ return String(fieldValue) === compareValue;
84
+ case 'notEquals':
85
+ case '!=':
86
+ return String(fieldValue) !== compareValue;
87
+ case 'contains':
88
+ return String(fieldValue).includes(compareValue);
89
+ case 'notContains':
90
+ return !String(fieldValue).includes(compareValue);
91
+ case 'greaterThan':
92
+ case '>':
93
+ return Number(fieldValue) > Number(compareValue);
94
+ case 'lessThan':
95
+ case '<':
96
+ return Number(fieldValue) < Number(compareValue);
97
+ case 'greaterThanOrEqual':
98
+ case '>=':
99
+ return Number(fieldValue) >= Number(compareValue);
100
+ case 'lessThanOrEqual':
101
+ case '<=':
102
+ return Number(fieldValue) <= Number(compareValue);
103
+ case 'isEmpty':
104
+ return fieldValue == null || fieldValue === '';
105
+ case 'isNotEmpty':
106
+ return fieldValue != null && fieldValue !== '';
107
+ default:
108
+ return false;
109
+ }
110
+ }
111
+
112
+ // ─── Graph Navigation ────────────────────────────────────────────────────────
113
+
114
+ /**
115
+ * Get successor node IDs from a list of source node IDs.
116
+ */
117
+ export function getSuccessorsFromNodes(dsl: WorkflowDSL, nodeIds: string[]): string[] {
118
+ return dsl.edges.filter((e) => nodeIds.includes(e.source)).map((e) => e.target);
119
+ }
120
+
121
+ /**
122
+ * Determine next nodes to execute based on the current node and optional branch.
123
+ * For condition nodes, follows only the matching branch edge.
124
+ */
125
+ export function getNextNodes(dsl: WorkflowDSL, node: DslNode, branch?: string): string[] {
126
+ if (branch !== undefined) {
127
+ const branchEdges = dsl.edges.filter(
128
+ (e) => e.source === node.id && e.sourceHandle === branch,
129
+ );
130
+ if (branchEdges.length > 0) return branchEdges.map((e) => e.target);
131
+ }
132
+ return dsl.edges.filter((e) => e.source === node.id).map((e) => e.target);
133
+ }