Skip to content
Merged
5 changes: 3 additions & 2 deletions workspaces/ballerina/ballerina-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
All notable changes to the "Ballerina" extension will be documented in this file.


## Version 5.3.1 (2025-08-07)
## **5.3.1** (2025-08-13)

### Fixed

- Resolved issues affecting Inline Data Mapper functionality and flow diagram rendering

## Version 5.3.0 (2025-07-29)

## **5.3.0** (2025-07-29)

### Major Updates

Expand Down
2 changes: 1 addition & 1 deletion workspaces/ballerina/ballerina-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ballerina",
"displayName": "Ballerina",
"description": "Ballerina Language support, debugging, graphical visualization, AI-based data-mapping and many more.",
"version": "5.3.0",
"version": "5.3.1",
"publisher": "wso2",
"icon": "resources/images/ballerina.png",
"homepage": "https://wso2.com/ballerina/vscode/docs",
Expand Down
23 changes: 12 additions & 11 deletions workspaces/ballerina/ballerina-visualizer/src/utils/bi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,25 +419,26 @@ export function removeDraftNodeFromDiagram(flowModel: Flow) {
return newFlow;
}

export function enrichFormPropertiesWithValueConstraint(
export function enrichFormTemplatePropertiesWithValues(
formProperties: NodeProperties,
formTemplateProperties: NodeProperties
) {
const enrichedFormProperties = cloneDeep(formProperties);
const enrichedFormTemplateProperties = cloneDeep(formTemplateProperties);

for (const key in formTemplateProperties) {
if (formTemplateProperties.hasOwnProperty(key)) {
const expression = formTemplateProperties[key as NodePropertyKey];
if (expression) {
const valConstraint = formTemplateProperties[key as NodePropertyKey]?.valueTypeConstraint;
if (valConstraint && enrichedFormProperties[key as NodePropertyKey]) {
enrichedFormProperties[key as NodePropertyKey].valueTypeConstraint = valConstraint;
}
for (const key in formProperties) {
if (formProperties.hasOwnProperty(key)) {
const formProperty = formProperties[key as NodePropertyKey];
if (
formProperty &&
enrichedFormTemplateProperties[key as NodePropertyKey] != null
) {
// Copy the value from formProperties to formTemplateProperties
enrichedFormTemplateProperties[key as NodePropertyKey].value = formProperty.value;
}
}
}

return enrichedFormProperties;
return enrichedFormTemplateProperties;
}

function getEnrichedValue(kind: CompletionItemKind, value: string): CompletionInsertText {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import {
convertNodePropertiesToFormFields,
convertToFnSignature,
convertToVisibleTypes,
enrichFormPropertiesWithValueConstraint,
enrichFormTemplatePropertiesWithValues,
filterUnsupportedDiagnostics,
getFormProperties,
getImportsForFormFields,
Expand Down Expand Up @@ -243,7 +243,7 @@ export const FormGenerator = forwardRef<FormExpressionEditorRef, FormProps>(func
let enrichedNodeProperties;
if (nodeFormTemplate) {
const formTemplateProperties = getFormProperties(nodeFormTemplate);
enrichedNodeProperties = enrichFormPropertiesWithValueConstraint(formProperties, formTemplateProperties);
enrichedNodeProperties = enrichFormTemplatePropertiesWithValues(formProperties, formTemplateProperties);
console.log(">>> Form properties", { formProperties, formTemplateProperties, enrichedNodeProperties });
}
if (Object.keys(formProperties).length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function isSupportedType(node: STNode,
return [false, TypeNature.TYPE_UNAVAILABLE];
} else if ((isUnionType || isOptionalType) && kind === 'output' && getUnsupportedTypesFromTypeDesc(node).length === 0) {
return [true];
} else if (isUnionType || isMapType || isOptionalType) {
} else if (isMapType) {
return [false, TypeNature.YET_TO_SUPPORT];
} else if (isArrayType || isParenthesisedType) {
return [getUnsupportedTypesFromTypeDesc(node).length === 0, TypeNature.BLACKLISTED]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
getFromClauseNodeLabel,
getOptionalArrayField,
getSearchFilteredInput,
getTypeFromStore
getTypeFromStore,
isOptionalAndNillableField
} from "../../utils/dm-utils";
import { DataMapperNodeModel } from "../commons/DataMapperNode";
import { QueryExprMappingType } from "../QueryExpression";
Expand Down Expand Up @@ -128,6 +129,12 @@ export class FromClauseNode extends DataMapperNodeModel {
parentPort.collapsed
);
});
} else {
const isOptional = isOptionalAndNillableField(this.typeDef);
this.numberOfFields += this.addPortsForInputRecordField(
this.typeDef, "OUT", this.nodeLabel, this.nodeLabel,
EXPANDED_QUERY_SOURCE_PORT_PREFIX, parentPort, this.context.collapsedFields, parentPort.collapsed, isOptional
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,13 @@ export class LinkConnectorNode extends DataMapperNodeModel {
const inputNode = getInputNodeExpr(field, this);
if (inputNode) {
const inputPort = getInputPortsForExpr(inputNode, field);
if (!this.sourcePorts.some(port => port.getID() === inputPort.getID())) {
this.sourcePorts.push(inputPort);
this.sourceValues[inputPort.getID()] = [field];
} else {
this.sourceValues[inputPort.getID()].push(field);
if (inputPort) {
if (!this.sourcePorts.some(port => port.getID() === inputPort.getID())) {
this.sourcePorts.push(inputPort);
this.sourceValues[inputPort.getID()] = [field];
} else {
this.sourceValues[inputPort.getID()].push(field);
}
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class RequiredParamNode extends DataMapperNodeModel {
});
} else {
const isOptional = isOptionalAndNillableField(this.typeDef);
this.addPortsForInputRecordField(
this.numberOfFields += this.addPortsForInputRecordField(
this.typeDef, "OUT", this.value.paramName.value, this.value.paramName.value,
'', parentPort, this.context.collapsedFields, parentPort.collapsed, isOptional
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export class RequiredParamNodeFactory extends AbstractReactFactory<RequiredParam
return (
<InputSearchNoResultFound kind={SearchNoResultFoundKind.InputField} />
);
} else if (event.model.typeDef && event.model.typeDef.typeName === PrimitiveBalType.Record) {
} else if (event.model.typeDef &&
(event.model.typeDef.typeName === PrimitiveBalType.Record ||
event.model.typeDef.typeName === PrimitiveBalType.Union)
) {
return (
<RecordTypeTreeWidget
engine={this.engine}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,9 @@ export abstract class DataMapperNodeModel extends NodeModel<NodeModelGenerics &
const fieldFQN = parentId
? `${parentId}${fieldName && isOptional
? `?.${fieldName}`
: `.${fieldName}`}`
: fieldName ? `.${fieldName}` : ''}`
: fieldName && fieldName;
const unsafeFieldFQN = unsafeParentId
? `${unsafeParentId}.${fieldName}`
: fieldName || '';
const unsafeFieldFQN = fieldFQN.replaceAll('?.', '.');

if (fieldName.startsWith("$missingNode$")) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import React, { useState } from "react";

import { Button, Codicon, TruncatedLabel } from "@wso2/ui-toolkit";
import { DiagramEngine, PortWidget } from '@projectstorm/react-diagrams';
import { TypeField } from "@wso2/ballerina-core";
import { PrimitiveBalType, TypeField } from "@wso2/ballerina-core";

import { DataMapperPortWidget, PortState, RecordFieldPortModel } from '../../../Port';
import { EXPANDED_QUERY_INPUT_NODE_PREFIX } from '../../../utils/constants';
import { getTypeName } from "../../../utils/dm-utils";
import { getOptionalRecordField, getTypeName } from "../../../utils/dm-utils";
import { InputSearchHighlight } from '../Search';
import { TreeBody, TreeContainer, TreeHeader } from '../Tree/Tree';

Expand Down Expand Up @@ -56,10 +56,21 @@ export function RecordTypeTreeWidget(props: RecordTypeTreeWidgetProps) {
const isPortDisabled = hasLinkViaCollectClause && Object.keys(portOut.getLinks()).length === 0;
portOut.isDisabledDueToCollectClause = isPortDisabled;

const hasFields = !!typeDesc?.fields?.length;
let fields: TypeField[] = [];
let optional = false;

const optionalRecordField = getOptionalRecordField(typeDesc);
if (optionalRecordField) {
optional = true
fields = optionalRecordField.fields;
} else if (typeDesc.typeName === PrimitiveBalType.Record) {
fields = typeDesc.fields;
}

const hasFields = fields?.length > 0;

let expanded = true;
if (portOut && portOut.collapsed) {
if (portOut && (portOut.collapsed || portOut.hidden)) {
expanded = false;
}

Expand Down Expand Up @@ -143,7 +154,7 @@ export function RecordTypeTreeWidget(props: RecordTypeTreeWidgetProps) {
{expanded && hasFields && (
<TreeBody>
{
typeDesc.fields.map((field, index) => {
fields.map((field, index) => {
return (
<RecordFieldTreeItemWidget
key={index}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,9 @@ export function getInputPortsForExpr(node: InputNode, expr: STNode ): RecordFiel
portIdBuffer = EXPANDED_QUERY_SOURCE_PORT_PREFIX + "." + (node as FromClauseNode).nodeLabel;
}

if (typeDesc && typeDesc.typeName === PrimitiveBalType.Record) {
if (typeDesc && (typeDesc.typeName === PrimitiveBalType.Record ||
typeDesc.typeName === PrimitiveBalType.Union)
) {
if (STKindChecker.isFieldAccess(expr) || STKindChecker.isOptionalFieldAccess(expr)) {
const fieldNames = getFieldNames(expr);
let nextTypeNode: TypeField = typeDesc;
Expand Down
6 changes: 4 additions & 2 deletions workspaces/bi/bi-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Change log

## Version 1.2.1 (2025-08-07)
## **1.2.1** (2025-08-13)

### Fixed

- Resolved issues affecting Inline Data Mapper functionality and flow diagram rendering

## Version 1.2.0 (2025-07-29)

## **1.2.0** (2025-07-29)

### Major Updates

Expand Down Expand Up @@ -36,6 +37,7 @@
- **Configuration:** Fixed issues with Config.toml management and fast-run command failures.
- **IDE Stability:** Addressed UI freezing, improved state management, and enhanced project handling in multi-root workspaces.


## **1.1.0** (2025-07-14)

### Major Features
Expand Down
2 changes: 1 addition & 1 deletion workspaces/bi/bi-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ballerina-integrator",
"displayName": "WSO2 Integrator: BI",
"description": "An extension which gives a development environment for designing, developing, debugging, and testing integration solutions.",
"version": "1.2.0",
"version": "1.2.1",
"publisher": "wso2",
"icon": "resources/images/wso2-ballerina-integrator-logo.png",
"repository": {
Expand Down
Loading