@synergenius/flow-weaver 0.10.2 → 0.10.4
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/ast/types.d.ts +2 -0
- package/dist/chevrotain-parser/connect-parser.d.ts +5 -0
- package/dist/chevrotain-parser/connect-parser.js +24 -4
- package/dist/cli/flow-weaver.mjs +401 -35
- package/dist/diagram/html-viewer.d.ts +8 -0
- package/dist/diagram/html-viewer.js +170 -7
- package/dist/diagram/index.js +48 -12
- package/dist/friendly-errors.js +45 -10
- package/dist/generator/code-utils.d.ts +12 -1
- package/dist/generator/code-utils.js +88 -3
- package/dist/jsdoc-parser.js +2 -1
- package/dist/validator.js +56 -0
- package/package.json +1 -1
package/dist/validator.js
CHANGED
|
@@ -17,7 +17,25 @@ const ERROR_DOC_URLS = {
|
|
|
17
17
|
INFERRED_NODE_TYPE: `${DOCS_BASE}/node-conversion`,
|
|
18
18
|
DUPLICATE_CONNECTION: `${DOCS_BASE}/concepts#connections`,
|
|
19
19
|
STUB_NODE: `${DOCS_BASE}/model-driven#stub-nodes`,
|
|
20
|
+
COERCE_TYPE_MISMATCH: `${DOCS_BASE}/compilation#type-coercion`,
|
|
21
|
+
REDUNDANT_COERCE: `${DOCS_BASE}/compilation#type-coercion`,
|
|
22
|
+
COERCE_ON_FUNCTION_PORT: `${DOCS_BASE}/compilation#type-coercion`,
|
|
20
23
|
};
|
|
24
|
+
/** Map coerce type to the dataType it produces */
|
|
25
|
+
const COERCE_OUTPUT_TYPE = {
|
|
26
|
+
string: 'STRING', number: 'NUMBER', boolean: 'BOOLEAN',
|
|
27
|
+
json: 'STRING', object: 'OBJECT',
|
|
28
|
+
};
|
|
29
|
+
/** Suggest the correct `as <type>` for a given target dataType */
|
|
30
|
+
function suggestCoerceType(targetType) {
|
|
31
|
+
switch (targetType) {
|
|
32
|
+
case 'STRING': return 'string';
|
|
33
|
+
case 'NUMBER': return 'number';
|
|
34
|
+
case 'BOOLEAN': return 'boolean';
|
|
35
|
+
case 'OBJECT': return 'object';
|
|
36
|
+
default: return '<type>';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
21
39
|
export class WorkflowValidator {
|
|
22
40
|
errors = [];
|
|
23
41
|
warnings = [];
|
|
@@ -478,8 +496,30 @@ export class WorkflowValidator {
|
|
|
478
496
|
if (sourceType === 'STEP' && targetType === 'STEP') {
|
|
479
497
|
return;
|
|
480
498
|
}
|
|
499
|
+
// Block coercion on FUNCTION ports — coercing a function value is nonsensical
|
|
500
|
+
if (conn.coerce && (sourceType === 'FUNCTION' || targetType === 'FUNCTION')) {
|
|
501
|
+
this.errors.push({
|
|
502
|
+
type: 'error',
|
|
503
|
+
code: 'COERCE_ON_FUNCTION_PORT',
|
|
504
|
+
message: `Coercion \`as ${conn.coerce}\` cannot be used on FUNCTION ports in connection "${fromNode}.${fromPort}" → "${toNode}.${toPort}". FUNCTION values cannot be meaningfully coerced.`,
|
|
505
|
+
connection: conn,
|
|
506
|
+
location: connLocation,
|
|
507
|
+
});
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
481
510
|
// Same type - check for structural compatibility if both are OBJECT
|
|
482
511
|
if (sourceType === targetType) {
|
|
512
|
+
// Redundant coerce: same types don't need coercion
|
|
513
|
+
if (conn.coerce) {
|
|
514
|
+
this.warnings.push({
|
|
515
|
+
type: 'warning',
|
|
516
|
+
code: 'REDUNDANT_COERCE',
|
|
517
|
+
message: `Coercion \`as ${conn.coerce}\` on connection "${fromNode}.${fromPort}" → "${toNode}.${toPort}" is redundant — source and target are both ${sourceType}.`,
|
|
518
|
+
connection: conn,
|
|
519
|
+
location: connLocation,
|
|
520
|
+
});
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
483
523
|
// For OBJECT types, check if tsType differs (structural mismatch)
|
|
484
524
|
if (sourceType === 'OBJECT' && sourcePortDef.tsType && targetPortDef.tsType) {
|
|
485
525
|
const normalizedSource = this.normalizeTypeString(sourcePortDef.tsType);
|
|
@@ -504,6 +544,22 @@ export class WorkflowValidator {
|
|
|
504
544
|
if (sourceType === 'ANY' || targetType === 'ANY') {
|
|
505
545
|
return;
|
|
506
546
|
}
|
|
547
|
+
// Validate explicit coerce: check that produced type matches target
|
|
548
|
+
if (conn.coerce) {
|
|
549
|
+
const producedType = COERCE_OUTPUT_TYPE[conn.coerce];
|
|
550
|
+
if (producedType === targetType) {
|
|
551
|
+
return; // Coerce correctly resolves the mismatch
|
|
552
|
+
}
|
|
553
|
+
// Wrong coerce type — produced type doesn't match target
|
|
554
|
+
pushTypeIssue({
|
|
555
|
+
type: 'warning',
|
|
556
|
+
code: 'COERCE_TYPE_MISMATCH',
|
|
557
|
+
message: `Coercion \`as ${conn.coerce}\` produces ${producedType} but target port "${toPort}" on "${toNode}" expects ${targetType}. Use \`as ${suggestCoerceType(targetType)}\` instead.`,
|
|
558
|
+
connection: conn,
|
|
559
|
+
location: connLocation,
|
|
560
|
+
}, true);
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
507
563
|
// Safe coercions (no warning)
|
|
508
564
|
const safeCoercions = [
|
|
509
565
|
['NUMBER', 'STRING'],
|
package/package.json
CHANGED