@flowgram.ai/runtime-js 0.2.23 → 0.2.24

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/esm/index.js CHANGED
@@ -1,79 +1,78 @@
1
1
  // ../interface/dist/esm/index.js
2
+ import z2 from "zod";
2
3
  import z from "zod";
3
4
  import z3 from "zod";
4
- import z2 from "zod";
5
5
  import z4 from "zod";
6
6
  import z5 from "zod";
7
7
  import z6 from "zod";
8
8
  import z7 from "zod";
9
+ var WorkflowIOZodSchema = z.record(z.string(), z.any());
10
+ var WorkflowSnapshotZodSchema = z.object({
11
+ id: z.string(),
12
+ nodeID: z.string(),
13
+ inputs: WorkflowIOZodSchema,
14
+ outputs: WorkflowIOZodSchema.optional(),
15
+ data: WorkflowIOZodSchema,
16
+ branch: z.string().optional()
17
+ });
18
+ var WorkflowStatusZodShape = {
19
+ status: z.string(),
20
+ terminated: z.boolean(),
21
+ startTime: z.number(),
22
+ endTime: z.number().optional(),
23
+ timeCost: z.number()
24
+ };
25
+ var WorkflowStatusZodSchema = z.object(WorkflowStatusZodShape);
26
+ var WorkflowNodeReportZodSchema = z.object({
27
+ id: z.string(),
28
+ ...WorkflowStatusZodShape,
29
+ snapshots: z.array(WorkflowSnapshotZodSchema)
30
+ });
31
+ var WorkflowReportsZodSchema = z.record(z.string(), WorkflowNodeReportZodSchema);
32
+ var WorkflowMessageZodSchema = z.object({
33
+ id: z.string(),
34
+ type: z.enum(["log", "info", "debug", "error", "warning"]),
35
+ message: z.string(),
36
+ nodeID: z.string().optional(),
37
+ timestamp: z.number()
38
+ });
39
+ var WorkflowMessagesZodSchema = z.record(
40
+ z.enum(["log", "info", "debug", "error", "warning"]),
41
+ z.array(WorkflowMessageZodSchema)
42
+ );
43
+ var WorkflowZodSchema = {
44
+ Inputs: WorkflowIOZodSchema,
45
+ Outputs: WorkflowIOZodSchema,
46
+ Status: WorkflowStatusZodSchema,
47
+ Snapshot: WorkflowSnapshotZodSchema,
48
+ Reports: WorkflowReportsZodSchema,
49
+ Messages: WorkflowMessagesZodSchema
50
+ };
9
51
  var FlowGramAPIName = /* @__PURE__ */ ((FlowGramAPIName2) => {
10
52
  FlowGramAPIName2["ServerInfo"] = "ServerInfo";
11
53
  FlowGramAPIName2["TaskRun"] = "TaskRun";
12
54
  FlowGramAPIName2["TaskReport"] = "TaskReport";
13
55
  FlowGramAPIName2["TaskResult"] = "TaskResult";
14
56
  FlowGramAPIName2["TaskCancel"] = "TaskCancel";
15
- FlowGramAPIName2["Validation"] = "Validation";
57
+ FlowGramAPIName2["TaskValidate"] = "TaskValidate";
16
58
  return FlowGramAPIName2;
17
59
  })(FlowGramAPIName || {});
18
- var ValidationDefine = {
19
- name: "Validation",
60
+ var TaskValidateDefine = {
61
+ name: "TaskValidate",
20
62
  method: "POST",
21
- path: "/validation",
22
- module: "Validation",
63
+ path: "/task/validate",
64
+ module: "Task",
23
65
  schema: {
24
- input: z.object({
25
- schema: z.string()
66
+ input: z2.object({
67
+ schema: z2.string(),
68
+ inputs: WorkflowZodSchema.Inputs
26
69
  }),
27
- output: z.object({
28
- valid: z.boolean(),
29
- nodeErrors: z.array(
30
- z.object({
31
- message: z.string(),
32
- nodeID: z.string()
33
- })
34
- ),
35
- edgeErrors: z.array(
36
- z.object({
37
- message: z.string(),
38
- edge: z.object({
39
- sourceNodeID: z.string(),
40
- targetNodeID: z.string(),
41
- sourcePortID: z.string().optional(),
42
- targetPortID: z.string().optional()
43
- })
44
- })
45
- )
70
+ output: z2.object({
71
+ valid: z2.boolean(),
72
+ errors: z2.array(z2.string()).optional()
46
73
  })
47
74
  }
48
75
  };
49
- var WorkflowIOZodSchema = z2.record(z2.string(), z2.any());
50
- var WorkflowSnapshotZodSchema = z2.object({
51
- id: z2.string(),
52
- nodeID: z2.string(),
53
- inputs: WorkflowIOZodSchema,
54
- outputs: WorkflowIOZodSchema.optional(),
55
- data: WorkflowIOZodSchema,
56
- branch: z2.string().optional()
57
- });
58
- var WorkflowStatusZodShape = {
59
- status: z2.string(),
60
- terminated: z2.boolean(),
61
- startTime: z2.number(),
62
- endTime: z2.number().optional(),
63
- timeCost: z2.number()
64
- };
65
- var WorkflowStatusZodSchema = z2.object(WorkflowStatusZodShape);
66
- var WorkflowZodSchema = {
67
- Inputs: WorkflowIOZodSchema,
68
- Outputs: WorkflowIOZodSchema,
69
- Status: WorkflowStatusZodSchema,
70
- Snapshot: WorkflowSnapshotZodSchema,
71
- NodeReport: z2.object({
72
- id: z2.string(),
73
- ...WorkflowStatusZodShape,
74
- snapshots: z2.array(WorkflowSnapshotZodSchema)
75
- })
76
- };
77
76
  var TaskRunDefine = {
78
77
  name: "TaskRun",
79
78
  method: "POST",
@@ -115,7 +114,8 @@ var TaskReportDefine = {
115
114
  inputs: WorkflowZodSchema.Inputs,
116
115
  outputs: WorkflowZodSchema.Outputs,
117
116
  workflowStatus: WorkflowZodSchema.Status,
118
- reports: z5.record(z5.string(), WorkflowZodSchema.NodeReport)
117
+ reports: WorkflowZodSchema.Reports,
118
+ messages: WorkflowZodSchema.Messages
119
119
  })
120
120
  }
121
121
  };
@@ -170,9 +170,9 @@ var FlowGramAPIs = {
170
170
  /* TaskCancel */
171
171
  ]: TaskCancelDefine,
172
172
  [
173
- "Validation"
174
- /* Validation */
175
- ]: ValidationDefine
173
+ "TaskValidate"
174
+ /* TaskValidate */
175
+ ]: TaskValidateDefine
176
176
  };
177
177
  var FlowGramAPINames = Object.keys(FlowGramAPIs);
178
178
  var WorkflowPortType = /* @__PURE__ */ ((WorkflowPortType2) => {
@@ -362,6 +362,205 @@ function compareNodeGroups(groupA, groupB) {
362
362
  };
363
363
  }
364
364
 
365
+ // src/infrastructure/utils/json-schema-validator.ts
366
+ var ROOT_PATH = "root";
367
+ var isRootPath = (path) => path === ROOT_PATH;
368
+ var validateValue = (value, schema, path) => {
369
+ if (schema.$ref) {
370
+ return { result: true };
371
+ }
372
+ if (schema.enum && schema.enum.length > 0) {
373
+ if (!schema.enum.includes(value)) {
374
+ return {
375
+ result: false,
376
+ errorMessage: `Value at ${path} must be one of: ${schema.enum.join(
377
+ ", "
378
+ )}, but got: ${JSON.stringify(value)}`
379
+ };
380
+ }
381
+ }
382
+ switch (schema.type) {
383
+ case "boolean":
384
+ return validateBoolean(value, path);
385
+ case "string":
386
+ return validateString(value, path);
387
+ case "integer":
388
+ return validateInteger(value, path);
389
+ case "number":
390
+ return validateNumber(value, path);
391
+ case "object":
392
+ return validateObject(value, schema, path);
393
+ case "array":
394
+ return validateArray(value, schema, path);
395
+ case "map":
396
+ return validateMap(value, schema, path);
397
+ default:
398
+ return {
399
+ result: false,
400
+ errorMessage: `Unknown type "${schema.type}" at ${path}`
401
+ };
402
+ }
403
+ };
404
+ var validateBoolean = (value, path) => {
405
+ if (typeof value !== "boolean") {
406
+ return {
407
+ result: false,
408
+ errorMessage: `Expected boolean at ${path}, but got: ${typeof value}`
409
+ };
410
+ }
411
+ return { result: true };
412
+ };
413
+ var validateString = (value, path) => {
414
+ if (typeof value !== "string") {
415
+ return {
416
+ result: false,
417
+ errorMessage: `Expected string at ${path}, but got: ${typeof value}`
418
+ };
419
+ }
420
+ return { result: true };
421
+ };
422
+ var validateInteger = (value, path) => {
423
+ if (!Number.isInteger(value)) {
424
+ return {
425
+ result: false,
426
+ errorMessage: `Expected integer at ${path}, but got: ${JSON.stringify(value)}`
427
+ };
428
+ }
429
+ return { result: true };
430
+ };
431
+ var validateNumber = (value, path) => {
432
+ if (typeof value !== "number" || isNaN(value)) {
433
+ return {
434
+ result: false,
435
+ errorMessage: `Expected number at ${path}, but got: ${JSON.stringify(value)}`
436
+ };
437
+ }
438
+ return { result: true };
439
+ };
440
+ var validateObject = (value, schema, path) => {
441
+ if (value === null || value === void 0) {
442
+ return {
443
+ result: false,
444
+ errorMessage: `Expected object at ${path}, but got: ${value}`
445
+ };
446
+ }
447
+ if (typeof value !== "object" || Array.isArray(value)) {
448
+ return {
449
+ result: false,
450
+ errorMessage: `Expected object at ${path}, but got: ${Array.isArray(value) ? "array" : typeof value}`
451
+ };
452
+ }
453
+ const objectValue = value;
454
+ if (schema.required && schema.required.length > 0) {
455
+ for (const requiredProperty of schema.required) {
456
+ if (!(requiredProperty in objectValue)) {
457
+ return {
458
+ result: false,
459
+ errorMessage: `Missing required property "${requiredProperty}" at ${path}`
460
+ };
461
+ }
462
+ }
463
+ }
464
+ if (schema.properties) {
465
+ for (const [propertyName, propertySchema] of Object.entries(schema.properties)) {
466
+ const isRequired = propertySchema.isPropertyRequired === true;
467
+ if (isRequired && !(propertyName in objectValue)) {
468
+ return {
469
+ result: false,
470
+ errorMessage: `Missing required property "${propertyName}" at ${path}`
471
+ };
472
+ }
473
+ }
474
+ }
475
+ if (schema.properties) {
476
+ for (const [propertyName, propertySchema] of Object.entries(schema.properties)) {
477
+ if (propertyName in objectValue) {
478
+ const propertyPath = isRootPath(path) ? propertyName : `${path}.${propertyName}`;
479
+ const propertyResult = validateValue(
480
+ objectValue[propertyName],
481
+ propertySchema,
482
+ propertyPath
483
+ );
484
+ if (!propertyResult.result) {
485
+ return propertyResult;
486
+ }
487
+ }
488
+ }
489
+ }
490
+ if (schema.additionalProperties) {
491
+ const definedProperties = new Set(Object.keys(schema.properties || {}));
492
+ for (const [propertyName, propertyValue] of Object.entries(objectValue)) {
493
+ if (!definedProperties.has(propertyName)) {
494
+ const propertyPath = isRootPath(path) ? propertyName : `${path}.${propertyName}`;
495
+ const propertyResult = validateValue(
496
+ propertyValue,
497
+ schema.additionalProperties,
498
+ propertyPath
499
+ );
500
+ if (!propertyResult.result) {
501
+ return propertyResult;
502
+ }
503
+ }
504
+ }
505
+ }
506
+ return { result: true };
507
+ };
508
+ var validateArray = (value, schema, path) => {
509
+ if (!Array.isArray(value)) {
510
+ return {
511
+ result: false,
512
+ errorMessage: `Expected array at ${path}, but got: ${typeof value}`
513
+ };
514
+ }
515
+ if (schema.items) {
516
+ for (const [index, item] of value.entries()) {
517
+ const itemPath = `${path}[${index}]`;
518
+ const itemResult = validateValue(item, schema.items, itemPath);
519
+ if (!itemResult.result) {
520
+ return itemResult;
521
+ }
522
+ }
523
+ }
524
+ return { result: true };
525
+ };
526
+ var validateMap = (value, schema, path) => {
527
+ if (value === null || value === void 0) {
528
+ return {
529
+ result: false,
530
+ errorMessage: `Expected map at ${path}, but got: ${value}`
531
+ };
532
+ }
533
+ if (typeof value !== "object" || Array.isArray(value)) {
534
+ return {
535
+ result: false,
536
+ errorMessage: `Expected map at ${path}, but got: ${Array.isArray(value) ? "array" : typeof value}`
537
+ };
538
+ }
539
+ const mapValue = value;
540
+ if (schema.additionalProperties) {
541
+ for (const [key, mapItemValue] of Object.entries(mapValue)) {
542
+ const keyPath = isRootPath(path) ? key : `${path}.${key}`;
543
+ const keyResult = validateValue(mapItemValue, schema.additionalProperties, keyPath);
544
+ if (!keyResult.result) {
545
+ return keyResult;
546
+ }
547
+ }
548
+ }
549
+ return { result: true };
550
+ };
551
+ var JSONSchemaValidator = (params) => {
552
+ const { schema, value } = params;
553
+ try {
554
+ const validationResult = validateValue(value, schema, ROOT_PATH);
555
+ return validationResult;
556
+ } catch (error) {
557
+ return {
558
+ result: false,
559
+ errorMessage: `Validation error: ${error instanceof Error ? error.message : String(error)}`
560
+ };
561
+ }
562
+ };
563
+
365
564
  // src/nodes/loop/index.ts
366
565
  var LoopExecutor = class {
367
566
  constructor() {
@@ -880,11 +1079,48 @@ var WorkflowRuntimeNodeExecutors = [
880
1079
 
881
1080
  // src/domain/validation/index.ts
882
1081
  var WorkflowRuntimeValidation = class {
883
- validate(schema) {
1082
+ invoke(params) {
1083
+ const { schema, inputs } = params;
1084
+ const schemaValidationResult = this.schema(schema);
1085
+ if (!schemaValidationResult.valid) {
1086
+ return schemaValidationResult;
1087
+ }
1088
+ const inputsValidationResult = this.inputs(this.getWorkflowInputsDeclare(schema), inputs);
1089
+ if (!inputsValidationResult.valid) {
1090
+ return inputsValidationResult;
1091
+ }
1092
+ return {
1093
+ valid: true
1094
+ };
1095
+ }
1096
+ schema(schema) {
1097
+ return {
1098
+ valid: true
1099
+ };
1100
+ }
1101
+ inputs(inputsSchema, inputs) {
1102
+ const { result, errorMessage } = JSONSchemaValidator({
1103
+ schema: inputsSchema,
1104
+ value: inputs
1105
+ });
1106
+ if (!result) {
1107
+ const error = `JSON Schema validation failed: ${errorMessage}`;
1108
+ return {
1109
+ valid: false,
1110
+ errors: [error]
1111
+ };
1112
+ }
884
1113
  return {
885
1114
  valid: true
886
1115
  };
887
1116
  }
1117
+ getWorkflowInputsDeclare(schema) {
1118
+ const startNode = schema.nodes.find((node) => node.type === FlowGramNode.Start);
1119
+ if (!startNode) {
1120
+ throw new Error("Workflow schema must have a start node");
1121
+ }
1122
+ return startNode.data.outputs;
1123
+ }
888
1124
  };
889
1125
 
890
1126
  // src/domain/executor/index.ts
@@ -1892,11 +2128,19 @@ var WorkflowRuntimeContext = class _WorkflowRuntimeContext {
1892
2128
  // src/domain/engine/index.ts
1893
2129
  var WorkflowRuntimeEngine = class {
1894
2130
  constructor(service) {
2131
+ this.validation = service.Validation;
1895
2132
  this.executor = service.Executor;
1896
2133
  }
1897
2134
  invoke(params) {
1898
2135
  const context = WorkflowRuntimeContext.create();
1899
2136
  context.init(params);
2137
+ const valid = this.validate(params, context);
2138
+ if (!valid) {
2139
+ return WorkflowRuntimeTask.create({
2140
+ processing: Promise.resolve({}),
2141
+ context
2142
+ });
2143
+ }
1900
2144
  const processing = this.process(context);
1901
2145
  processing.then(() => {
1902
2146
  context.dispose();
@@ -1963,6 +2207,19 @@ var WorkflowRuntimeEngine = class {
1963
2207
  return {};
1964
2208
  }
1965
2209
  }
2210
+ validate(params, context) {
2211
+ const { valid, errors } = this.validation.invoke(params);
2212
+ if (valid) {
2213
+ return true;
2214
+ }
2215
+ errors?.forEach((message) => {
2216
+ context.messageCenter.error({
2217
+ message
2218
+ });
2219
+ });
2220
+ context.statusCenter.workflow.fail();
2221
+ return false;
2222
+ }
1966
2223
  canExecuteNode(params) {
1967
2224
  const { node, context } = params;
1968
2225
  const prevNodes = node.prev;
@@ -2031,6 +2288,7 @@ var WorkflowRuntimeContainer = class _WorkflowRuntimeContainer {
2031
2288
  const Validation = new WorkflowRuntimeValidation();
2032
2289
  const Executor = new WorkflowRuntimeExecutor(WorkflowRuntimeNodeExecutors);
2033
2290
  const Engine = new WorkflowRuntimeEngine({
2291
+ Validation,
2034
2292
  Executor
2035
2293
  });
2036
2294
  return {
@@ -2087,6 +2345,12 @@ var WorkflowApplication = class _WorkflowApplication {
2087
2345
  }
2088
2346
  return task.context.ioCenter.outputs;
2089
2347
  }
2348
+ validate(params) {
2349
+ const validation = this.container.get(IValidation);
2350
+ const result = validation.invoke(params);
2351
+ console.log("> POST TaskValidate - valid: ", result.valid);
2352
+ return result;
2353
+ }
2090
2354
  static get instance() {
2091
2355
  if (this._instance) {
2092
2356
  return this._instance;
@@ -2096,6 +2360,19 @@ var WorkflowApplication = class _WorkflowApplication {
2096
2360
  }
2097
2361
  };
2098
2362
 
2363
+ // src/api/task-validate.ts
2364
+ var TaskValidateAPI = async (input) => {
2365
+ const app = WorkflowApplication.instance;
2366
+ const { schema: stringSchema, inputs } = input;
2367
+ const schema = JSON.parse(stringSchema);
2368
+ const result = app.validate({
2369
+ schema,
2370
+ inputs
2371
+ });
2372
+ const output = result;
2373
+ return output;
2374
+ };
2375
+
2099
2376
  // src/api/task-run.ts
2100
2377
  var TaskRunAPI = async (input) => {
2101
2378
  const app = WorkflowApplication.instance;
@@ -2146,22 +2423,21 @@ var TaskCancelAPI = async (input) => {
2146
2423
 
2147
2424
  // src/api/index.ts
2148
2425
  var WorkflowRuntimeAPIs = {
2426
+ [FlowGramAPIName.ServerInfo]: () => {
2427
+ },
2428
+ // TODO
2149
2429
  [FlowGramAPIName.TaskRun]: TaskRunAPI,
2150
2430
  [FlowGramAPIName.TaskReport]: TaskReportAPI,
2151
2431
  [FlowGramAPIName.TaskResult]: TaskResultAPI,
2152
2432
  [FlowGramAPIName.TaskCancel]: TaskCancelAPI,
2153
- [FlowGramAPIName.ServerInfo]: () => {
2154
- },
2155
- // TODO
2156
- [FlowGramAPIName.Validation]: () => {
2157
- }
2158
- // TODO
2433
+ [FlowGramAPIName.TaskValidate]: TaskValidateAPI
2159
2434
  };
2160
2435
  export {
2161
2436
  TaskCancelAPI,
2162
2437
  TaskReportAPI,
2163
2438
  TaskResultAPI,
2164
2439
  TaskRunAPI,
2440
+ TaskValidateAPI,
2165
2441
  WorkflowRuntimeAPIs
2166
2442
  };
2167
2443
  //# sourceMappingURL=index.js.map