@defai.digital/workflow-engine 13.0.3

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.
@@ -0,0 +1,77 @@
1
+ import { WorkflowSchema, } from '@defai.digital/contracts';
2
+ import { WorkflowErrorCodes } from './types.js';
3
+ /**
4
+ * Validation error for workflows
5
+ */
6
+ export class WorkflowValidationError extends Error {
7
+ code;
8
+ details;
9
+ constructor(code, message, details) {
10
+ super(message);
11
+ this.code = code;
12
+ this.details = details;
13
+ this.name = 'WorkflowValidationError';
14
+ }
15
+ }
16
+ /**
17
+ * Validates a workflow definition and checks invariants
18
+ * INV-WF-003: Schema strictness - unknown fields rejected
19
+ * INV-WF-004: Step ID uniqueness
20
+ */
21
+ export function validateWorkflow(data) {
22
+ // Use strict parsing to reject unknown fields (INV-WF-003)
23
+ const strictSchema = WorkflowSchema.strict();
24
+ const result = strictSchema.safeParse(data);
25
+ if (!result.success) {
26
+ throw new WorkflowValidationError(WorkflowErrorCodes.VALIDATION_ERROR, `Workflow validation failed: ${result.error.message}`, { errors: result.error.errors });
27
+ }
28
+ const workflow = result.data;
29
+ // INV-WF-004: Check for duplicate step IDs
30
+ const stepIds = new Set();
31
+ for (const step of workflow.steps) {
32
+ if (stepIds.has(step.stepId)) {
33
+ throw new WorkflowValidationError(WorkflowErrorCodes.DUPLICATE_STEP_ID, `Duplicate step ID found: ${step.stepId}`, { stepId: step.stepId });
34
+ }
35
+ stepIds.add(step.stepId);
36
+ }
37
+ return workflow;
38
+ }
39
+ /**
40
+ * Deep freezes an object to make it immutable
41
+ * INV-WF-005: Workflow definitions must not be modified during execution
42
+ */
43
+ function deepFreeze(obj) {
44
+ const propNames = Reflect.ownKeys(obj);
45
+ for (const name of propNames) {
46
+ const value = obj[name];
47
+ if (value !== null && typeof value === 'object') {
48
+ deepFreeze(value);
49
+ }
50
+ }
51
+ return Object.freeze(obj);
52
+ }
53
+ /**
54
+ * Prepares a workflow for execution by validating and freezing it
55
+ * INV-WF-003: Schema strictness
56
+ * INV-WF-004: Step ID uniqueness
57
+ * INV-WF-005: Immutable definition
58
+ */
59
+ export function prepareWorkflow(data) {
60
+ const workflow = validateWorkflow(data);
61
+ // Collect step IDs
62
+ const stepIds = new Set(workflow.steps.map((s) => s.stepId));
63
+ // Deep freeze the workflow (INV-WF-005)
64
+ const frozenWorkflow = deepFreeze(structuredClone(workflow));
65
+ return {
66
+ workflow: frozenWorkflow,
67
+ stepIds,
68
+ };
69
+ }
70
+ /**
71
+ * Deep freezes a step result to ensure immutability
72
+ * This prevents subsequent steps from accidentally modifying previous results
73
+ */
74
+ export function deepFreezeStepResult(result) {
75
+ return deepFreeze(structuredClone(result));
76
+ }
77
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAE9B;IAEA;IAHlB,YACkB,IAAY,EAC5B,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QAEZ,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,2DAA2D;IAC3D,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAE5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,uBAAuB,CAC/B,kBAAkB,CAAC,gBAAgB,EACnC,+BAA+B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EACrD,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAChC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IAE7B,2CAA2C;IAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,uBAAuB,CAC/B,kBAAkB,CAAC,iBAAiB,EACpC,4BAA4B,IAAI,CAAC,MAAM,EAAE,EACzC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CACxB,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAmB,GAAM;IAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAgB,CAAC;IAEtD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,UAAU,CAAC,KAAe,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAExC,mBAAmB;IACnB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7D,wCAAwC;IACxC,MAAM,cAAc,GAAG,UAAU,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE7D,OAAO;QACL,QAAQ,EAAE,cAAc;QACxB,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,OAAO,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@defai.digital/workflow-engine",
3
+ "version": "13.0.3",
4
+ "type": "module",
5
+ "description": "Workflow execution engine - executes workflows following contract invariants",
6
+ "license": "Apache-2.0",
7
+ "author": "DEFAI Private Limited",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/defai-digital/automatosx.git",
11
+ "directory": "packages/core/workflow-engine"
12
+ },
13
+ "homepage": "https://github.com/defai-digital/automatosx#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/defai-digital/automatosx/issues"
16
+ },
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "engines": {
29
+ "node": ">=20.0.0"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "dependencies": {
35
+ "yaml": "^2.7.0",
36
+ "@defai.digital/contracts": "13.0.3"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc --build",
40
+ "clean": "rm -rf dist *.tsbuildinfo"
41
+ }
42
+ }