diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/service.ts b/workspaces/ballerina/ballerina-core/src/interfaces/service.ts
index cb003e7e718..f9545b3133f 100644
--- a/workspaces/ballerina/ballerina-core/src/interfaces/service.ts
+++ b/workspaces/ballerina/ballerina-core/src/interfaces/service.ts
@@ -112,7 +112,8 @@ export enum Protocol {
MESSAGE_BROKER = "MESSAGE_BROKER",
GRAPHQL = "GRAPHQL",
FTP = "FTP",
- CDC = "CDC"
+ CDC = "CDC",
+ SMB = "SMB"
}
export interface HttpPayloadContext {
diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/platform-ext/utils.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/platform-ext/utils.ts
index b261807b34d..452a9c576cb 100644
--- a/workspaces/ballerina/ballerina-core/src/rpc-types/platform-ext/utils.ts
+++ b/workspaces/ballerina/ballerina-core/src/rpc-types/platform-ext/utils.ts
@@ -20,7 +20,7 @@ import { DevantScopes } from "@wso2/wso2-platform-core";
const INTEGRATION_API_MODULES = ["http", "graphql", "tcp"];
const EVENT_INTEGRATION_MODULES = ["kafka", "rabbitmq", "salesforce", "trigger.github", "mqtt", "asb"];
-const FILE_INTEGRATION_MODULES = ["ftp", "file"];
+const FILE_INTEGRATION_MODULES = ["ftp", "smb", "file"];
const AI_AGENT_MODULE = "ai";
const MCP_MODULE = "mcp";
diff --git a/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/file-integration/smb.spec.ts b/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/file-integration/smb.spec.ts
new file mode 100644
index 00000000000..ca7b26adb9d
--- /dev/null
+++ b/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/file-integration/smb.spec.ts
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com)
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { expect, test } from '@playwright/test';
+import { addArtifact, initTest, page } from '../utils/helpers';
+import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester';
+import { ProjectExplorer } from '../utils/pages';
+import { DEFAULT_PROJECT_NAME } from '../utils/helpers/setup';
+
+export default function createTests() {
+ const listenerName = 'smbListener';
+ test.describe('SMB Integration Tests', {
+ tag: '@group1',
+ }, async () => {
+ test.describe.configure({ mode: 'serial' });
+ initTest();
+ test('Create SMB Integration', async ({ }, testInfo) => {
+ const testAttempt = testInfo.retry + 1;
+ console.log('Creating a new service in test attempt: ', testAttempt);
+ await addArtifact('SMB Integration', 'trigger-smb');
+ const artifactWebView = await switchToIFrame('WSO2 Integrator: BI', page.page);
+ if (!artifactWebView) {
+ throw new Error('WSO2 Integrator: BI webview not found');
+ }
+ const form = new Form(page.page, 'WSO2 Integrator: BI', artifactWebView);
+ await form.switchToFormView(false, artifactWebView);
+ await form.submit('Create');
+
+ const projectExplorer = new ProjectExplorer(page.page);
+ await projectExplorer.findItem([DEFAULT_PROJECT_NAME, `SMB Integration`], true);
+
+ const context = artifactWebView.locator(`text=${listenerName}`);
+ await context.waitFor();
+ });
+
+ test('Editing SMB Service', async ({ }, testInfo) => {
+ const testAttempt = testInfo.retry + 1;
+ console.log('Editing a service in test attempt: ', testAttempt);
+ const artifactWebView = await switchToIFrame('WSO2 Integrator: BI', page.page);
+ if (!artifactWebView) {
+ throw new Error('WSO2 Integrator: BI webview not found');
+ }
+
+ const editBtn = artifactWebView.locator('vscode-button[title="Edit Service"]');
+ await editBtn.waitFor();
+ await editBtn.click({ force: true });
+
+ const form = new Form(page.page, 'WSO2 Integrator: BI', artifactWebView);
+ await form.switchToFormView(false, artifactWebView);
+
+ await form.fill({
+ values: {
+ 'host': {
+ type: 'cmEditor',
+ value: `127.0.0.6`,
+ additionalProps: { clickLabel: true, switchMode: 'primary-mode', window: global.window }
+ }
+ }
+ });
+
+ await form.submit('Save Changes');
+
+ const saveChangesBtn = artifactWebView.locator('#save-changes-btn vscode-button[appearance="primary"]');
+ await saveChangesBtn.waitFor({ state: 'visible' });
+ await expect(saveChangesBtn).toHaveClass(/disabled/, { timeout: 5000 });
+ await expect(saveChangesBtn).toHaveText('Save Changes');
+
+ const backBtn = artifactWebView.locator('[data-testid="back-button"]');
+ await backBtn.waitFor();
+ await backBtn.click();
+
+ await editBtn.waitFor();
+
+ const context = artifactWebView.locator(`text=${listenerName}`);
+ await context.waitFor();
+ });
+
+ test('Delete SMB Integration', async ({ }, testInfo) => {
+ const testAttempt = testInfo.retry + 1;
+ console.log('Deleting SMB integration in test attempt: ', testAttempt);
+
+ const artifactWebView = await switchToIFrame('WSO2 Integrator: BI', page.page);
+ if (!artifactWebView) {
+ throw new Error('WSO2 Integrator: BI webview not found');
+ }
+ const projectExplorer = new ProjectExplorer(page.page);
+ const serviceTreeItem = await projectExplorer.findItem([DEFAULT_PROJECT_NAME, `SMB Integration`], true);
+ await serviceTreeItem.click({ button: 'right' });
+ const deleteButton = page.page.getByRole('button', { name: 'Delete' }).first();
+ await deleteButton.waitFor({ timeout: 5000 });
+ await deleteButton.click();
+ await expect(serviceTreeItem).not.toBeVisible({ timeout: 10000 });
+ });
+ });
+}
diff --git a/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/test.list.ts b/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/test.list.ts
index 2480e6b92ae..cd970b5ef54 100644
--- a/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/test.list.ts
+++ b/workspaces/ballerina/ballerina-extension/e2e-test/e2e-playwright-tests/test.list.ts
@@ -55,6 +55,7 @@ import twillioIntegration from './event-integration/twillio.spec';
import githubIntegration from './event-integration/github.spec';
import ftpIntegration from './file-integration/ftp.spec';
+import smbIntegration from './file-integration/smb.spec';
import directoryIntegration from './file-integration/directory.spec';
import functionArtifact from './other-artifacts/function.spec';
@@ -127,6 +128,7 @@ test.describe(githubIntegration);
// <----File Integration Test---->
test.describe(ftpIntegration);
+test.describe(smbIntegration);
test.describe(directoryIntegration);
// <----Other Artifacts Test---->
diff --git a/workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts b/workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts
index c9d52bd6822..e80361e48f1 100644
--- a/workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts
+++ b/workspaces/ballerina/ballerina-extension/src/utils/project-artifacts.ts
@@ -565,6 +565,8 @@ function getCustomEntryNodeIcon(type: string) {
return "bi-asb";
case "ftp":
return "bi-ftp";
+ case "smb":
+ return "bi-smb";
case "file":
return "bi-file";
case "mcp":
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ComponentListView/FileIntegrationPanel.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ComponentListView/FileIntegrationPanel.tsx
index cc60c31c5f8..4fc3a78c0c9 100644
--- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ComponentListView/FileIntegrationPanel.tsx
+++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ComponentListView/FileIntegrationPanel.tsx
@@ -92,6 +92,8 @@ export function getCustomFileIntegrationIcon(type: string) {
switch (type) {
case "ftp":
return ;
+ case "smb":
+ return ;
case "file":
return ;
default:
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/Parameters/Parameters.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/Parameters/Parameters.tsx
index 12ea1d09c2d..30d08334525 100644
--- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/Parameters/Parameters.tsx
+++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/Parameters/Parameters.tsx
@@ -36,6 +36,7 @@ export interface ParametersProps {
onEditClick?: (param: ParameterModel) => void;
showPayload: boolean;
typeLabel?: string;
+ streamEnabled?: boolean;
}
const ParamLabelContainer = styled.div`
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/index.tsx
index 803a6bf2217..f8a815c1c95 100644
--- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/index.tsx
+++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/Forms/FileIntegrationForm/index.tsx
@@ -178,7 +178,7 @@ export function FileIntegrationForm(props: FileIntegrationFormProps) {
const [functionModel, setFunctionModel] = useState(props.functionModel || null);
const payloadContext = {
- protocol: Protocol.FTP,
+ protocol: model.moduleName === 'smb' ? Protocol.SMB : Protocol.FTP,
filterType: functionModel?.name?.metadata?.label || "",
} as GeneralPayloadContext;
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/index.tsx
index 02ac3b6109e..f910cc02f34 100644
--- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/index.tsx
+++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/ServiceDesigner/index.tsx
@@ -360,7 +360,7 @@ export function ServiceDesigner(props: ServiceDesignerProps) {
}
setReadonlyProperties(readonlyProps);
- setIsFtpService(service.moduleName === "ftp");
+ setIsFtpService(service.moduleName === "ftp" || service.moduleName === "smb");
setIsHttpService(service.moduleName === "http");
setIsMcpService(service.moduleName === "mcp");
setIsCdcService(service.moduleName === "mssql" || service.moduleName === "postgresql");
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/TypeEditor/utils.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/TypeEditor/utils.tsx
index 4c9ebf86462..a9d47849f89 100644
--- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/TypeEditor/utils.tsx
+++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/TypeEditor/utils.tsx
@@ -80,7 +80,7 @@ export const getTypes = (types: VisibleTypeItem[], filterDMTypes?: boolean, payl
items
}));
- if (payloadContext?.protocol === Protocol.FTP || payloadContext?.protocol === Protocol.CDC) {
+ if (payloadContext?.protocol === Protocol.FTP || payloadContext?.protocol === Protocol.SMB || payloadContext?.protocol === Protocol.CDC) {
categories = categories
.filter((category) => category.category === "User-Defined")
diff --git a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GeneralWidget.tsx b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GeneralWidget.tsx
index 18b82470b4c..2b4da68bfbb 100644
--- a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GeneralWidget.tsx
+++ b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GeneralWidget.tsx
@@ -122,6 +122,8 @@ function getCustomEntryNodeIcon(type: string) {
return ;
case "ftp":
return ;
+ case "smb":
+ return ;
case "file":
return ;
case "mssql":
diff --git a/workspaces/ballerina/type-editor/src/TypeEditor/ContextBasedTypeEditor/GenericImportTab.tsx b/workspaces/ballerina/type-editor/src/TypeEditor/ContextBasedTypeEditor/GenericImportTab.tsx
index 0adc8b2db51..75a452aac72 100644
--- a/workspaces/ballerina/type-editor/src/TypeEditor/ContextBasedTypeEditor/GenericImportTab.tsx
+++ b/workspaces/ballerina/type-editor/src/TypeEditor/ContextBasedTypeEditor/GenericImportTab.tsx
@@ -579,12 +579,14 @@ export function GenericImportTab(props: GenericImportTabProps) {
Generate Sample JSON
-
- or
-
+ {payloadContext?.protocol !== Protocol.FTP && payloadContext?.protocol !== Protocol.SMB && (
+
+ or
+
+ )}
>
)}
{payloadContext?.protocol!==Protocol.FTP && (
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file