@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/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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "Deterministic workflow compiler for AI agents. Compiles to standalone TypeScript, no runtime dependencies.",
5
5
  "private": false,
6
6
  "type": "module",