@octaviaflow/flow-rules 0.20.0 → 0.21.0
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/index.cjs +28 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -1
- package/dist/rules/nodeConfigStatus.d.ts +11 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -121,6 +121,7 @@ __export(exports_src, {
|
|
|
121
121
|
contractDrift: () => contractDrift,
|
|
122
122
|
contractFieldsFor: () => contractFieldsFor,
|
|
123
123
|
contractFor: () => contractFor,
|
|
124
|
+
contractValidationErrors: () => contractValidationErrors,
|
|
124
125
|
contractVocabularyDrift: () => contractVocabularyDrift,
|
|
125
126
|
declaredKeys: () => declaredKeys,
|
|
126
127
|
detectRecordFields: () => detectRecordFields,
|
|
@@ -5249,6 +5250,21 @@ function missingContractRequired(node) {
|
|
|
5249
5250
|
}
|
|
5250
5251
|
return missing;
|
|
5251
5252
|
}
|
|
5253
|
+
function contractValidationErrors(node) {
|
|
5254
|
+
if (HIDDEN_STATUS_ACTIONS.has(node.actionDefinitionId))
|
|
5255
|
+
return [];
|
|
5256
|
+
const contract = contractFor(node.actionDefinitionId);
|
|
5257
|
+
if (!contract?.validate)
|
|
5258
|
+
return [];
|
|
5259
|
+
try {
|
|
5260
|
+
const verdict = contract.validate(node.config ?? {});
|
|
5261
|
+
if (verdict.valid)
|
|
5262
|
+
return [];
|
|
5263
|
+
return [...new Set(verdict.errors.map((e) => String(e).trim()).filter(Boolean))];
|
|
5264
|
+
} catch {
|
|
5265
|
+
return [];
|
|
5266
|
+
}
|
|
5267
|
+
}
|
|
5252
5268
|
|
|
5253
5269
|
// src/rules/workflowValidator.ts
|
|
5254
5270
|
var nodeName = (n) => n.label || n.id;
|
|
@@ -5284,8 +5300,19 @@ function validateNode(node, allNodes, allEdges) {
|
|
|
5284
5300
|
nodeId: node.id
|
|
5285
5301
|
});
|
|
5286
5302
|
}
|
|
5303
|
+
const contractIssues = cfg.missingRequired.length === 0 ? contractValidationErrors(node) : [];
|
|
5287
5304
|
const contractGaps = missingContractRequired(node);
|
|
5288
|
-
if (
|
|
5305
|
+
if (contractIssues.length > 0) {
|
|
5306
|
+
const shown = contractIssues.slice(0, 3).map((e) => e.replace(/[.\s]+$/, ""));
|
|
5307
|
+
const more = contractIssues.length > 3 ? ` (+${contractIssues.length - 3} more)` : "";
|
|
5308
|
+
errors.push({
|
|
5309
|
+
id: `node-${node.id}-contract`,
|
|
5310
|
+
type: "node",
|
|
5311
|
+
severity: "warning",
|
|
5312
|
+
message: `This step will not run as set up: ${shown.join("; ")}${more}. Open the step to fix it.`,
|
|
5313
|
+
nodeId: node.id
|
|
5314
|
+
});
|
|
5315
|
+
} else if (contractGaps.length > 0) {
|
|
5289
5316
|
const fields = contractGaps.slice(0, 4).join(", ");
|
|
5290
5317
|
const more = contractGaps.length > 4 ? ` +${contractGaps.length - 4} more` : "";
|
|
5291
5318
|
errors.push({
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
export * from "./catalog/types";
|
|
22
22
|
export { actionsRegistry, getAllActions, getActionById, getActionsByCategory, } from "./catalog/index";
|
|
23
23
|
export { validateNode, validateEdge, validateWorkflow, getNodeValidationStatus, getEdgeValidationStatus, type ValidationError, type ValidationResult, } from "./rules/workflowValidator";
|
|
24
|
-
export { getNodeConfigStatus, missingContractRequired, type NodeConfigStatus, type NodeConfigStatusResult, } from "./rules/nodeConfigStatus";
|
|
24
|
+
export { getNodeConfigStatus, missingContractRequired, contractValidationErrors, type NodeConfigStatus, type NodeConfigStatusResult, } from "./rules/nodeConfigStatus";
|
|
25
25
|
export { generateWorkflowId, generateStepId, generateEdgeId, generateUUIDv4, } from "./ids";
|
|
26
26
|
export { CONDITION_OPERATORS, ConditionConfig, type ConditionFilter, type ConditionOperator, } from "./catalog/logic/condition/config";
|
|
27
27
|
export { ForEachConfig, type ForEachConfigType, type ForEachMode, } from "./catalog/logic/for-each/config";
|
package/dist/index.js
CHANGED
|
@@ -5073,6 +5073,21 @@ function missingContractRequired(node) {
|
|
|
5073
5073
|
}
|
|
5074
5074
|
return missing;
|
|
5075
5075
|
}
|
|
5076
|
+
function contractValidationErrors(node) {
|
|
5077
|
+
if (HIDDEN_STATUS_ACTIONS.has(node.actionDefinitionId))
|
|
5078
|
+
return [];
|
|
5079
|
+
const contract = contractFor(node.actionDefinitionId);
|
|
5080
|
+
if (!contract?.validate)
|
|
5081
|
+
return [];
|
|
5082
|
+
try {
|
|
5083
|
+
const verdict = contract.validate(node.config ?? {});
|
|
5084
|
+
if (verdict.valid)
|
|
5085
|
+
return [];
|
|
5086
|
+
return [...new Set(verdict.errors.map((e) => String(e).trim()).filter(Boolean))];
|
|
5087
|
+
} catch {
|
|
5088
|
+
return [];
|
|
5089
|
+
}
|
|
5090
|
+
}
|
|
5076
5091
|
|
|
5077
5092
|
// src/rules/workflowValidator.ts
|
|
5078
5093
|
var nodeName = (n) => n.label || n.id;
|
|
@@ -5108,8 +5123,19 @@ function validateNode(node, allNodes, allEdges) {
|
|
|
5108
5123
|
nodeId: node.id
|
|
5109
5124
|
});
|
|
5110
5125
|
}
|
|
5126
|
+
const contractIssues = cfg.missingRequired.length === 0 ? contractValidationErrors(node) : [];
|
|
5111
5127
|
const contractGaps = missingContractRequired(node);
|
|
5112
|
-
if (
|
|
5128
|
+
if (contractIssues.length > 0) {
|
|
5129
|
+
const shown = contractIssues.slice(0, 3).map((e) => e.replace(/[.\s]+$/, ""));
|
|
5130
|
+
const more = contractIssues.length > 3 ? ` (+${contractIssues.length - 3} more)` : "";
|
|
5131
|
+
errors.push({
|
|
5132
|
+
id: `node-${node.id}-contract`,
|
|
5133
|
+
type: "node",
|
|
5134
|
+
severity: "warning",
|
|
5135
|
+
message: `This step will not run as set up: ${shown.join("; ")}${more}. Open the step to fix it.`,
|
|
5136
|
+
nodeId: node.id
|
|
5137
|
+
});
|
|
5138
|
+
} else if (contractGaps.length > 0) {
|
|
5113
5139
|
const fields = contractGaps.slice(0, 4).join(", ");
|
|
5114
5140
|
const more = contractGaps.length > 4 ? ` +${contractGaps.length - 4} more` : "";
|
|
5115
5141
|
errors.push({
|
|
@@ -6231,6 +6257,7 @@ export {
|
|
|
6231
6257
|
contractDrift,
|
|
6232
6258
|
contractFieldsFor,
|
|
6233
6259
|
contractFor,
|
|
6260
|
+
contractValidationErrors,
|
|
6234
6261
|
contractVocabularyDrift,
|
|
6235
6262
|
declaredKeys,
|
|
6236
6263
|
detectRecordFields,
|
|
@@ -43,3 +43,14 @@ export declare function getNodeConfigStatus(node: WorkflowNode): NodeConfigStatu
|
|
|
43
43
|
* The drift test pins the list of such keys, so a new one is a decision.
|
|
44
44
|
*/
|
|
45
45
|
export declare function missingContractRequired(node: WorkflowNode): string[];
|
|
46
|
+
/**
|
|
47
|
+
* What the action's own contract check (`validate()`, the check its config
|
|
48
|
+
* panel runs) says is wrong with this node, deduplicated (DEV-643).
|
|
49
|
+
*
|
|
50
|
+
* `getNodeConfigStatus` only asks whether each required setting is filled in;
|
|
51
|
+
* a Variables step whose `fields` holds a row with no key passed it, so
|
|
52
|
+
* `check_flow` and the canvas called the flow fine while the panel and the
|
|
53
|
+
* MCP's `add_step` said "Each field needs a key". A validator that throws is
|
|
54
|
+
* treated as silent: a broken check must not invent a problem.
|
|
55
|
+
*/
|
|
56
|
+
export declare function contractValidationErrors(node: WorkflowNode): string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octaviaflow/flow-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "The flow action catalog and the rules engine behind Flow Doctor \u2014 one definition of what a step accepts and what makes a flow valid, shared by the editor and the server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|