@gadmin2n/schematics 0.0.135 → 0.0.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.server +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/compose-ctl.sh +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/canvas.prisma +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +14 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/User.ts +4 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.md +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.yml +13 -92
- package/dist/lib/application/files/gadmin2-game-angle-demo/readme.md +105 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/ensure-database.js +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +7 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +9 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/gen-jwt.ts +85 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/notify-dev-servers.js +9 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/wait-for-nest-ready.js +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +43 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +9 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +24 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.dto.ts +27 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.service.spec.ts +430 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas-export.service.ts +203 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.ts +36 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.module.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +245 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.service.spec.ts +366 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.service.ts +110 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +15 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +41 -19
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +5 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +37 -573
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/ecosystem.dev.config.cjs +12 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +3 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +39 -26
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/i18n.ts +3 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +23 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +66 -10
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +16 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +21 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts +30 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/ExportModal.tsx +84 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/ImportModal.tsx +166 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/hooks/useCanvasHistory.ts +52 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +6 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +17 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +18 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +225 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/lazy-with-reload.ts +31 -0
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-dsl-validate.spec.ts +0 -220
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-dsl-validate.ts +0 -132
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/TODO.md +0 -152
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +0 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +0 -25
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +0 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.dockerignore +0 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +0 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/Dockerfile +0 -79
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/GRACEFUL-DEPLOYMENT.md +0 -270
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +0 -122
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +0 -4285
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +0 -28
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +0 -51
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +0 -85
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +0 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +0 -54
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +0 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +0 -85
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +0 -47
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +0 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +0 -58
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +0 -184
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +0 -133
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +0 -96
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +0 -77
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/validate.ts +0 -109
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +0 -382
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/activities/code-execute.test.ts +0 -44
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/activities/http-request.test.ts +0 -87
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/cron-trigger-workflow.test.ts +0 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/helpers.test.ts +0 -225
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/node-type-consistency.test.ts +0 -101
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/validate.test.ts +0 -205
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +0 -499
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +0 -19
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +0 -1905
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "gadmin-workflow-worker",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"scripts": {
|
|
6
|
-
"build": "tsc",
|
|
7
|
-
"dev": "ts-node src/index.ts",
|
|
8
|
-
"start": "node dist/index.js",
|
|
9
|
-
"test": "vitest run",
|
|
10
|
-
"test:watch": "vitest"
|
|
11
|
-
},
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"@temporalio/activity": "^1.11.6",
|
|
14
|
-
"@temporalio/client": "^1.11.6",
|
|
15
|
-
"@temporalio/worker": "^1.11.6",
|
|
16
|
-
"@temporalio/workflow": "^1.11.6",
|
|
17
|
-
"axios": "^1.7.9",
|
|
18
|
-
"dotenv": "^16.4.7",
|
|
19
|
-
"pg": "^8.16.3"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@types/node": "^22.0.0",
|
|
23
|
-
"@types/pg": "^8.11.0",
|
|
24
|
-
"ts-node": "^10.9.2",
|
|
25
|
-
"typescript": "^5.7.0",
|
|
26
|
-
"vitest": "^3.1.0"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export interface CodeExecuteInput {
|
|
2
|
-
script: string;
|
|
3
|
-
mode?: 'runOnceForAll' | 'runOnceForEach';
|
|
4
|
-
timeout?: number;
|
|
5
|
-
data?: any;
|
|
6
|
-
items?: any[];
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface CodeExecuteOutput {
|
|
10
|
-
result: any;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Execute custom JavaScript code in a sandboxed environment.
|
|
15
|
-
* Uses Node.js vm module for basic isolation.
|
|
16
|
-
* For production, consider isolated-vm for stronger sandboxing.
|
|
17
|
-
*/
|
|
18
|
-
export async function codeExecute(input: CodeExecuteInput): Promise<CodeExecuteOutput> {
|
|
19
|
-
const { script, mode = 'runOnceForAll', timeout = 5000, data, items } = input;
|
|
20
|
-
const vm = await import('vm');
|
|
21
|
-
|
|
22
|
-
if (mode === 'runOnceForEach' && Array.isArray(items)) {
|
|
23
|
-
const results: any[] = [];
|
|
24
|
-
for (const item of items) {
|
|
25
|
-
const sandbox = {
|
|
26
|
-
item,
|
|
27
|
-
data,
|
|
28
|
-
console: { log: () => {} },
|
|
29
|
-
result: undefined as any,
|
|
30
|
-
};
|
|
31
|
-
const context = vm.createContext(sandbox);
|
|
32
|
-
const wrappedScript = new vm.Script(`result = (function() { ${script} })()`);
|
|
33
|
-
wrappedScript.runInContext(context, { timeout });
|
|
34
|
-
results.push(sandbox.result);
|
|
35
|
-
}
|
|
36
|
-
return { result: results };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// runOnceForAll
|
|
40
|
-
const sandbox = {
|
|
41
|
-
data,
|
|
42
|
-
items: items || [],
|
|
43
|
-
console: { log: () => {} },
|
|
44
|
-
result: undefined as any,
|
|
45
|
-
};
|
|
46
|
-
const context = vm.createContext(sandbox);
|
|
47
|
-
const wrappedScript = new vm.Script(`result = (function() { ${script} })()`);
|
|
48
|
-
wrappedScript.runInContext(context, { timeout });
|
|
49
|
-
|
|
50
|
-
return { result: sandbox.result };
|
|
51
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { Pool } from 'pg';
|
|
2
|
-
import { config } from '../config';
|
|
3
|
-
|
|
4
|
-
const pool = new Pool({ connectionString: config.database.url });
|
|
5
|
-
|
|
6
|
-
export interface DbExecuteInput {
|
|
7
|
-
operation: 'insert' | 'update' | 'delete' | 'raw';
|
|
8
|
-
table?: string;
|
|
9
|
-
data?: Record<string, any>;
|
|
10
|
-
where?: string;
|
|
11
|
-
rawSql?: string;
|
|
12
|
-
params?: any[];
|
|
13
|
-
datasource?: string;
|
|
14
|
-
timeout?: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface DbExecuteOutput {
|
|
18
|
-
affectedRows: number;
|
|
19
|
-
insertedId?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Execute a database write operation (INSERT/UPDATE/DELETE).
|
|
24
|
-
*/
|
|
25
|
-
export async function dbExecute(input: DbExecuteInput): Promise<DbExecuteOutput> {
|
|
26
|
-
const client = await pool.connect();
|
|
27
|
-
try {
|
|
28
|
-
if (input.timeout) {
|
|
29
|
-
await client.query(`SET statement_timeout = ${input.timeout}`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
let query: string;
|
|
33
|
-
let params: any[] = [];
|
|
34
|
-
|
|
35
|
-
switch (input.operation) {
|
|
36
|
-
case 'raw':
|
|
37
|
-
query = input.rawSql || '';
|
|
38
|
-
params = input.params || [];
|
|
39
|
-
break;
|
|
40
|
-
|
|
41
|
-
case 'insert': {
|
|
42
|
-
if (!input.table || !input.data) throw new Error('table and data required for insert');
|
|
43
|
-
const keys = Object.keys(input.data);
|
|
44
|
-
const values = Object.values(input.data);
|
|
45
|
-
const placeholders = keys.map((_, i) => `$${i + 1}`);
|
|
46
|
-
query = `INSERT INTO ${input.table} (${keys.join(', ')}) VALUES (${placeholders.join(', ')}) RETURNING id`;
|
|
47
|
-
params = values;
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
case 'update': {
|
|
52
|
-
if (!input.table || !input.data) throw new Error('table and data required for update');
|
|
53
|
-
const entries = Object.entries(input.data);
|
|
54
|
-
const sets = entries.map(([k], i) => `${k} = $${i + 1}`);
|
|
55
|
-
params = entries.map(([, v]) => v);
|
|
56
|
-
query = `UPDATE ${input.table} SET ${sets.join(', ')}`;
|
|
57
|
-
if (input.where) {
|
|
58
|
-
query += ` WHERE ${input.where}`;
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
case 'delete': {
|
|
64
|
-
if (!input.table) throw new Error('table required for delete');
|
|
65
|
-
query = `DELETE FROM ${input.table}`;
|
|
66
|
-
if (input.where) {
|
|
67
|
-
query += ` WHERE ${input.where}`;
|
|
68
|
-
}
|
|
69
|
-
params = input.params || [];
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
default:
|
|
74
|
-
throw new Error(`Unknown operation: ${input.operation}`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const result = await client.query(query, params);
|
|
78
|
-
return {
|
|
79
|
-
affectedRows: result.rowCount || 0,
|
|
80
|
-
insertedId: result.rows?.[0]?.id?.toString(),
|
|
81
|
-
};
|
|
82
|
-
} finally {
|
|
83
|
-
client.release();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Pool } from 'pg';
|
|
2
|
-
import { config } from '../config';
|
|
3
|
-
|
|
4
|
-
const pool = new Pool({ connectionString: config.database.url });
|
|
5
|
-
|
|
6
|
-
export interface DbQueryInput {
|
|
7
|
-
query: string;
|
|
8
|
-
params?: any[];
|
|
9
|
-
datasource?: string;
|
|
10
|
-
timeout?: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface DbQueryOutput {
|
|
14
|
-
rows: any[];
|
|
15
|
-
rowCount: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Execute a database SELECT query.
|
|
20
|
-
*/
|
|
21
|
-
export async function dbQuery(input: DbQueryInput): Promise<DbQueryOutput> {
|
|
22
|
-
const client = await pool.connect();
|
|
23
|
-
try {
|
|
24
|
-
if (input.timeout) {
|
|
25
|
-
await client.query(`SET statement_timeout = ${input.timeout}`);
|
|
26
|
-
}
|
|
27
|
-
const result = await client.query(input.query, input.params || []);
|
|
28
|
-
return {
|
|
29
|
-
rows: result.rows,
|
|
30
|
-
rowCount: result.rowCount || 0,
|
|
31
|
-
};
|
|
32
|
-
} finally {
|
|
33
|
-
client.release();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
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
|
-
}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
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, createCronInstance } from './reporting';
|
|
@@ -1,85 +0,0 @@
|
|
|
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
|
-
* Create a workflow instance for a cron-triggered run.
|
|
35
|
-
* Used by cronTriggerWorkflow before delegating to dslWorkflow.
|
|
36
|
-
*/
|
|
37
|
-
export async function createCronInstance(input: {
|
|
38
|
-
workflowId: number;
|
|
39
|
-
versionId: number;
|
|
40
|
-
scheduleId: string;
|
|
41
|
-
}): Promise<{ instanceId: number }> {
|
|
42
|
-
const { rows } = await pool.query(
|
|
43
|
-
`INSERT INTO t_workflow_instance
|
|
44
|
-
(workflow_id, version_id, status, context, creator, created_at, updated_at)
|
|
45
|
-
VALUES ($1, $2, 'PENDING', $3, 'cron', NOW(), NOW())
|
|
46
|
-
RETURNING id`,
|
|
47
|
-
[
|
|
48
|
-
input.workflowId,
|
|
49
|
-
input.versionId,
|
|
50
|
-
JSON.stringify({ scheduleId: input.scheduleId, scheduledAt: new Date().toISOString() }),
|
|
51
|
-
],
|
|
52
|
-
);
|
|
53
|
-
return { instanceId: Number(rows[0].id) };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Report overall workflow execution status.
|
|
58
|
-
*/
|
|
59
|
-
export async function reportWorkflowStatus(input: ReportWorkflowStatusInput): Promise<void> {
|
|
60
|
-
const { instanceId, status, result } = input;
|
|
61
|
-
|
|
62
|
-
const updates: string[] = ['status = $1', 'updated_at = NOW()'];
|
|
63
|
-
const values: any[] = [status];
|
|
64
|
-
let paramIdx = 2;
|
|
65
|
-
|
|
66
|
-
if (status === 'RUNNING') {
|
|
67
|
-
updates.push(`started_at = NOW()`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (status === 'COMPLETED' || status === 'FAILED' || status === 'CANCELLED') {
|
|
71
|
-
updates.push(`finished_at = NOW()`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (result !== undefined) {
|
|
75
|
-
updates.push(`result = $${paramIdx}`);
|
|
76
|
-
values.push(JSON.stringify(result));
|
|
77
|
-
paramIdx++;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
values.push(instanceId);
|
|
81
|
-
await pool.query(
|
|
82
|
-
`UPDATE t_workflow_instance SET ${updates.join(', ')} WHERE id = $${paramIdx}`,
|
|
83
|
-
values,
|
|
84
|
-
);
|
|
85
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
};
|
package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
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
|
-
}
|
package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
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
|
-
}
|