@skenora/flow 0.1.2

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,186 @@
1
+ import { createBuiltInFlowNodeRegistry, } from "./node-registry.js";
2
+ export class FlowValidationError extends Error {
3
+ issues;
4
+ constructor(issues) {
5
+ const ownedIssues = issues.map((issue) => Object.freeze({ ...issue }));
6
+ super(ownedIssues.map((issue) => issue.message).join("; "));
7
+ this.name = "FlowValidationError";
8
+ this.issues = Object.freeze(ownedIssues);
9
+ }
10
+ }
11
+ export function validateFlowGraph(graph, registry = createBuiltInFlowNodeRegistry()) {
12
+ const issues = [];
13
+ const nodeIds = new Set();
14
+ const edgeIds = new Set();
15
+ const definitions = new Map();
16
+ for (const node of graph.nodes) {
17
+ if (nodeIds.has(node.id)) {
18
+ issues.push({
19
+ code: "duplicate-node",
20
+ message: `Duplicate node id: ${node.id}`,
21
+ nodeId: node.id,
22
+ });
23
+ }
24
+ nodeIds.add(node.id);
25
+ const definition = registry.get(node.type);
26
+ if (!definition) {
27
+ issues.push({
28
+ code: "unknown-node",
29
+ message: `Flow node type is not registered: ${node.type}`,
30
+ nodeId: node.id,
31
+ });
32
+ continue;
33
+ }
34
+ definitions.set(node.id, definition);
35
+ for (const message of definition.validateConfig?.(node) ?? []) {
36
+ issues.push({
37
+ code: "invalid-config",
38
+ message,
39
+ nodeId: node.id,
40
+ });
41
+ }
42
+ }
43
+ for (const edge of graph.edges) {
44
+ validateEdge(edge, nodeIds, edgeIds, definitions, issues);
45
+ edgeIds.add(edge.id);
46
+ }
47
+ for (const node of graph.nodes) {
48
+ const definition = definitions.get(node.id);
49
+ if (!definition)
50
+ continue;
51
+ for (const port of definition.inputs) {
52
+ if (port.kind !== "value")
53
+ continue;
54
+ const connections = graph.edges.filter((edge) => edge.kind === "value" &&
55
+ edge.targetNodeId === node.id &&
56
+ edge.targetPort === port.name &&
57
+ graph.nodes.some((source) => source.id === edge.sourceNodeId && source.enabled !== false));
58
+ const connected = connections.length > 0;
59
+ if (connections.length > 1 && port.multiple !== true) {
60
+ issues.push({
61
+ code: "multiple-input",
62
+ message: `Flow node ${node.id} input accepts only one connection: ${port.name}`,
63
+ nodeId: node.id,
64
+ });
65
+ }
66
+ const configured = node.config[port.name];
67
+ if (!connected &&
68
+ isRequiredInput(node.type, node.config, port) &&
69
+ configured === undefined) {
70
+ issues.push({
71
+ code: "missing-input",
72
+ message: `Flow node ${node.id} requires input: ${port.name}`,
73
+ nodeId: node.id,
74
+ });
75
+ }
76
+ else if (!connected &&
77
+ configured !== undefined &&
78
+ !configValueMatchesPort(configured, port)) {
79
+ issues.push({
80
+ code: "invalid-config",
81
+ message: `Flow node ${node.id} has invalid config for input: ${port.name}`,
82
+ nodeId: node.id,
83
+ });
84
+ }
85
+ }
86
+ }
87
+ if (!graph.nodes.some((node) => definitions.get(node.id)?.category === "trigger")) {
88
+ issues.push({
89
+ code: "missing-trigger",
90
+ message: "Flow has no trigger node",
91
+ });
92
+ }
93
+ return { valid: issues.length === 0, issues };
94
+ }
95
+ function isRequiredInput(nodeType, config, port) {
96
+ if (!port.required)
97
+ return false;
98
+ if (port.name !== "right")
99
+ return true;
100
+ if (nodeType === "value.logic" && (config.operator ?? "and") === "not") {
101
+ return false;
102
+ }
103
+ if (nodeType === "value.compare" &&
104
+ (config.operator ?? "equals") === "isEmpty") {
105
+ return false;
106
+ }
107
+ return true;
108
+ }
109
+ function configValueMatchesPort(value, port) {
110
+ if (port.valueType === undefined || port.valueType === "any")
111
+ return true;
112
+ if (port.valueType === "object") {
113
+ return value !== null && typeof value === "object" && !Array.isArray(value);
114
+ }
115
+ if (port.valueType === "transform") {
116
+ return value !== null && typeof value === "object" && !Array.isArray(value);
117
+ }
118
+ if (port.valueType === "number") {
119
+ return typeof value === "number" && Number.isFinite(value);
120
+ }
121
+ if (port.valueType === "string") {
122
+ return typeof value === "string" && (!port.required || value.length > 0);
123
+ }
124
+ return typeof value === port.valueType;
125
+ }
126
+ function validateEdge(edge, nodeIds, edgeIds, definitions, issues) {
127
+ if (edgeIds.has(edge.id)) {
128
+ issues.push({
129
+ code: "duplicate-edge",
130
+ message: `Duplicate edge id: ${edge.id}`,
131
+ edgeId: edge.id,
132
+ });
133
+ }
134
+ if (!nodeIds.has(edge.sourceNodeId) || !nodeIds.has(edge.targetNodeId)) {
135
+ issues.push({
136
+ code: "missing-node",
137
+ message: `Edge ${edge.id} references a missing node`,
138
+ edgeId: edge.id,
139
+ });
140
+ }
141
+ if (!edge.sourcePort ||
142
+ !edge.targetPort ||
143
+ edge.sourceNodeId === edge.targetNodeId) {
144
+ issues.push({
145
+ code: "invalid-edge",
146
+ message: `Edge ${edge.id} has invalid ports or a direct self-loop`,
147
+ edgeId: edge.id,
148
+ });
149
+ return;
150
+ }
151
+ const sourceDefinition = definitions.get(edge.sourceNodeId);
152
+ const targetDefinition = definitions.get(edge.targetNodeId);
153
+ if (!sourceDefinition || !targetDefinition)
154
+ return;
155
+ const sourcePort = sourceDefinition.outputs.find((port) => port.name === edge.sourcePort);
156
+ const targetPort = targetDefinition.inputs.find((port) => port.name === edge.targetPort);
157
+ if (!sourcePort || !targetPort) {
158
+ issues.push({
159
+ code: "unknown-port",
160
+ message: `Edge ${edge.id} references an unknown source or target port`,
161
+ edgeId: edge.id,
162
+ });
163
+ return;
164
+ }
165
+ if (sourcePort.kind !== edge.kind || targetPort.kind !== edge.kind) {
166
+ issues.push({
167
+ code: "port-kind-mismatch",
168
+ message: `Edge ${edge.id} kind does not match its ports`,
169
+ edgeId: edge.id,
170
+ });
171
+ return;
172
+ }
173
+ if (edge.kind === "value" && !valueTypesCompatible(sourcePort, targetPort)) {
174
+ issues.push({
175
+ code: "port-type-mismatch",
176
+ message: `Edge ${edge.id} connects incompatible value ports`,
177
+ edgeId: edge.id,
178
+ });
179
+ }
180
+ }
181
+ function valueTypesCompatible(source, target) {
182
+ const sourceType = source.valueType ?? "any";
183
+ const targetType = target.valueType ?? "any";
184
+ return (sourceType === "any" || targetType === "any" || sourceType === targetType);
185
+ }
186
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/model/validation.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@skenora/flow",
3
+ "version": "0.1.2",
4
+ "description": "DOM-free serializable event-flow validation and execution for Skenora.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "dependencies": {
22
+ "@skenora/contracts": "0.1.2",
23
+ "@skenora/events": "0.1.2"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json && node ../../scripts/prepare-package-output.mjs dist",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit"
28
+ },
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts"
31
+ }