diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1e7af925d01..d20386f8254 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,10 +2,17 @@ *.css @hevayo @gigara @tharindulak *.scss @hevayo @gigara @tharindulak .trivyignore @hevayo @gigara +/.github/ @hevayo @gigara @kanushka +**/package.json @hevayo @gigara @kanushka +**/package-lock.json @hevayo @gigara @kanushka +**/pnpm-lock.yaml @hevayo @gigara @kanushka +pnpm-workspace.yaml @hevayo @gigara @kanushka +rush.json @hevayo @gigara @kanushka +/common/ @hevayo @gigara @kanushka /workspaces/common-libs/ @hevayo @gigara @tharindulak /workspaces/mi/ @hevayo @gigara @kaumini /workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts @hevayo @axewilledge @kanushka /workspaces/ballerina/ballerina-rpc-client @hevayo @axewilledge @kanushka /workspaces/choreo/ @kaje94 /workspaces/wso2-platform/ @kaje94 -* @hevayo @gigara \ No newline at end of file +* @hevayo @gigara diff --git a/.trivyignore b/.trivyignore index 1326e396bab..66301551846 100644 --- a/.trivyignore +++ b/.trivyignore @@ -1,13 +1,6 @@ # Trivy ignore file for known low-risk vulnerabilities # Format: CVE-ID or vulnerability ID -# Low severity vulnerability in jsondiffpatch package -# Used as transitive dependency via 'ai' package -# Risk Assessment: LOW severity, limited impact on diff operations -# Decision: Acceptable risk - waiting for ai package to update jsondiffpatch dependency -# Related Issue: https://github.com/wso2/product-ballerina-integrator/issues/1274 -CVE-2025-9910 - # No fix released by the author # https://github.com/wso2/vscode-extensions/issues/550 CVE-2020-36851 diff --git a/.vscode/launch.json b/.vscode/launch.json index c96e935da9b..0893a35dbb3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -245,7 +245,8 @@ "--extensionTestsPath=${workspaceFolder}/workspaces/ballerina/ballerina-extension/out/test", "${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/bi_empty_project", "${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/bi_init", - "${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/simple_order_management_system","${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/ai_datamapper" + "${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/simple_order_management_system", + "${workspaceFolder}/workspaces/ballerina/ballerina-extension/test/data/ai_datamapper" ], "env": { "LS_EXTENSIONS_PATH": "", @@ -294,4 +295,4 @@ "preLaunchTask": "npm: watch-apk" }, ] -} +} \ No newline at end of file diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index 15ab1176ab2..6017c38f0ce 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -89,7 +89,8 @@ * Ppnpmdocumentation: https://pnpm.io/package_json#pnpmoverrides */ "globalOverrides": { - "tar-fs": "3.1.1" + "tar-fs": "3.1.1", + "jws": "3.2.3" // "example1": "^1.0.0", // "example2": "npm:@company/example2@^1.0.0" }, diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index e5f665a77d4..6a74887e8e9 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -6,6 +6,7 @@ settings: overrides: tar-fs: 3.1.1 + jws: 3.2.3 pnpmfileChecksum: sha256-XTeZQwJtKk4dimqf7175GhJCXrnq3Yh7+kwb86Bwcdo= @@ -54,7 +55,7 @@ importers: version: 0.4.14 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/api-designer-core': specifier: workspace:* version: link:../api-designer-core @@ -306,7 +307,7 @@ importers: version: 5.2.7(webpack@5.103.0) sass-loader: specifier: ^13.2.0 - version: 13.3.3(sass@1.94.1)(webpack@5.103.0) + version: 13.3.3(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^4.0.1 version: 4.0.2(webpack@5.103.0) @@ -354,7 +355,7 @@ importers: version: 2.5.2 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 copyfiles: specifier: ^2.4.1 version: 2.4.1 @@ -448,10 +449,13 @@ importers: dependencies: '@ai-sdk/amazon-bedrock': specifier: ^3.0.25 - version: 3.0.56(zod@4.1.11) + version: 3.0.65(zod@4.1.11) '@ai-sdk/anthropic': specifier: ^2.0.20 - version: 2.0.45(zod@4.1.11) + version: 2.0.53(zod@4.1.11) + '@iarna/toml': + specifier: ^2.2.5 + version: 2.2.5 '@types/lodash': specifier: ^4.14.200 version: 4.17.17 @@ -460,7 +464,7 @@ importers: version: 2.5.2 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/ballerina-core': specifier: workspace:* version: link:../ballerina-core @@ -481,7 +485,7 @@ importers: version: link:../../wso2-platform/wso2-platform-core ai: specifier: ^5.0.56 - version: 5.0.93(zod@4.1.11) + version: 5.0.106(zod@4.1.11) cors-anywhere: specifier: ^0.4.4 version: 0.4.4 @@ -524,9 +528,9 @@ importers: source-map-support: specifier: ^0.5.21 version: 0.5.21 - toml: - specifier: ^3.0.0 - version: 3.0.0 + unzipper: + specifier: ~0.12.3 + version: 0.12.3 uuid: specifier: ^11.1.0 version: 11.1.0 @@ -610,8 +614,8 @@ importers: specifier: ^4.6.2 version: 4.6.2 express: - specifier: ^4.18.2 - version: 4.21.2 + specifier: ^4.22.1 + version: 4.22.1 istanbul: specifier: ^0.4.5 version: 0.4.5 @@ -707,7 +711,7 @@ importers: version: 4.7.8 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) joi: specifier: ^17.13.3 version: 17.13.3 @@ -753,31 +757,31 @@ importers: version: 7.27.2(@babel/core@7.27.7) '@rollup/plugin-commonjs': specifier: ^28.0.3 - version: 28.0.9(rollup@4.53.2) + version: 28.0.9(rollup@4.53.3) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.53.2) + version: 6.1.0(rollup@4.53.3) '@rollup/plugin-node-resolve': specifier: ^16.0.1 - version: 16.0.3(rollup@4.53.2) + version: 16.0.3(rollup@4.53.3) '@storybook/addon-actions': specifier: ^6.5.16 version: 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addon-essentials': specifier: ^6.5.16 - version: 6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) + version: 6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) '@storybook/addon-links': specifier: ^6.5.16 version: 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/builder-webpack5': specifier: ^6.5.16 - version: 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + version: 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/manager-webpack5': specifier: ^6.5.9 - version: 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + version: 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/react': specifier: ^6.5.16 - version: 6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1) + version: 6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1) '@types/classnames': specifier: ^2.2.9 version: 2.3.4 @@ -807,7 +811,7 @@ importers: version: 10.0.0 '@types/webpack': specifier: ^5.28.5 - version: 5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + version: 5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) babel-loader: specifier: ^10.0.0 version: 10.0.0(@babel/core@7.27.7)(webpack@5.103.0) @@ -821,8 +825,8 @@ importers: specifier: ^7.1.2 version: 7.1.2(webpack@5.103.0) express: - specifier: ^5.1.0 - version: 5.1.0 + specifier: ^4.22.1 + version: 4.22.1 file-loader: specifier: ^6.2.0 version: 6.2.0(webpack@5.103.0) @@ -834,7 +838,7 @@ importers: version: 11.1.0 react-scripts-ts: specifier: ^3.1.0 - version: 3.1.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(babel-core@7.0.0-bridge.0(@babel/core@7.27.7))(babel-runtime@6.26.0)(typescript@5.8.3)(webpack-cli@6.0.1) + version: 3.1.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(babel-core@7.0.0-bridge.0(@babel/core@7.27.7))(babel-runtime@6.26.0)(typescript@5.8.3)(webpack-cli@6.0.1) react-test-renderer: specifier: ^19.1.0 version: 19.1.1(react@18.2.0) @@ -843,16 +847,16 @@ importers: version: 6.0.1 rollup: specifier: ^4.41.0 - version: 4.53.2 + version: 4.53.3 rollup-plugin-import-css: specifier: ^3.5.8 - version: 3.5.8(rollup@4.53.2) + version: 3.5.8(rollup@4.53.3) rollup-plugin-peer-deps-external: specifier: ^2.2.4 - version: 2.2.4(rollup@4.53.2) + version: 2.2.4(rollup@4.53.3) rollup-plugin-postcss: specifier: ^4.0.2 - version: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + version: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) rollup-plugin-scss: specifier: ^4.0.1 version: 4.0.1 @@ -861,13 +865,13 @@ importers: version: 2.0.0 rollup-plugin-typescript2: specifier: ^0.36.0 - version: 0.36.0(rollup@4.53.2)(typescript@5.8.3) + version: 0.36.0(rollup@4.53.3)(typescript@5.8.3) sass: specifier: ^1.89.0 - version: 1.94.1 + version: 1.94.2 sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) storybook: specifier: ^8.6.14 version: 8.6.14(prettier@3.5.3) @@ -876,10 +880,10 @@ importers: version: 4.0.0(webpack@5.103.0) stylelint: specifier: ^16.19.1 - version: 16.25.0(typescript@5.8.3) + version: 16.26.1(typescript@5.8.3) stylelint-config-standard: specifier: ^38.0.0 - version: 38.0.0(stylelint@16.25.0(typescript@5.8.3)) + version: 38.0.0(stylelint@16.26.1(typescript@5.8.3)) svg-url-loader: specifier: ^8.0.0 version: 8.0.0(webpack@5.103.0) @@ -903,7 +907,7 @@ importers: version: 5.8.3 webpack: specifier: ^5.94.0 - version: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + version: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.103.0) @@ -977,6 +981,12 @@ importers: '@codemirror/commands': specifier: ~6.10.0 version: 6.10.0 + '@codemirror/lang-sql': + specifier: ~6.10.0 + version: 6.10.0 + '@codemirror/language': + specifier: ~6.11.3 + version: 6.11.3 '@codemirror/state': specifier: ~6.5.2 version: 6.5.2 @@ -992,6 +1002,9 @@ importers: '@github/markdown-toolbar-element': specifier: ^2.2.3 version: 2.2.3 + '@lezer/highlight': + specifier: ~1.2.3 + version: 1.2.3 '@wso2/ballerina-core': specifier: workspace:* version: link:../ballerina-core @@ -1061,7 +1074,7 @@ importers: version: 5.0.1(react-hook-form@7.56.4(react@18.2.0)) '@tanstack/query-core': specifier: ^5.77.1 - version: 5.90.10 + version: 5.90.11 '@tanstack/react-query': specifier: 5.77.1 version: 5.77.1(react@18.2.0) @@ -1218,7 +1231,7 @@ importers: version: 0.4.24(eslint@9.27.0(jiti@2.6.1)) sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^5.0.0 version: 5.0.0(webpack@5.103.0) @@ -1300,7 +1313,7 @@ importers: version: 7.27.1(@babel/core@7.27.7) '@storybook/react': specifier: ^6.3.7 - version: 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1) + version: 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1) '@testing-library/dom': specifier: ~10.4.0 version: 10.4.1 @@ -1339,7 +1352,7 @@ importers: version: 3.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 @@ -1351,7 +1364,7 @@ importers: version: 19.1.1(react@18.2.0) ts-jest: specifier: 29.3.4 - version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) + version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1418,7 +1431,7 @@ importers: version: 7.27.1(@babel/core@7.27.7) '@storybook/react': specifier: ^6.5.16 - version: 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1) + version: 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1) '@testing-library/dom': specifier: ~10.4.0 version: 10.4.1 @@ -1457,7 +1470,7 @@ importers: version: 3.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 @@ -1469,7 +1482,7 @@ importers: version: 19.1.1(react@18.2.0) ts-jest: specifier: 29.3.4 - version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) + version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 @@ -1499,7 +1512,7 @@ importers: version: 6.7.4(lodash@4.17.21)(react@18.2.0)(resize-observer-polyfill@1.5.1) '@tanstack/query-core': specifier: ^5.77.1 - version: 5.90.10 + version: 5.90.11 '@tanstack/react-query': specifier: 5.77.1 version: 5.77.1(react@18.2.0) @@ -1547,7 +1560,7 @@ importers: version: 3.17.5 zustand: specifier: ^5.0.4 - version: 5.0.8(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)) + version: 5.0.9(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)) devDependencies: '@types/blueimp-md5': specifier: ^2.18.2 @@ -2218,7 +2231,7 @@ importers: version: 9.1.7 lint-staged: specifier: ^16.0.0 - version: 16.2.6 + version: 16.2.7 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -2273,7 +2286,7 @@ importers: version: 7.1.2(webpack@5.103.0) sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^5.0.0 version: 5.0.0(webpack@5.103.0) @@ -2504,15 +2517,15 @@ importers: ../../workspaces/bi/bi-extension: dependencies: + '@iarna/toml': + specifier: ^2.2.5 + version: 2.2.5 '@wso2/ballerina-core': specifier: workspace:* version: link:../../ballerina/ballerina-core '@wso2/font-wso2-vscode': specifier: workspace:* version: link:../../common-libs/font-wso2-vscode - toml: - specifier: ^3.0.0 - version: 3.0.0 xstate: specifier: ^4.38.3 version: 4.38.3 @@ -2540,7 +2553,7 @@ importers: version: 2.5.2 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/playwright-vscode-tester': specifier: workspace:* version: link:../../common-libs/playwright-vscode-tester @@ -2655,10 +2668,10 @@ importers: version: 5.0.0 yaml: specifier: ^2.6.0 - version: 2.8.1 + version: 2.8.2 zustand: specifier: ^5.0.5 - version: 5.0.8(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) + version: 5.0.9(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) devDependencies: '@biomejs/biome': specifier: ^1.8.3 @@ -2686,7 +2699,7 @@ importers: version: 3.0.4 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/playwright-vscode-tester': specifier: workspace:* version: link:../../common-libs/playwright-vscode-tester @@ -2707,7 +2720,7 @@ importers: version: 11.7.5 terser-webpack-plugin: specifier: ^5.3.10 - version: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + version: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-loader: specifier: ~9.5.2 version: 9.5.4(typescript@5.8.3)(webpack@5.103.0) @@ -2794,7 +2807,7 @@ importers: version: 4.0.1 swagger-ui-react: specifier: ^5.22.0 - version: 5.30.2(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.30.3(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) timezone-support: specifier: ^3.1.0 version: 3.1.0 @@ -2852,7 +2865,7 @@ importers: version: 8.2.0(postcss@8.5.6)(typescript@5.8.3)(webpack@5.103.0) sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^5.0.0 version: 5.0.0(webpack@5.103.0) @@ -2861,7 +2874,7 @@ importers: version: 4.0.0(webpack@5.103.0) tailwindcss: specifier: ^3.4.3 - version: 3.4.18(yaml@2.8.1) + version: 3.4.18(yaml@2.8.2) ts-loader: specifier: ^9.5.2 version: 9.5.4(typescript@5.8.3)(webpack@5.103.0) @@ -2900,7 +2913,7 @@ importers: version: 1.55.1 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 compare-versions: specifier: ~6.1.1 version: 6.1.1 @@ -3086,7 +3099,7 @@ importers: version: 9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3) '@storybook/react-vite': specifier: ^9.0.12 - version: 9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.53.2)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3) + version: 9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.53.3)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3) '@types/lodash': specifier: ~4.17.16 version: 4.17.17 @@ -3143,7 +3156,7 @@ importers: dependencies: '@modelcontextprotocol/inspector': specifier: ^0.17.2 - version: 0.17.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.18)(@types/react-dom@18.2.0)(@types/react@18.2.0)(typescript@5.8.3) + version: 0.17.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.18)(@types/react-dom@18.2.0)(@types/react@18.2.0)(typescript@5.8.3) devDependencies: '@types/mocha': specifier: ^10.0.3 @@ -3165,7 +3178,7 @@ importers: version: 2.5.2 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 copy-webpack-plugin: specifier: ^13.0.0 version: 13.0.1(webpack@5.103.0) @@ -3192,7 +3205,7 @@ importers: version: 5.8.3 webpack: specifier: ^5.94.0 - version: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@5.1.4) + version: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4) webpack-cli: specifier: ^5.1.4 version: 5.1.4(webpack@5.103.0) @@ -3278,7 +3291,7 @@ importers: devDependencies: '@eslint/eslintrc': specifier: ~3.3.1 - version: 3.3.1 + version: 3.3.3 '@eslint/js': specifier: ~9.27.0 version: 9.27.0 @@ -3320,7 +3333,7 @@ importers: version: 6.7.4(lodash@4.17.21)(react@18.2.0)(resize-observer-polyfill@1.5.1) '@tanstack/query-core': specifier: ^5.76.2 - version: 5.90.10 + version: 5.90.11 '@tanstack/react-query': specifier: 5.76.2 version: 5.76.2(react@18.2.0) @@ -3374,7 +3387,7 @@ importers: version: 3.17.5 zustand: specifier: ^5.0.5 - version: 5.0.8(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)) + version: 5.0.9(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)) devDependencies: '@types/blueimp-md5': specifier: ^2.18.2 @@ -3585,7 +3598,7 @@ importers: version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) '@storybook/react-webpack5': specifier: ^8.6.14 - version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) + version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) '@storybook/test': specifier: ^8.6.14 version: 8.6.14(storybook@8.6.14(prettier@3.5.3)) @@ -3630,7 +3643,7 @@ importers: version: 3.0.0 jest: specifier: ^30.0.0 - version: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + version: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 @@ -3645,7 +3658,7 @@ importers: version: 8.6.14(prettier@3.5.3) ts-jest: specifier: 29.3.4 - version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@30.2.0(@babel/core@7.27.7))(esbuild@0.25.12)(jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) + version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@30.2.0(@babel/core@7.27.7))(esbuild@0.25.12)(jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 @@ -3666,7 +3679,7 @@ importers: dependencies: '@ai-sdk/anthropic': specifier: ^2.0.35 - version: 2.0.45(zod@3.25.76) + version: 2.0.53(zod@3.25.76) '@apidevtools/json-schema-ref-parser': specifier: 12.0.2 version: 12.0.2 @@ -3702,7 +3715,7 @@ importers: version: 0.4.14 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/font-wso2-vscode': specifier: workspace:* version: link:../../common-libs/font-wso2-vscode @@ -3726,7 +3739,7 @@ importers: version: 0.5.16 ai: specifier: ^5.0.76 - version: 5.0.93(zod@3.25.76) + version: 5.0.106(zod@3.25.76) axios: specifier: ~1.12.0 version: 1.12.2 @@ -3895,7 +3908,7 @@ importers: version: 4.10.0(webpack@5.103.0) yaml: specifier: ~2.8.0 - version: 2.8.1 + version: 2.8.2 ../../workspaces/mi/mi-rpc-client: dependencies: @@ -3971,10 +3984,10 @@ importers: version: 1.55.1 '@pmmmwh/react-refresh-webpack-plugin': specifier: ~0.6.0 - version: 0.6.1(@types/webpack@5.28.5(webpack-cli@5.1.4))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0) + version: 0.6.2(@types/webpack@5.28.5(webpack-cli@5.1.4))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0) '@tanstack/query-core': specifier: ^5.76.0 - version: 5.90.10 + version: 5.90.11 '@tanstack/react-query': specifier: 5.76.1 version: 5.76.1(react@18.2.0) @@ -4134,7 +4147,7 @@ importers: version: 7.1.2(webpack@5.103.0) sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^5.0.0 version: 5.0.0(webpack@5.103.0) @@ -4161,7 +4174,7 @@ importers: version: 5.2.2(webpack-cli@5.1.4)(webpack@5.103.0) yaml: specifier: ~2.8.0 - version: 2.8.1 + version: 2.8.2 ../../workspaces/mi/syntax-tree: dependencies: @@ -4232,7 +4245,7 @@ importers: dependencies: '@aws-sdk/client-s3': specifier: ^3.817.0 - version: 3.933.0 + version: 3.943.0 '@vscode-logging/logger': specifier: ^2.0.0 version: 2.0.0 @@ -4286,13 +4299,13 @@ importers: version: 5.0.0 yaml: specifier: ^2.8.0 - version: 2.8.1 + version: 2.8.2 zod: specifier: ^3.22.4 version: 3.25.76 zustand: specifier: ^5.0.5 - version: 5.0.8(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) + version: 5.0.9(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)) devDependencies: '@biomejs/biome': specifier: ^1.9.4 @@ -4320,7 +4333,7 @@ importers: version: 3.0.4 '@vscode/vsce': specifier: ^3.7.0 - version: 3.7.0 + version: 3.7.1 '@wso2/playwright-vscode-tester': specifier: workspace:* version: link:../../common-libs/playwright-vscode-tester @@ -4341,7 +4354,7 @@ importers: version: 11.7.5 terser-webpack-plugin: specifier: ^5.3.14 - version: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + version: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-loader: specifier: ~9.5.2 version: 9.5.4(typescript@5.8.3)(webpack@5.103.0) @@ -4425,7 +4438,7 @@ importers: version: 4.0.1 swagger-ui-react: specifier: ^5.22.0 - version: 5.30.2(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.30.3(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) timezone-support: specifier: ^3.1.0 version: 3.1.0 @@ -4483,7 +4496,7 @@ importers: version: 8.2.0(postcss@8.5.6)(typescript@5.8.3)(webpack@5.103.0) sass-loader: specifier: ^16.0.5 - version: 16.0.6(sass@1.94.1)(webpack@5.103.0) + version: 16.0.6(sass@1.94.2)(webpack@5.103.0) source-map-loader: specifier: ^5.0.0 version: 5.0.0(webpack@5.103.0) @@ -4514,26 +4527,26 @@ packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - '@ai-sdk/amazon-bedrock@3.0.56': - resolution: {integrity: sha512-SncBHNNav14D5TOZilLX/FZHpPKwp8dixPj1FRut8YBGZ1Ou4gOqjR2eJ2NVsMiKi1X/Hb+Izo8vQcZ81AGSXg==} + '@ai-sdk/amazon-bedrock@3.0.65': + resolution: {integrity: sha512-E5KJv9OvLJitwPo6GnTgYdssTjEbwVW08TXqaQE2C6hfpg6XdwMXc7BJvQ97eXogGETAyFSS0irDYsbA90rB+g==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/anthropic@2.0.45': - resolution: {integrity: sha512-Ipv62vavDCmrV/oE/lXehL9FzwQuZOnnlhPEftWizx464Wb6lvnBTJx8uhmEYruFSzOWTI95Z33ncZ4tA8E6RQ==} + '@ai-sdk/anthropic@2.0.53': + resolution: {integrity: sha512-ih7NV+OFSNWZCF+tYYD7ovvvM+gv7TRKQblpVohg2ipIwC9Y0TirzocJVREzZa/v9luxUwFbsPji++DUDWWxsg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@2.0.9': - resolution: {integrity: sha512-E6x4h5CPPPJ0za1r5HsLtHbeI+Tp3H+YFtcH8G3dSSPFE6w+PZINzB4NxLZmg1QqSeA5HTP3ZEzzsohp0o2GEw==} + '@ai-sdk/gateway@2.0.18': + resolution: {integrity: sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@3.0.17': - resolution: {integrity: sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==} + '@ai-sdk/provider-utils@3.0.18': + resolution: {integrity: sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -4585,123 +4598,127 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.933.0': - resolution: {integrity: sha512-KxwZvdxdCeWK6o8mpnb+kk7Kgb8V+8AjTwSXUWH1UAD85B0tjdo1cSfE5zoR5fWGol4Ml5RLez12a6LPhsoTqA==} + '@aws-sdk/client-s3@3.943.0': + resolution: {integrity: sha512-UOX8/1mmNaRmEkxoIVP2+gxd5joPJqz+fygRqlIXON1cETLGoctinMwQs7qU8g8hghm76TU2G6ZV6sLH8cySMw==} + engines: {node: '>=18.0.0'} + + '@aws-sdk/client-sso@3.943.0': + resolution: {integrity: sha512-kOTO2B8Ks2qX73CyKY8PAajtf5n39aMe2spoiOF5EkgSzGV7hZ/HONRDyADlyxwfsX39Q2F2SpPUaXzon32IGw==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.933.0': - resolution: {integrity: sha512-zwGLSiK48z3PzKpQiDMKP85+fpIrPMF1qQOQW9OW7BGj5AuBZIisT2O4VzIgYJeh+t47MLU7VgBQL7muc+MJDg==} + '@aws-sdk/core@3.943.0': + resolution: {integrity: sha512-8CBy2hI9ABF7RBVQuY1bgf/ue+WPmM/hl0adrXFlhnhkaQP0tFY5zhiy1Y+n7V+5f3/ORoHBmCCQmcHDDYJqJQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.932.0': - resolution: {integrity: sha512-AS8gypYQCbNojwgjvZGkJocC2CoEICDx9ZJ15ILsv+MlcCVLtUJSRSx3VzJOUY2EEIaGLRrPNlIqyn/9/fySvA==} + '@aws-sdk/credential-provider-env@3.943.0': + resolution: {integrity: sha512-WnS5w9fK9CTuoZRVSIHLOMcI63oODg9qd1vXMYb7QGLGlfwUm4aG3hdu7i9XvYrpkQfE3dzwWLtXF4ZBuL1Tew==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.932.0': - resolution: {integrity: sha512-ozge/c7NdHUDyHqro6+P5oHt8wfKSUBN+olttiVfBe9Mw3wBMpPa3gQ0pZnG+gwBkKskBuip2bMR16tqYvUSEA==} + '@aws-sdk/credential-provider-http@3.943.0': + resolution: {integrity: sha512-SA8bUcYDEACdhnhLpZNnWusBpdmj4Vl67Vxp3Zke7SvoWSYbuxa+tiDiC+c92Z4Yq6xNOuLPW912ZPb9/NsSkA==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.932.0': - resolution: {integrity: sha512-b6N9Nnlg8JInQwzBkUq5spNaXssM3h3zLxGzpPrnw0nHSIWPJPTbZzA5Ca285fcDUFuKP+qf3qkuqlAjGOdWhg==} + '@aws-sdk/credential-provider-ini@3.943.0': + resolution: {integrity: sha512-BcLDb8l4oVW+NkuqXMlO7TnM6lBOWW318ylf4FRED/ply5eaGxkQYqdGvHSqGSN5Rb3vr5Ek0xpzSjeYD7C8Kw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.933.0': - resolution: {integrity: sha512-HygGyKuMG5AaGXsmM0d81miWDon55xwalRHB3UmDg3QBhtunbNIoIaWUbNTKuBZXcIN6emeeEZw/YgSMqLc0YA==} + '@aws-sdk/credential-provider-login@3.943.0': + resolution: {integrity: sha512-9iCOVkiRW+evxiJE94RqosCwRrzptAVPhRhGWv4osfYDhjNAvUMyrnZl3T1bjqCoKNcETRKEZIU3dqYHnUkcwQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.933.0': - resolution: {integrity: sha512-L2dE0Y7iMLammQewPKNeEh1z/fdJyYEU+/QsLBD9VEh+SXcN/FIyTi21Isw8wPZN6lMB9PDVtISzBnF8HuSFrw==} + '@aws-sdk/credential-provider-node@3.943.0': + resolution: {integrity: sha512-14eddaH/gjCWoLSAELVrFOQNyswUYwWphIt+PdsJ/FqVfP4ay2HsiZVEIYbQtmrKHaoLJhiZKwBQRjcqJDZG0w==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.932.0': - resolution: {integrity: sha512-BodZYKvT4p/Dkm28Ql/FhDdS1+p51bcZeMMu2TRtU8PoMDHnVDhHz27zASEKSZwmhvquxHrZHB0IGuVqjZUtSQ==} + '@aws-sdk/credential-provider-process@3.943.0': + resolution: {integrity: sha512-GIY/vUkthL33AdjOJ8r9vOosKf/3X+X7LIiACzGxvZZrtoOiRq0LADppdiKIB48vTL63VvW+eRIOFAxE6UDekw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.933.0': - resolution: {integrity: sha512-/R1DBR7xNcuZIhS2RirU+P2o8E8/fOk+iLAhbqeSTq+g09fP/F6W7ouFpS5eVE2NIfWG7YBFoVddOhvuqpn51g==} + '@aws-sdk/credential-provider-sso@3.943.0': + resolution: {integrity: sha512-1c5G11syUrru3D9OO6Uk+ul5e2lX1adb+7zQNyluNaLPXP6Dina6Sy6DFGRLu7tM8+M7luYmbS3w63rpYpaL+A==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.933.0': - resolution: {integrity: sha512-c7Eccw2lhFx2/+qJn3g+uIDWRuWi2A6Sz3PVvckFUEzPsP0dPUo19hlvtarwP5GzrsXn0yEPRVhpewsIaSCGaQ==} + '@aws-sdk/credential-provider-web-identity@3.943.0': + resolution: {integrity: sha512-VtyGKHxICSb4kKGuaqotxso8JVM8RjCS3UYdIMOxUt9TaFE/CZIfZKtjTr+IJ7M0P7t36wuSUb/jRLyNmGzUUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-bucket-endpoint@3.930.0': - resolution: {integrity: sha512-cnCLWeKPYgvV4yRYPFH6pWMdUByvu2cy2BAlfsPpvnm4RaVioztyvxmQj5PmVN5fvWs5w/2d6U7le8X9iye2sA==} + '@aws-sdk/middleware-bucket-endpoint@3.936.0': + resolution: {integrity: sha512-XLSVVfAorUxZh6dzF+HTOp4R1B5EQcdpGcPliWr0KUj2jukgjZEcqbBmjyMF/p9bmyQsONX80iURF1HLAlW0qg==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-expect-continue@3.930.0': - resolution: {integrity: sha512-5HEQ+JU4DrLNWeY27wKg/jeVa8Suy62ivJHOSUf6e6hZdVIMx0h/kXS1fHEQNNiLu2IzSEP/bFXsKBaW7x7s0g==} + '@aws-sdk/middleware-expect-continue@3.936.0': + resolution: {integrity: sha512-Eb4ELAC23bEQLJmUMYnPWcjD3FZIsmz2svDiXEcxRkQU9r7NRID7pM7C5NPH94wOfiCk0b2Y8rVyFXW0lGQwbA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.932.0': - resolution: {integrity: sha512-hyvRz/XS/0HTHp9/Ld1mKwpOi7bZu5olI42+T112rkCTbt1bewkygzEl4oflY4H7cKMamQusYoL0yBUD/QSEvA==} + '@aws-sdk/middleware-flexible-checksums@3.943.0': + resolution: {integrity: sha512-J2oYbAQXTFEezs5m2Vij6H3w71K1hZfCtb85AsR/2Ovp/FjABMnK+Es1g1edRx6KuMTc9HkL/iGU4e+ek+qCZw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.930.0': - resolution: {integrity: sha512-x30jmm3TLu7b/b+67nMyoV0NlbnCVT5DI57yDrhXAPCtdgM1KtdLWt45UcHpKOm1JsaIkmYRh2WYu7Anx4MG0g==} + '@aws-sdk/middleware-host-header@3.936.0': + resolution: {integrity: sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-location-constraint@3.930.0': - resolution: {integrity: sha512-QIGNsNUdRICog+LYqmtJ03PLze6h2KCORXUs5td/hAEjVP5DMmubhtrGg1KhWyctACluUH/E/yrD14p4pRXxwA==} + '@aws-sdk/middleware-location-constraint@3.936.0': + resolution: {integrity: sha512-SCMPenDtQMd9o5da9JzkHz838w3327iqXk3cbNnXWqnNRx6unyW8FL0DZ84gIY12kAyVHz5WEqlWuekc15ehfw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.930.0': - resolution: {integrity: sha512-vh4JBWzMCBW8wREvAwoSqB2geKsZwSHTa0nSt0OMOLp2PdTYIZDi0ZiVMmpfnjcx9XbS6aSluLv9sKx4RrG46A==} + '@aws-sdk/middleware-logger@3.936.0': + resolution: {integrity: sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.933.0': - resolution: {integrity: sha512-qgrMlkVKzTCAdNw2A05DC2sPBo0KRQ7wk+lbYSRJnWVzcrceJhnmhoZVV5PFv7JtchK7sHVcfm9lcpiyd+XaCA==} + '@aws-sdk/middleware-recursion-detection@3.936.0': + resolution: {integrity: sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.932.0': - resolution: {integrity: sha512-bYMHxqQzseaAP9Z5qLI918z5AtbAnZRRtFi3POb4FLZyreBMgCgBNaPkIhdgywnkqaydTWvbMBX4s9f4gUwlTw==} + '@aws-sdk/middleware-sdk-s3@3.943.0': + resolution: {integrity: sha512-kd2mALfthU+RS9NsPS+qvznFcPnVgVx9mgmStWCPn5Qc5BTnx4UAtm+HPA+XZs+zxOopp+zmAfE4qxDHRVONBA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-ssec@3.930.0': - resolution: {integrity: sha512-N2/SvodmaDS6h7CWfuapt3oJyn1T2CBz0CsDIiTDv9cSagXAVFjPdm2g4PFJqrNBeqdDIoYBnnta336HmamWHg==} + '@aws-sdk/middleware-ssec@3.936.0': + resolution: {integrity: sha512-/GLC9lZdVp05ozRik5KsuODR/N7j+W+2TbfdFL3iS+7un+gnP6hC8RDOZd6WhpZp7drXQ9guKiTAxkZQwzS8DA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.932.0': - resolution: {integrity: sha512-9BGTbJyA/4PTdwQWE9hAFIJGpsYkyEW20WON3i15aDqo5oRZwZmqaVageOD57YYqG8JDJjvcwKyDdR4cc38dvg==} + '@aws-sdk/middleware-user-agent@3.943.0': + resolution: {integrity: sha512-956n4kVEwFNXndXfhSAN5wO+KRgqiWEEY+ECwLvxmmO8uQ0NWOa8l6l65nTtyuiWzMX81c9BvlyNR5EgUeeUvA==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.933.0': - resolution: {integrity: sha512-o1GX0+IPlFi/D8ei9y/jj3yucJWNfPnbB5appVBWevAyUdZA5KzQ2nK/hDxiu9olTZlFEFpf1m1Rn3FaGxHqsw==} + '@aws-sdk/nested-clients@3.943.0': + resolution: {integrity: sha512-anFtB0p2FPuyUnbOULwGmKYqYKSq1M73c9uZ08jR/NCq6Trjq9cuF5TFTeHwjJyPRb4wMf2Qk859oiVfFqnQiw==} engines: {node: '>=18.0.0'} - '@aws-sdk/region-config-resolver@3.930.0': - resolution: {integrity: sha512-KL2JZqH6aYeQssu1g1KuWsReupdfOoxD6f1as2VC+rdwYFUu4LfzMsFfXnBvvQWWqQ7rZHWOw1T+o5gJmg7Dzw==} + '@aws-sdk/region-config-resolver@3.936.0': + resolution: {integrity: sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.932.0': - resolution: {integrity: sha512-NCIRJvoRc9246RZHIusY1+n/neeG2yGhBGdKhghmrNdM+mLLN6Ii7CKFZjx3DhxtpHMpl1HWLTMhdVrGwP2upw==} + '@aws-sdk/signature-v4-multi-region@3.943.0': + resolution: {integrity: sha512-KKvmxNQ/FZbM6ml6nKd8ltDulsUojsXnMJNgf1VHTcJEbADC/6mVWOq0+e9D0WP1qixUBEuMjlS2HqD5KoqwEg==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.933.0': - resolution: {integrity: sha512-Qzq7zj9yXUgAAJEbbmqRhm0jmUndl8nHG0AbxFEfCfQRVZWL96Qzx0mf8lYwT9hIMrXncLwy31HOthmbXwFRwQ==} + '@aws-sdk/token-providers@3.943.0': + resolution: {integrity: sha512-cRKyIzwfkS+XztXIFPoWORuaxlIswP+a83BJzelX4S1gUZ7FcXB4+lj9Jxjn8SbQhR4TPU3Owbpu+S7pd6IRbQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/types@3.930.0': - resolution: {integrity: sha512-we/vaAgwlEFW7IeftmCLlLMw+6hFs3DzZPJw7lVHbj/5HJ0bz9gndxEsS2lQoeJ1zhiiLqAqvXxmM43s0MBg0A==} + '@aws-sdk/types@3.936.0': + resolution: {integrity: sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==} engines: {node: '>=18.0.0'} '@aws-sdk/util-arn-parser@3.893.0': resolution: {integrity: sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.930.0': - resolution: {integrity: sha512-M2oEKBzzNAYr136RRc6uqw3aWlwCxqTP1Lawps9E1d2abRPvl1p1ztQmmXp1Ak4rv8eByIZ+yQyKQ3zPdRG5dw==} + '@aws-sdk/util-endpoints@3.936.0': + resolution: {integrity: sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==} engines: {node: '>=18.0.0'} '@aws-sdk/util-locate-window@3.893.0': resolution: {integrity: sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.930.0': - resolution: {integrity: sha512-q6lCRm6UAe+e1LguM5E4EqM9brQlDem4XDcQ87NzEvlTW6GzmNCO0w1jS0XgCFXQHjDxjdlNFX+5sRbHijwklg==} + '@aws-sdk/util-user-agent-browser@3.936.0': + resolution: {integrity: sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==} - '@aws-sdk/util-user-agent-node@3.932.0': - resolution: {integrity: sha512-/kC6cscHrZL74TrZtgiIL5jJNbVsw9duGGPurmaVgoCbP7NnxyaSWEurbNV3VPNPhNE3bV3g4Ci+odq+AlsYQg==} + '@aws-sdk/util-user-agent-node@3.943.0': + resolution: {integrity: sha512-gn+ILprVRrgAgTIBk2TDsJLRClzIOdStQFeFTcN0qpL8Z4GBCqMFhw7O7X+MM55Stt5s4jAauQ/VvoqmCADnQg==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -4713,8 +4730,8 @@ packages: resolution: {integrity: sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==} engines: {node: '>=18.0.0'} - '@aws/lambda-invoke-store@0.2.0': - resolution: {integrity: sha512-D1jAmAZQYMoPiacfgNf7AWhg3DFN3Wq/vQv3WINt9znwjzHp2x+WzdJFxxj7xZL7V1U79As6G8f7PorMYWBKsQ==} + '@aws/lambda-invoke-store@0.2.1': + resolution: {integrity: sha512-sIyFcoPZkTtNu9xFeEoynMef3bPJIAbOfUh+ueYcfhVl6xm2VRtMcMclSxmZCMnHHd4hlYKJeq/aggmBEWynww==} engines: {node: '>=18.0.0'} '@azu/format-text@1.0.2': @@ -4755,16 +4772,16 @@ packages: resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==} engines: {node: '>=20.0.0'} - '@azure/msal-browser@4.26.1': - resolution: {integrity: sha512-GGCIsZXxyNm5QcQZ4maA9q+9UWmM+/87G+ybvPkrE32el1URSa9WYt0t67ks3/P0gspZX9RoEqyLqJ/X/JDnBQ==} + '@azure/msal-browser@4.26.2': + resolution: {integrity: sha512-F2U1mEAFsYGC5xzo1KuWc/Sy3CRglU9Ql46cDUx8x/Y3KnAIr1QAq96cIKCk/ZfnVxlvprXWRjNKoEpgLJXLhg==} engines: {node: '>=0.8.0'} - '@azure/msal-common@15.13.1': - resolution: {integrity: sha512-vQYQcG4J43UWgo1lj7LcmdsGUKWYo28RfEvDQAEMmQIMjSFufvb+pS0FJ3KXmrPmnWlt1vHDl3oip6mIDUQ4uA==} + '@azure/msal-common@15.13.2': + resolution: {integrity: sha512-cNwUoCk3FF8VQ7Ln/MdcJVIv3sF73/OT86cRH81ECsydh7F4CNfIo2OAx6Cegtg8Yv75x4506wN4q+Emo6erOA==} engines: {node: '>=0.8.0'} - '@azure/msal-node@3.8.2': - resolution: {integrity: sha512-dQrex2LiXwlCe9WuBHnCsY+xxLyuMXSd2SDEYJuhqB7cE8u6QafiC1xy8j8eBjGO30AsRi2M6amH0ZKk7vJpjA==} + '@azure/msal-node@3.8.3': + resolution: {integrity: sha512-Ul7A4gwmaHzYWj2Z5xBDly/W8JSC1vnKgJ898zPMZr0oSf1ah0tiL15sytjycU/PMhDZAlkWtEL1+MzNMU6uww==} engines: {node: '>=16'} '@babel/code-frame@7.27.1': @@ -5586,11 +5603,11 @@ packages: cpu: [x64] os: [win32] - '@cacheable/memory@2.0.5': - resolution: {integrity: sha512-fkiAxCvssEyJZ5fxX4tcdZFRmW9JehSTGvvqmXn6rTzG5cH6V/3C4ad8yb01vOjp2xBydHkHrgpW0qeGtzt6VQ==} + '@cacheable/memory@2.0.6': + resolution: {integrity: sha512-7e8SScMocHxcAb8YhtkbMhGG+EKLRIficb1F5sjvhSYsWTZGxvg4KIDp8kgxnV2PUJ3ddPe6J9QESjKvBWRDkg==} - '@cacheable/utils@2.3.1': - resolution: {integrity: sha512-38NJXjIr4W1Sghun8ju+uYWD8h2c61B4dKwfnQHVDFpAJ9oS28RpfqZQJ6Dgd3RceGkILDY9YT+72HJR3LoeSQ==} + '@cacheable/utils@2.3.2': + resolution: {integrity: sha512-8kGE2P+HjfY8FglaOiW+y8qxcaQAfAhVML+i66XJR3YX5FtyDqn6Txctr3K2FrbxLKixRRYYBWMbuGciOhYNDg==} '@cnakazawa/watch@1.0.4': resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} @@ -5723,6 +5740,10 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-syntax-patches-for-csstree@1.0.20': + resolution: {integrity: sha512-8BHsjXfSciZxjmHQOuVdW2b8WLUPts9a+mfL13/PzEviufUEW2xnvQuOlKs9dRBHgRqJ53SF/DUoK9+MZk72oQ==} + engines: {node: '>=18'} + '@csstools/css-tokenizer@3.0.4': resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} @@ -6027,8 +6048,8 @@ packages: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@8.57.1': @@ -6567,8 +6588,8 @@ packages: peerDependencies: yjs: '>=13.5.22' - '@lezer/common@1.3.0': - resolution: {integrity: sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ==} + '@lezer/common@1.4.0': + resolution: {integrity: sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg==} '@lezer/cpp@1.1.3': resolution: {integrity: sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w==} @@ -6594,8 +6615,8 @@ packages: '@lezer/json@1.0.3': resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} - '@lezer/lr@1.4.3': - resolution: {integrity: sha512-yenN5SqAxAPv/qMnpWW0AT7l+SxVrgG+u0tNsRQWqbrz66HIl8DnEbBObvy21J5K7+I1v7gsAnlE2VQ5yYVSeA==} + '@lezer/lr@1.4.4': + resolution: {integrity: sha512-LHL17Mq0OcFXm1pGQssuGTQFPPdxARjKM8f7GA5+sGtHi0K3R84YaSbmche0+RKWHnCsx9asEe5OWOI4FHfe4A==} '@lezer/markdown@1.6.0': resolution: {integrity: sha512-AXb98u3M6BEzTnreBnGtQaF7xFTiMA92Dsy5tqEjpacbjRxDSFdN4bKJo9uvU4cEEOS7D2B9MT7kvDgOEIzJSw==} @@ -6720,8 +6741,8 @@ packages: engines: {node: '>=22.7.5'} hasBin: true - '@modelcontextprotocol/sdk@1.22.0': - resolution: {integrity: sha512-VUpl106XVTCpDmTBil2ehgJZjhyLY2QZikzF8NvTXtLRF1CvO5iEE2UNZdVIUer35vFOwMKYeUGbjJtvPWan3g==} + '@modelcontextprotocol/sdk@1.24.0': + resolution: {integrity: sha512-D8h5KXY2vHFW8zTuxn2vuZGN0HGrQ5No6LkHwlEA9trVgNdPL3TF1dSqKA7Dny6BbBYKSW/rOBDXdC8KJAjUCg==} engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 @@ -6729,8 +6750,8 @@ packages: '@cfworker/json-schema': optional: true - '@monaco-editor/loader@1.6.1': - resolution: {integrity: sha512-w3tEnj9HYEC73wtjdpR089AqkUPskFRcdkxsiSFt3SoUc3OHpmu+leP94CXBm4mHfefmhsdfI0ZQu6qJ0wgtPg==} + '@monaco-editor/loader@1.7.0': + resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==} '@monaco-editor/react@4.7.0': resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==} @@ -6954,14 +6975,14 @@ packages: webpack-plugin-serve: optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.6.1': - resolution: {integrity: sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==} + '@pmmmwh/react-refresh-webpack-plugin@0.6.2': + resolution: {integrity: sha512-IhIAD5n4XvGHuL9nAgWfsBR0TdxtjrUWETYKCBHxauYXEv+b+ctEbs9neEgPC7Ecgzv4bpZTBwesAoGDeFymzA==} engines: {node: '>=18.12'} peerDependencies: '@types/webpack': 5.x react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 - type-fest: '>=0.17.0 <5.0.0' + type-fest: '>=0.17.0 <6.0.0' webpack: ^5.0.0 webpack-dev-server: ^4.8.0 || 5.x webpack-hot-middleware: 2.x @@ -7957,113 +7978,113 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.53.2': - resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.53.2': - resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.2': - resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.2': - resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.2': - resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.2': - resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': - resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.53.2': - resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.53.2': - resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.53.2': - resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.53.2': - resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.53.2': - resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.53.2': - resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.53.2': - resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.53.2': - resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.53.2': - resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.53.2': - resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.53.2': - resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.53.2': - resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.2': - resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.2': - resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.53.2': - resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} cpu: [x64] os: [win32] @@ -8206,8 +8227,8 @@ packages: resolution: {integrity: sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==} engines: {node: '>=18.0.0'} - '@smithy/core@3.18.4': - resolution: {integrity: sha512-o5tMqPZILBvvROfC8vC+dSVnWJl9a0u9ax1i1+Bq8515eYjUJqqk5XjjEsDLoeL5dSqGSh6WGdVx1eJ1E/Nwhw==} + '@smithy/core@3.18.6': + resolution: {integrity: sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.2.5': @@ -8270,12 +8291,12 @@ packages: resolution: {integrity: sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.3.11': - resolution: {integrity: sha512-eJXq9VJzEer1W7EQh3HY2PDJdEcEUnv6sKuNt4eVjyeNWcQFS4KmnY+CKkYOIR6tSqarn6bjjCqg1UB+8UJiPQ==} + '@smithy/middleware-endpoint@4.3.13': + resolution: {integrity: sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.11': - resolution: {integrity: sha512-EL5OQHvFOKneJVRgzRW4lU7yidSwp/vRJOe542bHgExN3KNThr1rlg0iE4k4SnA+ohC+qlUxoK+smKeAYPzfAQ==} + '@smithy/middleware-retry@4.4.13': + resolution: {integrity: sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@4.2.6': @@ -8322,8 +8343,8 @@ packages: resolution: {integrity: sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.9.7': - resolution: {integrity: sha512-pskaE4kg0P9xNQWihfqlTMyxyFR3CH6Sr6keHYghgyqqDXzjl2QJg5lAzuVe/LzZiOzcbcVtxKYi1/fZPt/3DA==} + '@smithy/smithy-client@4.9.9': + resolution: {integrity: sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA==} engines: {node: '>=18.0.0'} '@smithy/types@4.9.0': @@ -8358,12 +8379,12 @@ packages: resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.10': - resolution: {integrity: sha512-3iA3JVO1VLrP21FsZZpMCeF93aqP3uIOMvymAT3qHIJz2YlgDeRvNUspFwCNqd/j3qqILQJGtsVQnJZICh/9YA==} + '@smithy/util-defaults-mode-browser@4.3.12': + resolution: {integrity: sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.13': - resolution: {integrity: sha512-PTc6IpnpSGASuzZAgyUtaVfOFpU0jBD2mcGwrgDuHf7PlFgt5TIPxCYBDbFQs06jxgeV3kd/d/sok1pzV0nJRg==} + '@smithy/util-defaults-mode-node@4.2.15': + resolution: {integrity: sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.2.5': @@ -9356,95 +9377,95 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@swagger-api/apidom-ast@1.0.0-rc.3': - resolution: {integrity: sha512-lGxvtanmQYqepjVWwPROR/97BIP3sUtwzoHbMSMag2/C3+Un8p6Xz8+I+1sPG2UOBlvDsQe3Di0hlSET7EFwAQ==} + '@swagger-api/apidom-ast@1.0.0-rc.4': + resolution: {integrity: sha512-IaXz00VLMq0Kw5vh5f2MX4gNWzPy8ujBl5FInM5w+1mezoyrwTnVRiKO7sf611OthmNmnK5cWy3hjqURAT9wCQ==} - '@swagger-api/apidom-core@1.0.0-rc.3': - resolution: {integrity: sha512-cRf+HzoXl3iDPc7alVxdPbLb1TqRePqsxI0id2KaB8HYbyxTUy3ygqY/jmxGtfAAK0Ba85Bw8j4N0crw23vLTg==} + '@swagger-api/apidom-core@1.0.0-rc.4': + resolution: {integrity: sha512-dSvq/FmUffmv9nqBO8LZ5+ESFWPe/y7UsatRiwpqh6M7vBHy9xBuKdn6A/7QtmZnetjigkx3h4CXc4Mi30RZCg==} - '@swagger-api/apidom-error@1.0.0-rc.3': - resolution: {integrity: sha512-E9WsxzR9wwD4+1zmZm9PVvxXBAYxMtGJjpRYR/FthvxhIwx+Vsey2h5k7FPS8yJsawIrdGPQtdiFMLPvnQXUFg==} + '@swagger-api/apidom-error@1.0.0-rc.4': + resolution: {integrity: sha512-uakMfKYyLgGjLrVaaUKWyl0D+wGxza+nh1Ct4fOFRiy0Dm91I4AD4HwsG3Uvk5gLrvqlf/OutKYzKt8Ufhlyig==} - '@swagger-api/apidom-json-pointer@1.0.0-rc.3': - resolution: {integrity: sha512-cj83L5ntai/RJcZV0++lQiCHPWE6lTy62bGC2lQ0yi/kyCc+Ig+Sn08qpiLSrkQ4OooK85X+wgAy6pMK+Vt/8Q==} + '@swagger-api/apidom-json-pointer@1.0.0-rc.4': + resolution: {integrity: sha512-5bB6nemgzkWs440a8PX+lS3fGtEtJt2iYhK0Xf9E+9qU6d1eR9aiETPdAVjbdL8vLhyZvmgvZie/7q0l6bbLJg==} - '@swagger-api/apidom-ns-api-design-systems@1.0.0-rc.3': - resolution: {integrity: sha512-JB06VDEKPvyOcJ9qIJmr2vI2FSWjdZh+BiRExZPW4tv/mTvdOxt1n38WA+mKzfFHQuoTR4ork/wR481CjAfGGQ==} + '@swagger-api/apidom-ns-api-design-systems@1.0.0-rc.4': + resolution: {integrity: sha512-JlOD1H2jSl/XxdFwa/zPOvRZh8rk/O/2B2xkoKaxhTmkVTKq2Y1rHsey8cyU9qrfQSkLpPm1cxXeIfqmhdPmqQ==} - '@swagger-api/apidom-ns-arazzo-1@1.0.0-rc.3': - resolution: {integrity: sha512-Um0MGGsGLQWvnASDoguSuE5X/NpS/9RlXlOHHG5nqzG2cdTlifRcN5tiz7H997162+ahEsD5aHD6tUKWOPCLtQ==} + '@swagger-api/apidom-ns-arazzo-1@1.0.0-rc.4': + resolution: {integrity: sha512-sKep7qCvJa2zB4q67e9zinLKjVx0vhV/e40OLEg3JeECMWcRrW3oI2JB3jSJ7ZZwCgvatfBc6/ucFsX/1oKpkg==} - '@swagger-api/apidom-ns-asyncapi-2@1.0.0-rc.3': - resolution: {integrity: sha512-UFmnbvEsN7jVvS/8V7X37UPvn8uxdqYBhDzdPSivjxpu/5Ag5Q1P2gHJnO6K2EfTCFL4S1qDObW2TUFdV1b6pg==} + '@swagger-api/apidom-ns-asyncapi-2@1.0.0-rc.4': + resolution: {integrity: sha512-RDNKv4kCAzQ+aA02VjgxS9Cve0UgnRkcFNEUxYEHWNbqVcMmxcck6GLQo4OuwhgJczEyZC3TB5idfxphRhaybg==} - '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-rc.3': - resolution: {integrity: sha512-fxQo/GK5NGdx4gN2snj4DpBcDc8bORLehTUqcwp33ikJ2PGugtpV3IQrBjxSWP05PyLOZAMpq1SM9gkCPgZNRA==} + '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-rc.4': + resolution: {integrity: sha512-kgIo3d9VZjBFg30Cg0asokbBGVb4WvVckkf9U2T8/6wh2o1J+KMqvdRauo2Xz+o5EubLpGyZjrwOzMbFJv/viA==} - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-rc.3': - resolution: {integrity: sha512-iDPbua9HajFwkH9vFUIbkmKVI/VXKuV9G+jLGkyBlF/Zu++1Rv6CstBt+F9CgNThSUqkKt3YA9Rcd82uh1+HnQ==} + '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-rc.4': + resolution: {integrity: sha512-0mpBu8iXq8GaY+KDQGWSU+8Xvd1Kd5EXKOpW8tDgJINBgeYm7F3m8iP3irP0OMeCyX9ISMq+bDgXg+YjS8kYzA==} - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-rc.3': - resolution: {integrity: sha512-8lft8qCo/KAHqiUpfwUMifP9JDhuhXKMNYSSahP2SN0PnbujoS1h3DOXtpR9/+0N6fKPUT8I6GLEwgq8TX2yvA==} + '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-rc.4': + resolution: {integrity: sha512-FOqR+EMMt5QPXmQv/gJ/syzp+G5QCrb+5n3tkmVwBNKhiPHcX4kOHt6/8wZo/6V++hhv1IzCt1JwGJGiNEuK9A==} - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-rc.3': - resolution: {integrity: sha512-IDC+98ur+7L3YaZZnnCytx9+cihElj24CcjX/X2mOBqOTaAwZ/Exb7LiBnvUswV1lOE2X2CX4donRemjk+e32Q==} + '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-rc.4': + resolution: {integrity: sha512-OQonOTVyPzKUvE2+6AB+JK7rkqqd0AG0QyarSyPJH+vbt2Nsj2tUaEXNY3WeP9OX1xvbtUysR74fefsOkjzO1Q==} - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-rc.3': - resolution: {integrity: sha512-P0dk9WhH7CINBCh1u8GfcQFycrZcw3qCXug0w6M0wiSrjqZv+Mv/AI68dc0Rb+Dzshe4aZy0bZFjAQb3NHfrSg==} + '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-rc.4': + resolution: {integrity: sha512-p1YbbkHQDD0REbz30F/vMXjPjsh7j7jIjaHNgFv3zC+KZN776GkOwQIpdP56lwneWFdMj9jOSRhwBKp34h9iXw==} - '@swagger-api/apidom-ns-openapi-2@1.0.0-rc.3': - resolution: {integrity: sha512-zwriSfjG+qiPWBHLZRyfdZa305xrB24aZjiAY8r2ikZsdQhC/WHI+e6YqeVCkJwkLzA/oZgrlmyci0mvtkFDQA==} + '@swagger-api/apidom-ns-openapi-2@1.0.0-rc.4': + resolution: {integrity: sha512-Wil2egcmJJIrgEDYGZVaDIMGlnLhcBw8I5ZjWBgyU8nLocuqdKVE8I1TwPO+7830dnfjCaXs+nUzfgkBcGefMg==} - '@swagger-api/apidom-ns-openapi-3-0@1.0.0-rc.3': - resolution: {integrity: sha512-RCufXt7ja7fqFS/EqWOMZ54J4uEnqPQkCXMwwCqUrFHXQ7nGN1J9nmwj2hFQUFYraajmtnk2dNByO46+XefV1w==} + '@swagger-api/apidom-ns-openapi-3-0@1.0.0-rc.4': + resolution: {integrity: sha512-t4ZX6I76fcrCsV1Aj8Um6LiIceVCKNgakg5MIuBiRZaA0q8fZPerLSD1KIYMLWPd+cV5ptKZyv+bugzhlhQtTg==} - '@swagger-api/apidom-ns-openapi-3-1@1.0.0-rc.3': - resolution: {integrity: sha512-Nc28G/ikbypcXVricv8+PGEGXKAmOwZjkBxB3wN5D4+D0+AiUy1lV07Z7+xFWdql65Y5WWxxfU2/Ej01Bnqt4Q==} + '@swagger-api/apidom-ns-openapi-3-1@1.0.0-rc.4': + resolution: {integrity: sha512-Ibv8PP0npBb8QupINmluQmLCZ1IhANlRUic8K7k32Lbc9ejMGTLCKGl2J3hPPeKsER3zqfEjHAhkins9r/CJcw==} - '@swagger-api/apidom-parser-adapter-api-design-systems-json@1.0.0-rc.3': - resolution: {integrity: sha512-ZXKuMd6nqBrpCqTJmbd2pS46ZmL8bIra1KqWVjcvkA/E032nmgDeaT78Cf0Ulha6j+CAzcwL0AnR7GrtFpSfSw==} + '@swagger-api/apidom-parser-adapter-api-design-systems-json@1.0.0-rc.4': + resolution: {integrity: sha512-/K9xj7tL6RB6B+krFf5JlzEGb3bebVt5c6t9a0ZZps+4TjcAQ3M1B9Gs3+ngR6Hy2RwtqIPKWKl0fhgfpArmnw==} - '@swagger-api/apidom-parser-adapter-api-design-systems-yaml@1.0.0-rc.3': - resolution: {integrity: sha512-Qg1yTPPzGF3EhlqcxIZeDVBxxvZzylGM6CTHg5cltGOSoFQ7+NJFE9Ktvk0gbVaFUyElFduCno9FvIfzxPlj8g==} + '@swagger-api/apidom-parser-adapter-api-design-systems-yaml@1.0.0-rc.4': + resolution: {integrity: sha512-+J4hMSe7+cKxuDDEVxyF7MGfvAFv7cbFdyBKUDkvkKjtdkh40+5msTJ2ePuSxibNqZTJFGZhaJBIaPOfbqLpUQ==} - '@swagger-api/apidom-parser-adapter-arazzo-json-1@1.0.0-rc.3': - resolution: {integrity: sha512-T7MbfTSDqdHgSr+cSC6gcGIsiwK3NXmdo28ZUv6LWsgcWDj2zw2Jie+7rXQaDN3JFEL34M/BIcMLyvrG7gYN/Q==} + '@swagger-api/apidom-parser-adapter-arazzo-json-1@1.0.0-rc.4': + resolution: {integrity: sha512-7sDeZgV1SVwiWQmckvRgBwEBZXUavxvJr5m8C2daEge9DTM9LE3qNBAjWdwvd5E4sPeDdslSiCWT9Ipi+aiBsg==} - '@swagger-api/apidom-parser-adapter-arazzo-yaml-1@1.0.0-rc.3': - resolution: {integrity: sha512-mUmxQVXPoemP2ak/77g/o8kpP2DNd1EDjteuyGHyw1EHk/t4xYPAP05rQ2DfIQ5yVHmxBKRDQ15kfVNEpfUfYQ==} + '@swagger-api/apidom-parser-adapter-arazzo-yaml-1@1.0.0-rc.4': + resolution: {integrity: sha512-UnU6RLRKNMm0qbHjINbfrFgKQd6tD2pRKySWgR9HxLVS+VTL3J4Oid2Tt3ND5xy6nE4qZrV5vusZNkdDewZk7A==} - '@swagger-api/apidom-parser-adapter-asyncapi-json-2@1.0.0-rc.3': - resolution: {integrity: sha512-K2BaslenC4ouPyzOQSB7wQPSsIGKGIj4VfP4M9y3fJaX9dIi+z3kzYQV7NFhZHAnq6pVybIDA44FLHF/WLCxUg==} + '@swagger-api/apidom-parser-adapter-asyncapi-json-2@1.0.0-rc.4': + resolution: {integrity: sha512-fZJgQWRXQxPcZurKxiY2IcdtuS33CxuJyFD9Z+72v3OvVWFEII6mWGC6NdqevzYaD7WUVXhsQjAqibBNIcyJiQ==} - '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@1.0.0-rc.3': - resolution: {integrity: sha512-xJezoi5d+RtV7sG9VRcfpbLlJwaR6GoJr2S8lbsnMUkk/B2vZGdRbA2Fc67REQIJTEfxXcU8T3+5m8j0WrG9Xw==} + '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@1.0.0-rc.4': + resolution: {integrity: sha512-WNmlRSHiCLu9uCsadnoaWYxzV/aagUHAeVTY+Zgq+4bSNWx9DZTX5X1v/IW4aD5MAW6j1Inz8U5qdxWnrEdBBg==} - '@swagger-api/apidom-parser-adapter-json@1.0.0-rc.3': - resolution: {integrity: sha512-Y0dfIYvQE+OLjormlx6RjmA6ymNA6+nkqJC/6qkFt+4fSjfOiXwbOOnfZp9pJXb2ssmDDdrPTFc3ninx5k7jNw==} + '@swagger-api/apidom-parser-adapter-json@1.0.0-rc.4': + resolution: {integrity: sha512-UuYtpZtXoWuukny/1WIz2szlfKc6XDNh0W1E8PtZqhFOUDgaq0qXB7OBB7E/lDAJAIzlWfJu1lR87C2pwbJSRw==} - '@swagger-api/apidom-parser-adapter-openapi-json-2@1.0.0-rc.3': - resolution: {integrity: sha512-yaMS11FZVJLF062s+dch1kmUvBqdIS6mwAg/4XUL7XwSYat6pnV2ONCqdcUO9JSc9KJMZQiVAZjAZSj096ssNg==} + '@swagger-api/apidom-parser-adapter-openapi-json-2@1.0.0-rc.4': + resolution: {integrity: sha512-2OgY9MO0U2Ma7OiIOvsT7cn0J5XbfWy9JnOEGm6DCh+b1m+NGWSXuPKGB9o/R3DJu5Jar9ol7Mu+oyb6ENJKdg==} - '@swagger-api/apidom-parser-adapter-openapi-json-3-0@1.0.0-rc.3': - resolution: {integrity: sha512-5OdImG3eEgYpFvSo0EiZVvJJahk+f6cm5WZNn9lVdRlmxmtpzKM3UNfIYcBgVcAcLvfi8g6G7xRzD1DshaS8sw==} + '@swagger-api/apidom-parser-adapter-openapi-json-3-0@1.0.0-rc.4': + resolution: {integrity: sha512-XvZsBuUO2UY5qXsizw03A+dy745ZWvekwS0J3o5RmPoEuJ1eeRNXsUn+JoAHascX81vzlkam71Xp9XpcAlybYQ==} - '@swagger-api/apidom-parser-adapter-openapi-json-3-1@1.0.0-rc.3': - resolution: {integrity: sha512-UWlH29DOqKfHF2zwv7r5b7pgrc7Yxdus7FjYWA8p8yoIB02xDwHBaH4KhccIAXkm1qNMo+4TwSKFvO/boE8LMA==} + '@swagger-api/apidom-parser-adapter-openapi-json-3-1@1.0.0-rc.4': + resolution: {integrity: sha512-cydbVKumtVTTfTnbtvfw1kayYRbQyTS6iZ5s/Y6xyZb7ro5VNi6XZy6htOu0EvXUBS/NJjY9YDeWcVKGUEuohw==} - '@swagger-api/apidom-parser-adapter-openapi-yaml-2@1.0.0-rc.3': - resolution: {integrity: sha512-kSWzmalm98ScImQHHtpTBDAIEzLsfE24Pe1IIJP1TaI2rk1AuxzaCsqMl6NQIlnIEawghPOXlG0hLsgtswn/Jg==} + '@swagger-api/apidom-parser-adapter-openapi-yaml-2@1.0.0-rc.4': + resolution: {integrity: sha512-pqoPgMFOvJJ2v4qA9MKMnTlhOYST+o2WhYmY34GMCoZrRrHue0rnvjtsAyH9BQNk9WEmS1gdonKpyHl6a5bewQ==} - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@1.0.0-rc.3': - resolution: {integrity: sha512-IRxjOgmGpaA1ay/NITOqk3TKTXnGiJtNP8KsPm//i+HkGcg87lZEvRDflB2Z70aRofKncXM2rCMAEqFqV7A9ug==} + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@1.0.0-rc.4': + resolution: {integrity: sha512-7J+iWKNC6pjWGAsOy5it2FDJGYyiDJ+rvIrUFAiK3Giqk9t70/s6PmH54DtVnb8rzmpX/udd8PVxTE6uImru1Q==} - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@1.0.0-rc.3': - resolution: {integrity: sha512-uvDMPiKt7uZSAOUVe+q/AygTFXw1odxxu5mi5voQM3/0KbR/vlt8f1dO9sQkys+G6ped2nL4r8B0p6bXR8uAMQ==} + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@1.0.0-rc.4': + resolution: {integrity: sha512-N3ehKEKvEWkZjL6QAV4Fwepa+2lSSun8DYN1h+ScVMa/QSWQh558vSXv6cF49ClYIO+IQjZg1fsbDoVg7qjlcA==} - '@swagger-api/apidom-parser-adapter-yaml-1-2@1.0.0-rc.3': - resolution: {integrity: sha512-IiLIw74NRpRwi2YkV1hzmHC5JvvAm/TdeVYZoYK0QxeT2Ozr6MvhnUnRFjjSL3wcmku9+rLz2d8EGL2kO46qRA==} + '@swagger-api/apidom-parser-adapter-yaml-1-2@1.0.0-rc.4': + resolution: {integrity: sha512-go/s36rTmkgVIBt4Q/oAJzwRTwRjVdFQPeQGnuS6eX5mxMUWxzVrsKKLJ2qul5y8DVkzZsZ6K897RI5H0fUuuQ==} - '@swagger-api/apidom-reference@1.0.0-rc.3': - resolution: {integrity: sha512-xZ9B6lGpdlHGSZGEhYe/MAyULCN4d+w4LKK5P1C/i6W6AU4iDEMjMjSawRV9ptJcObnu9ArEe92rgI7XS6s0TQ==} + '@swagger-api/apidom-reference@1.0.0-rc.4': + resolution: {integrity: sha512-H0eVImmOEp8TjRBcVQuyBsCcUCR5094POMcgvcipUyKwAus62PwMivn1eQc+e/wyZSm7qqEbv1ksOcDLHltykA==} '@swaggerexpert/cookie@2.0.2': resolution: {integrity: sha512-DPI8YJ0Vznk4CT+ekn3rcFNq1uQwvUHZhH6WvTSPD0YKBIlMS9ur2RYKghXuxxOiqOam/i4lHJH4xTIiTgs3Mg==} @@ -9454,68 +9475,68 @@ packages: resolution: {integrity: sha512-qMx1nOrzoB+PF+pzb26Q4Tc2sOlrx9Ba2UBNX9hB31Omrq+QoZ2Gly0KLrQWw4Of1AQ4J9lnD+XOdwOdcdXqqw==} engines: {node: '>=12.20.0'} - '@swc/core-darwin-arm64@1.15.2': - resolution: {integrity: sha512-Ghyz4RJv4zyXzrUC1B2MLQBbppIB5c4jMZJybX2ebdEQAvryEKp3gq1kBksCNsatKGmEgXul88SETU19sMWcrw==} + '@swc/core-darwin-arm64@1.15.3': + resolution: {integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.2': - resolution: {integrity: sha512-7n/PGJOcL2QoptzL42L5xFFfXY5rFxLHnuz1foU+4ruUTG8x2IebGhtwVTpaDN8ShEv2UZObBlT1rrXTba15Zw==} + '@swc/core-darwin-x64@1.15.3': + resolution: {integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.2': - resolution: {integrity: sha512-ZUQVCfRJ9wimuxkStRSlLwqX4TEDmv6/J+E6FicGkQ6ssLMWoKDy0cAo93HiWt/TWEee5vFhFaSQYzCuBEGO6A==} + '@swc/core-linux-arm-gnueabihf@1.15.3': + resolution: {integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.2': - resolution: {integrity: sha512-GZh3pYBmfnpQ+JIg+TqLuz+pM+Mjsk5VOzi8nwKn/m+GvQBsxD5ectRtxuWUxMGNG8h0lMy4SnHRqdK3/iJl7A==} + '@swc/core-linux-arm64-gnu@1.15.3': + resolution: {integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.15.2': - resolution: {integrity: sha512-5av6VYZZeneiYIodwzGMlnyVakpuYZryGzFIbgu1XP8wVylZxduEzup4eP8atiMDFmIm+s4wn8GySJmYqeJC0A==} + '@swc/core-linux-arm64-musl@1.15.3': + resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.15.2': - resolution: {integrity: sha512-1nO/UfdCLuT/uE/7oB3EZgTeZDCIa6nL72cFEpdegnqpJVNDI6Qb8U4g/4lfVPkmHq2lvxQ0L+n+JdgaZLhrRA==} + '@swc/core-linux-x64-gnu@1.15.3': + resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.15.2': - resolution: {integrity: sha512-Ksfrb0Tx310kr+TLiUOvB/I80lyZ3lSOp6cM18zmNRT/92NB4mW8oX2Jo7K4eVEI2JWyaQUAFubDSha2Q+439A==} + '@swc/core-linux-x64-musl@1.15.3': + resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.15.2': - resolution: {integrity: sha512-IzUb5RlMUY0r1A9IuJrQ7Tbts1wWb73/zXVXT8VhewbHGoNlBKE0qUhKMED6Tv4wDF+pmbtUJmKXDthytAvLmg==} + '@swc/core-win32-arm64-msvc@1.15.3': + resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.2': - resolution: {integrity: sha512-kCATEzuY2LP9AlbU2uScjcVhgnCAkRdu62vbce17Ro5kxEHxYWcugkveyBRS3AqZGtwAKYbMAuNloer9LS/hpw==} + '@swc/core-win32-ia32-msvc@1.15.3': + resolution: {integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.2': - resolution: {integrity: sha512-iJaHeYCF4jTn7OEKSa3KRiuVFIVYts8jYjNmCdyz1u5g8HRyTDISD76r8+ljEOgm36oviRQvcXaw6LFp1m0yyA==} + '@swc/core-win32-x64-msvc@1.15.3': + resolution: {integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.2': - resolution: {integrity: sha512-OQm+yJdXxvSjqGeaWhP6Ia264ogifwAO7Q12uTDVYj/Ks4jBTI4JknlcjDRAXtRhqbWsfbZyK/5RtuIPyptk3w==} + '@swc/core@1.15.3': + resolution: {integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -9551,8 +9572,8 @@ packages: '@tanstack/query-core@5.77.1': resolution: {integrity: sha512-nfxVhy4UynChMFfN4NxwI8pktV9R3Zt/ROxOAe6pdOf8CigDLn26p+ex1YW5uien26BBICLmN0dTvIELHCs5vw==} - '@tanstack/query-core@5.90.10': - resolution: {integrity: sha512-EhZVFu9rl7GfRNuJLJ3Y7wtbTnENsvzp+YpcAV7kCYiXni1v8qZh++lpw4ch4rrwC0u/EZRnBHIehzCGzwXDSQ==} + '@tanstack/query-core@5.90.11': + resolution: {integrity: sha512-f9z/nXhCgWDF4lHqgIE30jxLe4sYv15QodfdPDKYAk7nAEjNcndy4dHz3ezhdUaR23BpWa4I2EH4/DZ0//Uf8A==} '@tanstack/query-persist-client-core@4.27.0': resolution: {integrity: sha512-A+dPA7zG0MJOMDeBc/2WcKXW4wV2JMkeBVydobPW9G02M4q0yAj7vI+7SmM2dFuXyIvxXp4KulCywN6abRKDSQ==} @@ -10320,8 +10341,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.47.0': - resolution: {integrity: sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==} + '@typescript-eslint/project-service@8.48.1': + resolution: {integrity: sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' @@ -10346,8 +10367,8 @@ packages: resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.47.0': - resolution: {integrity: sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==} + '@typescript-eslint/scope-manager@8.48.1': + resolution: {integrity: sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.33.1': @@ -10356,8 +10377,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/tsconfig-utils@8.47.0': - resolution: {integrity: sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==} + '@typescript-eslint/tsconfig-utils@8.48.1': + resolution: {integrity: sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' @@ -10426,8 +10447,8 @@ packages: resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.47.0': - resolution: {integrity: sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==} + '@typescript-eslint/types@8.48.1': + resolution: {integrity: sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@2.34.0': @@ -10478,8 +10499,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.47.0': - resolution: {integrity: sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==} + '@typescript-eslint/typescript-estree@8.48.1': + resolution: {integrity: sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' @@ -10516,8 +10537,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.47.0': - resolution: {integrity: sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==} + '@typescript-eslint/utils@8.48.1': + resolution: {integrity: sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -10543,8 +10564,8 @@ packages: resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.47.0': - resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==} + '@typescript-eslint/visitor-keys@8.48.1': + resolution: {integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typespec/ts-http-runtime@0.3.2': @@ -10662,8 +10683,8 @@ packages: cpu: [x64] os: [win32] - '@vercel/oidc@3.0.3': - resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} + '@vercel/oidc@3.0.5': + resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} engines: {node: '>= 20'} '@vitest/expect@2.0.5': @@ -10786,8 +10807,8 @@ packages: engines: {node: '>= 16'} hasBin: true - '@vscode/vsce@3.7.0': - resolution: {integrity: sha512-LY9r2T4joszRjz4d92ZPl6LTBUPS4IWH9gG/3JUv+1QyBJrveZlcVISuiaq0EOpmcgFh0GgVgKD4rD/21Tu8sA==} + '@vscode/vsce@3.7.1': + resolution: {integrity: sha512-OTm2XdMt2YkpSn2Nx7z2EJtSuhRHsTPYsSK59hr3v8jRArK+2UEoju4Jumn1CmpgoBLGI6ReHLJ/czYltNUW3g==} engines: {node: '>= 20'} hasBin: true @@ -11060,8 +11081,8 @@ packages: resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} engines: {node: '>=12'} - ai@5.0.93: - resolution: {integrity: sha512-9eGcu+1PJgPg4pRNV4L7tLjRR3wdJC9CXQoNMvtqvYNOLZHFCzjHtVIOr2SIkoJJeu2+sOy3hyiSuTmy2MA40g==} + ai@5.0.106: + resolution: {integrity: sha512-M5obwavxSJJ3tGlAFqI6eltYNJB0D20X6gIBCFx/KVorb/X1fxVVfiZZpZb+Gslu4340droSOjT0aKQFCarNVg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -11930,8 +11951,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.5.1: - resolution: {integrity: sha512-zGUCsm3yv/ePt2PHNbVxjjn0nNB1MkIaR4wOCxJ2ig5pCf5cCVAYJXVhQg/3OhhJV6DB1ts7Hv0oUaElc2TPQg==} + bare-fs@4.5.2: + resolution: {integrity: sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -11966,8 +11987,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.29: - resolution: {integrity: sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA==} + baseline-browser-mapping@2.8.32: + resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==} hasBin: true basic-auth@2.0.1: @@ -12032,12 +12053,12 @@ packages: blueimp-md5@2.19.0: resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} bonjour-service@1.3.0: @@ -12049,8 +12070,8 @@ packages: boundary@2.0.0: resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} - bowser@2.12.1: - resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} + bowser@2.13.1: + resolution: {integrity: sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==} boxen@1.3.0: resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==} @@ -12211,8 +12232,8 @@ packages: resolution: {integrity: sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==} engines: {node: '>=18'} - cacheable@2.2.0: - resolution: {integrity: sha512-LEJxRqfeomiiRd2t0uON6hxAtgOoWDfY3fugebbz+J3vDLO+SkdfFChQcOHTZhj9SYa9iwE9MGYNX72dKiOE4w==} + cacheable@2.3.0: + resolution: {integrity: sha512-HHiAvOBmlcR2f3SQ7kdlYD8+AUJG+wlFZ/Ze8tl1Vzvz0MdOh8IYA/EFU4ve8t1/sZ0j4MGi7ST5MoTwHessQA==} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -12284,11 +12305,11 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-db@1.0.30001755: - resolution: {integrity: sha512-R8xk0HVpfPgDIp4rpbHNYMZY3Bnr5XgEvQ54sbPQwIL2rBruVQNipYcGKlve7txXcgoD7ihoQDLU020hFysTLw==} + caniuse-db@1.0.30001757: + resolution: {integrity: sha512-A1KAcawhlASOv4/RwYwfJKld9x9//MUFfqqj7hT6vriXiGxVD6B1ZVLdfksa0WzZfGeUVd6JdW8SV+SH6HMSFw==} - caniuse-lite@1.0.30001755: - resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} canvas@3.2.0: resolution: {integrity: sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==} @@ -12530,8 +12551,8 @@ packages: resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} engines: {node: '>=18'} - clipboardy@5.0.0: - resolution: {integrity: sha512-MQfKHaD09eP80Pev4qBxZLbxJK/ONnqfSYAPlCmPh+7BDboYtO/3BmB6HGzxDIT0SlTRc2tzS8lQqfcdLtZ0Kg==} + clipboardy@5.0.1: + resolution: {integrity: sha512-pJ5ZDWjOT593Nli4TqlRLy33KomlAPxIFntMFxXrCqJON1cGcGPT5nNFxRxJ9m4HbfrccsYve7XwXjywW6nXVw==} engines: {node: '>=20'} cliui@3.2.0: @@ -12831,17 +12852,13 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -13621,8 +13638,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.255: - resolution: {integrity: sha512-Z9oIp4HrFF/cZkDPMpz2XSuVpc1THDpT4dlmATFlJUIBVCy9Vap5/rIXsASP1CscBacBqhabwh8vLctqBwEerQ==} + electron-to-chromium@1.5.263: + resolution: {integrity: sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg==} email-addresses@5.0.0: resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} @@ -13707,8 +13724,8 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - envinfo@7.20.0: - resolution: {integrity: sha512-+zUomDcLXsVkQ37vUqWBvQwLaLlj8eZPSi61llaEFAVBY5mhcXdaSw1pSJVl4yTYD5g/gEfpNl28YYk4IPvrrg==} + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} engines: {node: '>=4'} hasBin: true @@ -14174,8 +14191,8 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - execa@9.6.0: - resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} exenv-es6@1.1.1: @@ -14221,12 +14238,12 @@ packages: peerDependencies: express: '>= 4.11' - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} engines: {node: '>= 0.10.0'} - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} ext@1.7.0: @@ -14378,8 +14395,8 @@ packages: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} - file-entry-cache@10.1.4: - resolution: {integrity: sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==} + file-entry-cache@11.1.1: + resolution: {integrity: sha512-TPVFSDE7q91Dlk1xpFLvFllf8r0HyOMOlnWy7Z2HBku5H3KhIeOGInexrIeg2D64DosVB/JXkrrk6N/7Wriq4A==} file-entry-cache@5.0.1: resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} @@ -14450,13 +14467,13 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} find-cache-dir@1.0.0: resolution: {integrity: sha512-46TFiBOzX7xq/PcSWfFwkyjpemdRnMe31UQF+os0y+1W3k95f6R4SEt02Hj4p3X0Mir9gfrkmOtshFidS0VPUg==} @@ -15130,8 +15147,8 @@ packages: resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} engines: {node: '>= 0.4.0'} - hashery@1.2.0: - resolution: {integrity: sha512-43XJKpwle72Ik5Zpam7MuzRWyNdwwdf6XHlh8wCj2PggvWf+v/Dm5B0dxGZOmddidgeO6Ofu9As/o231Ti/9PA==} + hashery@1.3.0: + resolution: {integrity: sha512-fWltioiy5zsSAs9ouEnvhsVJeAXRybGCNNv0lvzpzNOSDbULXRy7ivFWwCCv4I5Am6kSo75hmbsCduOoc2/K4w==} engines: {node: '>=20'} hasown@2.0.2: @@ -15341,6 +15358,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} @@ -15612,8 +15633,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.2.0: - resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} is-absolute-url@2.1.0: @@ -16688,6 +16709,9 @@ packages: joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + jpjs@1.2.1: resolution: {integrity: sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw==} @@ -16860,8 +16884,8 @@ packages: jwa@1.4.2: resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + jws@3.2.3: + resolution: {integrity: sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==} jwt-decode@4.0.0: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} @@ -16974,8 +16998,8 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - lint-staged@16.2.6: - resolution: {integrity: sha512-s1gphtDbV4bmW1eylXpVMk2u7is7YsrLl8hzrtvC70h4ByhcMLZFY01Fx05ZUDNuv1H8HO4E+e2zgejV1jVwNw==} + lint-staged@16.2.7: + resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==} engines: {node: '>=20.17'} hasBin: true @@ -17199,8 +17223,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.2: - resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} lru-cache@4.1.5: @@ -17388,8 +17412,8 @@ packages: mdast-util-to-hast@11.3.0: resolution: {integrity: sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==} - mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} mdast-util-to-markdown@2.1.2: resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} @@ -17435,8 +17459,8 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.51.0: - resolution: {integrity: sha512-4zngfkVM/GpIhC8YazOsM6E8hoB33NP0BCESPOA6z7qaL6umPJNqkO8CNYaLV2FB2MV6H1O3x2luHHOSqppv+A==} + memfs@4.51.1: + resolution: {integrity: sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==} memoizee@0.4.17: resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} @@ -17702,9 +17726,9 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -18056,8 +18080,8 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + node-forge@1.3.2: + resolution: {integrity: sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==} engines: {node: '>= 6.13.0'} node-gyp-build@4.8.4: @@ -18098,8 +18122,8 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - node-sarif-builder@3.3.0: - resolution: {integrity: sha512-8taRy2nQs1xNs8iO2F0XbkZJEliiijpKgFVcyiwKjJ2+3X59LVI3wY84qRdJwRDpIo5GK8wvb1pxcJ+JVu3jrg==} + node-sarif-builder@3.3.1: + resolution: {integrity: sha512-8z5dAbhpxmk/WRQHXlv4V0h+9Y4Ugk+w08lyhV/7E/CQX9yDdBc3025/EG+RSMJU2aPFh/IQ7XDV7Ti5TLt/TA==} engines: {node: '>=20'} node-schedule@2.1.1: @@ -18744,8 +18768,8 @@ packages: resolution: {integrity: sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==} engines: {node: '>=16.20.0'} - pkce-challenge@5.0.0: - resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} pkg-dir@2.0.0: @@ -19194,8 +19218,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss-selector-parser@7.1.0: - resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} postcss-svgo@2.1.6: @@ -19471,10 +19495,6 @@ packages: resolution: {integrity: sha512-7gJ6mxcQb9vUBOtbKm5mDevbe2uRcOEVp1g4gb/Q+oLntB3HY8eBhOYRxFI2mlDFlY1e4DOSCptzxarXRvzxCA==} engines: {node: '>=20'} - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -19530,12 +19550,12 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} raw-loader@4.0.2: @@ -19830,8 +19850,8 @@ packages: '@types/react': optional: true - react-remove-scroll@2.7.1: - resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} engines: {node: '>=10'} peerDependencies: '@types/react': '*' @@ -20387,8 +20407,8 @@ packages: resolution: {integrity: sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==} hasBin: true - rollup@4.53.2: - resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -20514,8 +20534,8 @@ packages: webpack: optional: true - sass@1.94.1: - resolution: {integrity: sha512-/YVm5FRQaRlr3oNh2LLFYne1PdPlRZGyKnHh1sLleOqLcohTR4eUUvBjBIqkl1fEXd1MGOHgzJGJh+LgTtV4KQ==} + sass@1.94.2: + resolution: {integrity: sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==} engines: {node: '>=14.0.0'} hasBin: true @@ -20607,6 +20627,10 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + send@0.19.1: + resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} + engines: {node: '>= 0.8.0'} + send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -21282,8 +21306,8 @@ packages: peerDependencies: stylelint: ^16.18.0 - stylelint@16.25.0: - resolution: {integrity: sha512-Li0avYWV4nfv1zPbdnxLYBGq4z8DVZxbRgx4Kn6V+Uftz1rMoF1qiEI3oL4kgWqyYgCgs7gT5maHNZ82Gk03vQ==} + stylelint@16.26.1: + resolution: {integrity: sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw==} engines: {node: '>=18.12.0'} hasBin: true @@ -21293,8 +21317,8 @@ packages: subarg@1.0.0: resolution: {integrity: sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==} - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -21408,8 +21432,8 @@ packages: react: '>=16.8.0 <19' react-dom: '>=16.8.0 <19' - swagger-ui-react@5.30.2: - resolution: {integrity: sha512-0tS9GOcswKuQrIpCyvDoCDs6xS8B6MRC+iE7P99WfVXDhAIU+U7iFHuS4e7zucSh9qXvcL7KsXs623c+4oBe6w==} + swagger-ui-react@5.30.3: + resolution: {integrity: sha512-QIy32nPql6yiV2NVwbww1P7f6HEOAuYrnk8VEJkzPC/p6Xc5Xnz9hhmSHzXTuM70fDbVw/qPzCJ0mZMMultpiw==} peerDependencies: react: '>=16.8.0 <20' react-dom: '>=16.8.0 <20' @@ -21697,9 +21721,6 @@ packages: resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} engines: {node: '>=14.16'} - toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - toposort@1.0.7: resolution: {integrity: sha512-FclLrw8b9bMWf4QlCJuHBEVhSRsqDj6u3nIjAzPeJvgl//1hBlffdlk0MALceL14+koWEdU4ofRAXofbODxQzg==} @@ -23188,8 +23209,8 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true @@ -23269,10 +23290,10 @@ packages: zenscroll@4.0.2: resolution: {integrity: sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==} - zod-to-json-schema@3.24.6: - resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} + zod-to-json-schema@3.25.0: + resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} peerDependencies: - zod: ^3.24.1 + zod: ^3.25 || ^4 zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -23280,8 +23301,8 @@ packages: zod@4.1.11: resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} - zustand@5.0.8: - resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} + zustand@5.0.9: + resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} engines: {node: '>=12.20.0'} peerDependencies: '@types/react': '>=18.0.0' @@ -23308,50 +23329,50 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@ai-sdk/amazon-bedrock@3.0.56(zod@4.1.11)': + '@ai-sdk/amazon-bedrock@3.0.65(zod@4.1.11)': dependencies: - '@ai-sdk/anthropic': 2.0.45(zod@4.1.11) + '@ai-sdk/anthropic': 2.0.53(zod@4.1.11) '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@4.1.11) + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.11) '@smithy/eventstream-codec': 4.2.5 '@smithy/util-utf8': 4.2.0 aws4fetch: 1.0.20 zod: 4.1.11 - '@ai-sdk/anthropic@2.0.45(zod@3.25.76)': + '@ai-sdk/anthropic@2.0.53(zod@3.25.76)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@3.25.76) + '@ai-sdk/provider-utils': 3.0.18(zod@3.25.76) zod: 3.25.76 - '@ai-sdk/anthropic@2.0.45(zod@4.1.11)': + '@ai-sdk/anthropic@2.0.53(zod@4.1.11)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@4.1.11) + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.11) zod: 4.1.11 - '@ai-sdk/gateway@2.0.9(zod@3.25.76)': + '@ai-sdk/gateway@2.0.18(zod@3.25.76)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@3.25.76) - '@vercel/oidc': 3.0.3 + '@ai-sdk/provider-utils': 3.0.18(zod@3.25.76) + '@vercel/oidc': 3.0.5 zod: 3.25.76 - '@ai-sdk/gateway@2.0.9(zod@4.1.11)': + '@ai-sdk/gateway@2.0.18(zod@4.1.11)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@4.1.11) - '@vercel/oidc': 3.0.3 + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.11) + '@vercel/oidc': 3.0.5 zod: 4.1.11 - '@ai-sdk/provider-utils@3.0.17(zod@3.25.76)': + '@ai-sdk/provider-utils@3.0.18(zod@3.25.76)': dependencies: '@ai-sdk/provider': 2.0.0 '@standard-schema/spec': 1.0.0 eventsource-parser: 3.0.6 zod: 3.25.76 - '@ai-sdk/provider-utils@3.0.17(zod@4.1.11)': + '@ai-sdk/provider-utils@3.0.18(zod@4.1.11)': dependencies: '@ai-sdk/provider': 2.0.0 '@standard-schema/spec': 1.0.0 @@ -23388,20 +23409,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-locate-window': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -23411,7 +23432,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-locate-window': 3.893.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -23419,7 +23440,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -23428,35 +23449,35 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.933.0': + '@aws-sdk/client-s3@3.943.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.932.0 - '@aws-sdk/credential-provider-node': 3.933.0 - '@aws-sdk/middleware-bucket-endpoint': 3.930.0 - '@aws-sdk/middleware-expect-continue': 3.930.0 - '@aws-sdk/middleware-flexible-checksums': 3.932.0 - '@aws-sdk/middleware-host-header': 3.930.0 - '@aws-sdk/middleware-location-constraint': 3.930.0 - '@aws-sdk/middleware-logger': 3.930.0 - '@aws-sdk/middleware-recursion-detection': 3.933.0 - '@aws-sdk/middleware-sdk-s3': 3.932.0 - '@aws-sdk/middleware-ssec': 3.930.0 - '@aws-sdk/middleware-user-agent': 3.932.0 - '@aws-sdk/region-config-resolver': 3.930.0 - '@aws-sdk/signature-v4-multi-region': 3.932.0 - '@aws-sdk/types': 3.930.0 - '@aws-sdk/util-endpoints': 3.930.0 - '@aws-sdk/util-user-agent-browser': 3.930.0 - '@aws-sdk/util-user-agent-node': 3.932.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/credential-provider-node': 3.943.0 + '@aws-sdk/middleware-bucket-endpoint': 3.936.0 + '@aws-sdk/middleware-expect-continue': 3.936.0 + '@aws-sdk/middleware-flexible-checksums': 3.943.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-location-constraint': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-sdk-s3': 3.943.0 + '@aws-sdk/middleware-ssec': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.943.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/signature-v4-multi-region': 3.943.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.943.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/eventstream-serde-browser': 4.2.5 '@smithy/eventstream-serde-config-resolver': 4.3.5 '@smithy/eventstream-serde-node': 4.2.5 @@ -23467,21 +23488,21 @@ snapshots: '@smithy/invalid-dependency': 4.2.5 '@smithy/md5-js': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.11 - '@smithy/middleware-retry': 4.4.11 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.10 - '@smithy/util-defaults-mode-node': 4.2.13 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -23492,41 +23513,41 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.933.0': + '@aws-sdk/client-sso@3.943.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.932.0 - '@aws-sdk/middleware-host-header': 3.930.0 - '@aws-sdk/middleware-logger': 3.930.0 - '@aws-sdk/middleware-recursion-detection': 3.933.0 - '@aws-sdk/middleware-user-agent': 3.932.0 - '@aws-sdk/region-config-resolver': 3.930.0 - '@aws-sdk/types': 3.930.0 - '@aws-sdk/util-endpoints': 3.930.0 - '@aws-sdk/util-user-agent-browser': 3.930.0 - '@aws-sdk/util-user-agent-node': 3.932.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.943.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.943.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.11 - '@smithy/middleware-retry': 4.4.11 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.10 - '@smithy/util-defaults-mode-node': 4.2.13 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -23535,53 +23556,54 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.932.0': + '@aws-sdk/core@3.943.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/xml-builder': 3.930.0 - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 '@smithy/signature-v4': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-base64': 4.3.0 '@smithy/util-middleware': 4.2.5 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.932.0': + '@aws-sdk/credential-provider-env@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/property-provider': 4.2.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.932.0': + '@aws-sdk/credential-provider-http@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/fetch-http-handler': 5.3.6 '@smithy/node-http-handler': 4.4.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-stream': 4.5.6 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.933.0': - dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/credential-provider-env': 3.932.0 - '@aws-sdk/credential-provider-http': 3.932.0 - '@aws-sdk/credential-provider-process': 3.932.0 - '@aws-sdk/credential-provider-sso': 3.933.0 - '@aws-sdk/credential-provider-web-identity': 3.933.0 - '@aws-sdk/nested-clients': 3.933.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/credential-provider-ini@3.943.0': + dependencies: + '@aws-sdk/core': 3.943.0 + '@aws-sdk/credential-provider-env': 3.943.0 + '@aws-sdk/credential-provider-http': 3.943.0 + '@aws-sdk/credential-provider-login': 3.943.0 + '@aws-sdk/credential-provider-process': 3.943.0 + '@aws-sdk/credential-provider-sso': 3.943.0 + '@aws-sdk/credential-provider-web-identity': 3.943.0 + '@aws-sdk/nested-clients': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/credential-provider-imds': 4.2.5 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 @@ -23590,15 +23612,28 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.933.0': + '@aws-sdk/credential-provider-login@3.943.0': dependencies: - '@aws-sdk/credential-provider-env': 3.932.0 - '@aws-sdk/credential-provider-http': 3.932.0 - '@aws-sdk/credential-provider-ini': 3.933.0 - '@aws-sdk/credential-provider-process': 3.932.0 - '@aws-sdk/credential-provider-sso': 3.933.0 - '@aws-sdk/credential-provider-web-identity': 3.933.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/nested-clients': 3.943.0 + '@aws-sdk/types': 3.936.0 + '@smithy/property-provider': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.943.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.943.0 + '@aws-sdk/credential-provider-http': 3.943.0 + '@aws-sdk/credential-provider-ini': 3.943.0 + '@aws-sdk/credential-provider-process': 3.943.0 + '@aws-sdk/credential-provider-sso': 3.943.0 + '@aws-sdk/credential-provider-web-identity': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/credential-provider-imds': 4.2.5 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 @@ -23607,21 +23642,21 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.932.0': + '@aws-sdk/credential-provider-process@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.933.0': + '@aws-sdk/credential-provider-sso@3.943.0': dependencies: - '@aws-sdk/client-sso': 3.933.0 - '@aws-sdk/core': 3.932.0 - '@aws-sdk/token-providers': 3.933.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/client-sso': 3.943.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/token-providers': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 '@smithy/types': 4.9.0 @@ -23629,11 +23664,11 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.933.0': + '@aws-sdk/credential-provider-web-identity@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/nested-clients': 3.933.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/nested-clients': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 '@smithy/types': 4.9.0 @@ -23641,9 +23676,9 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/middleware-bucket-endpoint@3.930.0': + '@aws-sdk/middleware-bucket-endpoint@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-arn-parser': 3.893.0 '@smithy/node-config-provider': 4.3.5 '@smithy/protocol-http': 5.3.5 @@ -23651,20 +23686,20 @@ snapshots: '@smithy/util-config-provider': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.930.0': + '@aws-sdk/middleware-expect-continue@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.932.0': + '@aws-sdk/middleware-flexible-checksums@3.943.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/is-array-buffer': 4.2.0 '@smithy/node-config-provider': 4.3.5 '@smithy/protocol-http': 5.3.5 @@ -23674,43 +23709,43 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.930.0': + '@aws-sdk/middleware-host-header@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.930.0': + '@aws-sdk/middleware-location-constraint@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.930.0': + '@aws-sdk/middleware-logger@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.933.0': + '@aws-sdk/middleware-recursion-detection@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 - '@aws/lambda-invoke-store': 0.2.0 + '@aws-sdk/types': 3.936.0 + '@aws/lambda-invoke-store': 0.2.1 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.932.0': + '@aws-sdk/middleware-sdk-s3@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 '@aws-sdk/util-arn-parser': 3.893.0 - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/node-config-provider': 4.3.5 '@smithy/protocol-http': 5.3.5 '@smithy/signature-v4': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-config-provider': 4.2.0 '@smithy/util-middleware': 4.2.5 @@ -23718,57 +23753,57 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.930.0': + '@aws-sdk/middleware-ssec@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.932.0': + '@aws-sdk/middleware-user-agent@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/types': 3.930.0 - '@aws-sdk/util-endpoints': 3.930.0 - '@smithy/core': 3.18.4 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@smithy/core': 3.18.6 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.933.0': + '@aws-sdk/nested-clients@3.943.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.932.0 - '@aws-sdk/middleware-host-header': 3.930.0 - '@aws-sdk/middleware-logger': 3.930.0 - '@aws-sdk/middleware-recursion-detection': 3.933.0 - '@aws-sdk/middleware-user-agent': 3.932.0 - '@aws-sdk/region-config-resolver': 3.930.0 - '@aws-sdk/types': 3.930.0 - '@aws-sdk/util-endpoints': 3.930.0 - '@aws-sdk/util-user-agent-browser': 3.930.0 - '@aws-sdk/util-user-agent-node': 3.932.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/middleware-host-header': 3.936.0 + '@aws-sdk/middleware-logger': 3.936.0 + '@aws-sdk/middleware-recursion-detection': 3.936.0 + '@aws-sdk/middleware-user-agent': 3.943.0 + '@aws-sdk/region-config-resolver': 3.936.0 + '@aws-sdk/types': 3.936.0 + '@aws-sdk/util-endpoints': 3.936.0 + '@aws-sdk/util-user-agent-browser': 3.936.0 + '@aws-sdk/util-user-agent-node': 3.943.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.11 - '@smithy/middleware-retry': 4.4.11 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.10 - '@smithy/util-defaults-mode-node': 4.2.13 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -23777,28 +23812,28 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.930.0': + '@aws-sdk/region-config-resolver@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/config-resolver': 4.4.3 '@smithy/node-config-provider': 4.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.932.0': + '@aws-sdk/signature-v4-multi-region@3.943.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/middleware-sdk-s3': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/protocol-http': 5.3.5 '@smithy/signature-v4': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.933.0': + '@aws-sdk/token-providers@3.943.0': dependencies: - '@aws-sdk/core': 3.932.0 - '@aws-sdk/nested-clients': 3.933.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/core': 3.943.0 + '@aws-sdk/nested-clients': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/property-provider': 4.2.5 '@smithy/shared-ini-file-loader': 4.4.0 '@smithy/types': 4.9.0 @@ -23806,7 +23841,7 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.930.0': + '@aws-sdk/types@3.936.0': dependencies: '@smithy/types': 4.9.0 tslib: 2.8.1 @@ -23815,9 +23850,9 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.930.0': + '@aws-sdk/util-endpoints@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-endpoints': 3.2.5 @@ -23827,17 +23862,17 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.930.0': + '@aws-sdk/util-user-agent-browser@3.936.0': dependencies: - '@aws-sdk/types': 3.930.0 + '@aws-sdk/types': 3.936.0 '@smithy/types': 4.9.0 - bowser: 2.12.1 + bowser: 2.13.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.932.0': + '@aws-sdk/util-user-agent-node@3.943.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.932.0 - '@aws-sdk/types': 3.930.0 + '@aws-sdk/middleware-user-agent': 3.943.0 + '@aws-sdk/types': 3.936.0 '@smithy/node-config-provider': 4.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 @@ -23848,7 +23883,7 @@ snapshots: fast-xml-parser: 5.2.5 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.2.0': {} + '@aws/lambda-invoke-store@0.2.1': {} '@azu/format-text@1.0.2': {} @@ -23913,8 +23948,8 @@ snapshots: '@azure/core-tracing': 1.3.1 '@azure/core-util': 1.13.1 '@azure/logger': 1.3.0 - '@azure/msal-browser': 4.26.1 - '@azure/msal-node': 3.8.2 + '@azure/msal-browser': 4.26.2 + '@azure/msal-node': 3.8.3 open: 10.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -23927,15 +23962,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@azure/msal-browser@4.26.1': + '@azure/msal-browser@4.26.2': dependencies: - '@azure/msal-common': 15.13.1 + '@azure/msal-common': 15.13.2 - '@azure/msal-common@15.13.1': {} + '@azure/msal-common@15.13.2': {} - '@azure/msal-node@3.8.2': + '@azure/msal-node@3.8.3': dependencies: - '@azure/msal-common': 15.13.1 + '@azure/msal-common': 15.13.2 jsonwebtoken: 9.0.2 uuid: 8.3.2 @@ -25667,16 +25702,16 @@ snapshots: '@biomejs/cli-win32-x64@1.9.4': optional: true - '@cacheable/memory@2.0.5': + '@cacheable/memory@2.0.6': dependencies: - '@cacheable/utils': 2.3.1 + '@cacheable/utils': 2.3.2 '@keyv/bigmap': 1.3.0(keyv@5.5.4) hookified: 1.13.0 keyv: 5.5.4 - '@cacheable/utils@2.3.1': + '@cacheable/utils@2.3.2': dependencies: - hashery: 1.2.0 + hashery: 1.3.0 keyv: 5.5.4 '@cnakazawa/watch@1.0.4': @@ -25689,23 +25724,23 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@codemirror/commands@6.10.0': dependencies: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@codemirror/lang-angular@0.1.4': dependencies: '@codemirror/lang-html': 6.4.11 '@codemirror/lang-javascript': 6.2.4 '@codemirror/language': 6.11.3 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-cpp@6.0.3': dependencies: @@ -25717,7 +25752,7 @@ snapshots: '@codemirror/autocomplete': 6.19.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/css': 1.3.0 '@codemirror/lang-go@6.0.1': @@ -25725,7 +25760,7 @@ snapshots: '@codemirror/autocomplete': 6.19.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/go': 1.0.1 '@codemirror/lang-html@6.4.11': @@ -25736,7 +25771,7 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/css': 1.3.0 '@lezer/html': 1.3.12 @@ -25752,16 +25787,16 @@ snapshots: '@codemirror/lint': 6.8.5 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/javascript': 1.5.4 '@codemirror/lang-jinja@6.0.0': dependencies: '@codemirror/lang-html': 6.4.11 '@codemirror/language': 6.11.3 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-json@6.0.2': dependencies: @@ -25772,9 +25807,9 @@ snapshots: dependencies: '@codemirror/lang-css': 6.3.1 '@codemirror/language': 6.11.3 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-liquid@6.3.0': dependencies: @@ -25783,9 +25818,9 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-markdown@6.5.0': dependencies: @@ -25794,7 +25829,7 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/markdown': 1.6.0 '@codemirror/lang-php@6.0.2': @@ -25802,7 +25837,7 @@ snapshots: '@codemirror/lang-html': 6.4.11 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/php': 1.0.5 '@codemirror/lang-python@6.2.1': @@ -25810,7 +25845,7 @@ snapshots: '@codemirror/autocomplete': 6.19.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/python': 1.1.18 '@codemirror/lang-rust@6.0.2': @@ -25823,7 +25858,7 @@ snapshots: '@codemirror/lang-css': 6.3.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/sass': 1.1.0 '@codemirror/lang-sql@6.10.0': @@ -25831,25 +25866,25 @@ snapshots: '@codemirror/autocomplete': 6.19.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-vue@0.1.3': dependencies: '@codemirror/lang-html': 6.4.11 '@codemirror/lang-javascript': 6.2.4 '@codemirror/language': 6.11.3 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-wast@6.0.2': dependencies: '@codemirror/language': 6.11.3 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@codemirror/lang-xml@6.1.0': dependencies: @@ -25857,7 +25892,7 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/xml': 1.0.6 '@codemirror/lang-yaml@6.1.2': @@ -25865,9 +25900,9 @@ snapshots: '@codemirror/autocomplete': 6.19.1 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/yaml': 1.0.3 '@codemirror/language-data@6.5.2': @@ -25900,9 +25935,9 @@ snapshots: dependencies: '@codemirror/state': 6.5.2 '@codemirror/view': 6.38.8 - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 style-mod: 4.1.3 '@codemirror/legacy-modes@6.5.2': @@ -25998,6 +26033,8 @@ snapshots: dependencies: '@csstools/css-tokenizer': 3.0.4 + '@csstools/css-syntax-patches-for-csstree@1.0.20': {} + '@csstools/css-tokenizer@3.0.4': {} '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': @@ -26005,9 +26042,9 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)': + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': dependencies: - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 '@dabh/diagnostics@2.0.8': dependencies: @@ -26358,7 +26395,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 debug: 4.4.3(supports-color@8.1.1) @@ -26675,7 +26712,7 @@ snapshots: - supports-color - utf-8-validate - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -26689,7 +26726,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -26710,7 +26747,7 @@ snapshots: - supports-color - ts-node - '@jest/core@30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3))': + '@jest/core@30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3))': dependencies: '@jest/console': 30.2.0 '@jest/pattern': 30.0.1 @@ -26725,7 +26762,7 @@ snapshots: exit-x: 0.2.2 graceful-fs: 4.2.11 jest-changed-files: 30.2.0 - jest-config: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-config: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-haste-map: 30.2.0 jest-message-util: 30.2.0 jest-regex-util: 30.0.1 @@ -27210,7 +27247,7 @@ snapshots: '@keyv/bigmap@1.3.0(keyv@5.5.4)': dependencies: - hashery: 1.2.0 + hashery: 1.3.0 hookified: 1.13.0 keyv: 5.5.4 @@ -27362,98 +27399,98 @@ snapshots: '@lexical/offset': 0.17.1 lexical: 0.17.1 - '@lezer/common@1.3.0': {} + '@lezer/common@1.4.0': {} '@lezer/cpp@1.1.3': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/css@1.3.0': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/go@1.0.1': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/highlight@1.2.3': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/html@1.3.12': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/java@1.1.3': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/javascript@1.5.4': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/json@1.0.3': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 - '@lezer/lr@1.4.3': + '@lezer/lr@1.4.4': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/markdown@1.6.0': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 '@lezer/php@1.0.5': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/python@1.1.18': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/rust@1.0.2': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/sass@1.1.0': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/xml@1.0.6': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@lezer/yaml@1.0.3': dependencies: - '@lezer/common': 1.3.0 + '@lezer/common': 1.4.0 '@lezer/highlight': 1.2.3 - '@lezer/lr': 1.4.3 + '@lezer/lr': 1.4.4 '@marijn/find-cluster-break@1.0.2': {} @@ -27666,7 +27703,7 @@ snapshots: '@modelcontextprotocol/inspector-cli@0.17.2': dependencies: - '@modelcontextprotocol/sdk': 1.22.0 + '@modelcontextprotocol/sdk': 1.24.0 commander: 13.1.0 spawn-rx: 5.1.2 transitivePeerDependencies: @@ -27675,7 +27712,7 @@ snapshots: '@modelcontextprotocol/inspector-client@0.17.2(@types/react-dom@18.2.0)(@types/react@18.2.0)': dependencies: - '@modelcontextprotocol/sdk': 1.22.0 + '@modelcontextprotocol/sdk': 1.24.0 '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-icons': 1.3.2(react@18.3.1) @@ -27708,9 +27745,9 @@ snapshots: '@modelcontextprotocol/inspector-server@0.17.2': dependencies: - '@modelcontextprotocol/sdk': 1.22.0 + '@modelcontextprotocol/sdk': 1.24.0 cors: 2.8.5 - express: 5.1.0 + express: 5.2.1 shell-quote: 1.8.3 spawn-rx: 5.1.2 ws: 8.18.3 @@ -27721,18 +27758,18 @@ snapshots: - supports-color - utf-8-validate - '@modelcontextprotocol/inspector@0.17.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.18)(@types/react-dom@18.2.0)(@types/react@18.2.0)(typescript@5.8.3)': + '@modelcontextprotocol/inspector@0.17.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.18)(@types/react-dom@18.2.0)(@types/react@18.2.0)(typescript@5.8.3)': dependencies: '@modelcontextprotocol/inspector-cli': 0.17.2 '@modelcontextprotocol/inspector-client': 0.17.2(@types/react-dom@18.2.0)(@types/react@18.2.0) '@modelcontextprotocol/inspector-server': 0.17.2 - '@modelcontextprotocol/sdk': 1.22.0 + '@modelcontextprotocol/sdk': 1.24.0 concurrently: 9.2.1 node-fetch: 3.3.2 open: 10.2.0 shell-quote: 1.8.3 spawn-rx: 5.1.2 - ts-node: 10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.18)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.18)(typescript@5.8.3) zod: 3.25.76 transitivePeerDependencies: - '@cfworker/json-schema' @@ -27746,7 +27783,7 @@ snapshots: - typescript - utf-8-validate - '@modelcontextprotocol/sdk@1.22.0': + '@modelcontextprotocol/sdk@1.24.0': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) @@ -27755,29 +27792,30 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.0.6 - express: 5.1.0 - express-rate-limit: 7.5.1(express@5.1.0) - pkce-challenge: 5.0.0 - raw-body: 3.0.1 + express: 5.2.1 + express-rate-limit: 7.5.1(express@5.2.1) + jose: 6.1.3 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 zod: 3.25.76 - zod-to-json-schema: 3.24.6(zod@3.25.76) + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - supports-color - '@monaco-editor/loader@1.6.1': + '@monaco-editor/loader@1.7.0': dependencies: state-local: 1.0.7 '@monaco-editor/react@4.7.0(monaco-editor@0.52.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@monaco-editor/loader': 1.6.1 + '@monaco-editor/loader': 1.7.0 monaco-editor: 0.52.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) '@monaco-editor/react@4.7.0(monaco-editor@0.52.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@monaco-editor/loader': 1.6.1 + '@monaco-editor/loader': 1.7.0 monaco-editor: 0.52.2 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -27972,7 +28010,7 @@ snapshots: dependencies: playwright: 1.55.1 - '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0)': dependencies: ansi-html: 0.0.9 core-js-pure: 3.47.0 @@ -27982,14 +28020,14 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.3.3 source-map: 0.7.6 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: - '@types/webpack': 5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + '@types/webpack': 5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) type-fest: 4.41.0 webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.103.0) webpack-hot-middleware: 2.26.1 - '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)))': + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.47.0 @@ -27999,11 +28037,11 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.3.3 source-map: 0.7.6 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: - '@types/webpack': 5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)) + '@types/webpack': 5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)) type-fest: 4.41.0 - webpack-dev-server: 5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + webpack-dev-server: 5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) webpack-hot-middleware: 2.26.1 '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@5.28.5(webpack-cli@4.10.0))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0)': @@ -28057,7 +28095,7 @@ snapshots: webpack-dev-server: 5.2.2(webpack@5.103.0) webpack-hot-middleware: 2.26.1 - '@pmmmwh/react-refresh-webpack-plugin@0.6.1(@types/webpack@5.28.5(webpack-cli@5.1.4))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0)': + '@pmmmwh/react-refresh-webpack-plugin@0.6.2(@types/webpack@5.28.5(webpack-cli@5.1.4))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0)': dependencies: anser: 2.3.3 core-js-pure: 3.47.0 @@ -28498,7 +28536,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.2.0) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.2.0) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -28520,7 +28558,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.3.1) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -28773,7 +28811,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.2.0) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.2.0) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -28796,7 +28834,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.2.0) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.2.0) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -28819,7 +28857,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.3.1) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -29158,7 +29196,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.2.0) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.2.0) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -29187,7 +29225,7 @@ snapshots: aria-hidden: 1.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.7.1(@types/react@18.2.0)(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.2.0)(react@18.3.1) optionalDependencies: '@types/react': 18.2.0 '@types/react-dom': 18.2.0 @@ -29800,7 +29838,7 @@ snapshots: '@redhat-developer/page-objects@1.17.0(selenium-webdriver@4.38.0)(typescript@5.8.3)': dependencies: - clipboardy: 5.0.0 + clipboardy: 5.0.1 clone-deep: 4.0.1 compare-versions: 6.1.1 fs-extra: 11.3.2 @@ -29830,9 +29868,9 @@ snapshots: resolve: 1.22.11 rollup: 1.32.1 - '@rollup/plugin-commonjs@28.0.9(rollup@4.53.2)': + '@rollup/plugin-commonjs@28.0.9(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.3) @@ -29840,28 +29878,28 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 '@rollup/plugin-json@4.1.0(rollup@1.32.1)': dependencies: '@rollup/pluginutils': 3.1.0(rollup@1.32.1) rollup: 1.32.1 - '@rollup/plugin-json@6.1.0(rollup@4.53.2)': + '@rollup/plugin-json@6.1.0(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.53.2)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.53.3)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.11 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 '@rollup/plugin-node-resolve@9.0.0(rollup@1.32.1)': dependencies: @@ -29891,78 +29929,78 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/pluginutils@5.3.0(rollup@4.53.2)': + '@rollup/pluginutils@5.3.0(rollup@4.53.3)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.53.2 + rollup: 4.53.3 - '@rollup/rollup-android-arm-eabi@4.53.2': + '@rollup/rollup-android-arm-eabi@4.53.3': optional: true - '@rollup/rollup-android-arm64@4.53.2': + '@rollup/rollup-android-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-arm64@4.53.2': + '@rollup/rollup-darwin-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-x64@4.53.2': + '@rollup/rollup-darwin-x64@4.53.3': optional: true - '@rollup/rollup-freebsd-arm64@4.53.2': + '@rollup/rollup-freebsd-arm64@4.53.3': optional: true - '@rollup/rollup-freebsd-x64@4.53.2': + '@rollup/rollup-freebsd-x64@4.53.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.53.2': + '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.53.2': + '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.53.2': + '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.53.2': + '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.53.2': + '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.2': + '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.2': + '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.2': + '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-musl@4.53.2': + '@rollup/rollup-linux-x64-musl@4.53.3': optional: true - '@rollup/rollup-openharmony-arm64@4.53.2': + '@rollup/rollup-openharmony-arm64@4.53.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.2': + '@rollup/rollup-win32-arm64-msvc@4.53.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.2': + '@rollup/rollup-win32-ia32-msvc@4.53.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.2': + '@rollup/rollup-win32-x64-gnu@4.53.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.2': + '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true '@rtsao/scc@1.1.0': {} @@ -30030,7 +30068,7 @@ snapshots: '@secretlint/secretlint-formatter-sarif@10.2.2': dependencies: - node-sarif-builder: 3.3.0 + node-sarif-builder: 3.3.1 '@secretlint/secretlint-rule-no-dotenv@10.2.2': dependencies: @@ -30140,7 +30178,7 @@ snapshots: '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/core@3.18.4': + '@smithy/core@3.18.6': dependencies: '@smithy/middleware-serde': 4.2.6 '@smithy/protocol-http': 5.3.5 @@ -30244,9 +30282,9 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.3.11': + '@smithy/middleware-endpoint@4.3.13': dependencies: - '@smithy/core': 3.18.4 + '@smithy/core': 3.18.6 '@smithy/middleware-serde': 4.2.6 '@smithy/node-config-provider': 4.3.5 '@smithy/shared-ini-file-loader': 4.4.0 @@ -30255,12 +30293,12 @@ snapshots: '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.11': + '@smithy/middleware-retry@4.4.13': dependencies: '@smithy/node-config-provider': 4.3.5 '@smithy/protocol-http': 5.3.5 '@smithy/service-error-classification': 4.2.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -30334,10 +30372,10 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.9.7': + '@smithy/smithy-client@4.9.9': dependencies: - '@smithy/core': 3.18.4 - '@smithy/middleware-endpoint': 4.3.11 + '@smithy/core': 3.18.6 + '@smithy/middleware-endpoint': 4.3.13 '@smithy/middleware-stack': 4.2.5 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 @@ -30382,20 +30420,20 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.10': + '@smithy/util-defaults-mode-browser@4.3.12': dependencies: '@smithy/property-provider': 4.2.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.13': + '@smithy/util-defaults-mode-node@4.2.15': dependencies: '@smithy/config-resolver': 4.4.3 '@smithy/credential-provider-imds': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 - '@smithy/smithy-client': 4.9.7 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 tslib: 2.8.1 @@ -30630,13 +30668,13 @@ snapshots: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) ts-dedent: 2.2.0 - '@storybook/addon-controls@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/addon-controls@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 '@storybook/components': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/node-logger': 6.5.16 '@storybook/store': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -30744,7 +30782,7 @@ snapshots: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) ts-dedent: 2.2.0 - '@storybook/addon-docs@6.5.16(@babel/core@7.27.7)(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': + '@storybook/addon-docs@6.5.16(@babel/core@7.27.7)(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': dependencies: '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.7) '@babel/preset-env': 7.27.2(@babel/core@7.27.7) @@ -30753,7 +30791,7 @@ snapshots: '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/components': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/core-events': 6.5.16 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/docs-tools': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -30931,29 +30969,29 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@storybook/addon-essentials@6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': + '@storybook/addon-essentials@6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': dependencies: '@babel/core': 7.27.7 '@storybook/addon-actions': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addon-backgrounds': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/addon-controls': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) - '@storybook/addon-docs': 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) + '@storybook/addon-controls': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/addon-docs': 6.5.16(@babel/core@7.27.7)(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) '@storybook/addon-measure': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addon-outline': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addon-toolbars': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addon-viewport': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/node-logger': 6.5.16 core-js: 3.47.0 regenerator-runtime: 0.13.11 ts-dedent: 2.2.0 optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) transitivePeerDependencies: - '@storybook/mdx2-csf' - '@swc/core' @@ -31590,7 +31628,7 @@ snapshots: ejs: 3.1.10 esbuild: 0.25.12 esbuild-plugin-alias: 0.2.1 - express: 4.21.2 + express: 4.22.1 find-cache-dir: 3.3.2 fs-extra: 11.3.2 process: 0.11.10 @@ -31605,7 +31643,7 @@ snapshots: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) ts-dedent: 2.2.0 - '@storybook/builder-webpack4@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': + '@storybook/builder-webpack4@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': dependencies: '@babel/core': 7.27.7 '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -31615,7 +31653,7 @@ snapshots: '@storybook/client-api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 '@storybook/components': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@storybook/core-events': 6.5.16 '@storybook/node-logger': 6.5.16 '@storybook/preview-web': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -31627,33 +31665,33 @@ snapshots: '@types/node': 16.18.126 '@types/webpack': 4.41.40 autoprefixer: 9.8.8 - babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) case-sensitive-paths-webpack-plugin: 2.4.0 core-js: 3.47.0 - css-loader: 3.6.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + css-loader: 3.6.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) find-up: 5.0.0 fork-ts-checker-webpack-plugin: 4.1.6 glob: 7.2.3 glob-promise: 3.4.0(glob@7.2.3) global: 4.4.0 - html-webpack-plugin: 4.5.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + html-webpack-plugin: 4.5.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) pnp-webpack-plugin: 1.6.4(typescript@5.8.3) postcss: 7.0.39 postcss-flexbugs-fixes: 4.2.1 - postcss-loader: 4.3.0(postcss@7.0.39)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - raw-loader: 4.0.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + postcss-loader: 4.3.0(postcss@7.0.39)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + raw-loader: 4.0.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) stable: 0.1.8 - style-loader: 1.3.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - terser-webpack-plugin: 4.2.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + style-loader: 1.3.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + terser-webpack-plugin: 4.2.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) ts-dedent: 2.2.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) - webpack-dev-middleware: 3.7.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - webpack-filter-warnings-plugin: 1.2.1(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) + webpack-dev-middleware: 3.7.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + webpack-filter-warnings-plugin: 1.2.1(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.2.2 optionalDependencies: @@ -31667,7 +31705,7 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/builder-webpack4@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/builder-webpack4@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@babel/core': 7.27.7 '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -31677,7 +31715,7 @@ snapshots: '@storybook/client-api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 '@storybook/components': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/core-events': 6.5.16 '@storybook/node-logger': 6.5.16 '@storybook/preview-web': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -31713,7 +31751,7 @@ snapshots: ts-dedent: 2.2.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-dev-middleware: 3.7.3(webpack@5.103.0) webpack-filter-warnings-plugin: 1.2.1(webpack@5.103.0) webpack-hot-middleware: 2.26.1 @@ -31977,7 +32015,7 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@babel/core': 7.27.7 '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -31987,7 +32025,7 @@ snapshots: '@storybook/client-api': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 '@storybook/components': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/core-events': 6.5.16 '@storybook/node-logger': 6.5.16 '@storybook/preview-web': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -32012,10 +32050,10 @@ snapshots: react-dom: 18.2.0(react@18.2.0) stable: 0.1.8 style-loader: 2.0.0(webpack@5.103.0) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-dev-middleware: 4.3.0(webpack@5.103.0) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.4.6 @@ -32066,7 +32104,7 @@ snapshots: react-dom: 18.2.0(react@18.2.0) stable: 0.1.8 style-loader: 2.0.0(webpack@5.103.0) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 util-deprecate: 1.0.2 webpack: 5.103.0(webpack-cli@4.10.0) @@ -32104,7 +32142,7 @@ snapshots: '@storybook/router': 7.4.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/store': 7.4.6 '@storybook/theming': 7.4.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) '@types/node': 16.18.126 '@types/semver': 7.7.1 babel-loader: 9.2.1(@babel/core@7.27.7)(webpack@5.103.0) @@ -32113,7 +32151,7 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 constants-browserify: 1.0.0 css-loader: 6.11.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.103.0) fs-extra: 11.3.2 html-webpack-plugin: 5.6.5(webpack@5.103.0) @@ -32123,13 +32161,13 @@ snapshots: react-dom: 18.2.0(react@18.2.0) semver: 7.7.3 style-loader: 3.3.4(webpack@5.103.0) - swc-loader: 0.2.6(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + swc-loader: 0.2.6(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@5.1.4) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4) webpack-dev-middleware: 6.1.3(webpack@5.103.0) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.5.0 @@ -32165,33 +32203,33 @@ snapshots: '@storybook/router': 7.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@storybook/store': 7.4.6 '@storybook/theming': 7.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) '@types/node': 16.18.126 '@types/semver': 7.7.1 - babel-loader: 9.2.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + babel-loader: 9.2.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) babel-plugin-named-exports-order: 0.0.2 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 constants-browserify: 1.0.0 - css-loader: 6.11.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - express: 4.21.2 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + css-loader: 6.11.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + express: 4.22.1 + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) fs-extra: 11.3.2 - html-webpack-plugin: 5.6.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + html-webpack-plugin: 5.6.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) path-browserify: 1.0.1 process: 0.11.10 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) semver: 7.7.3 - style-loader: 3.3.4(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - swc-loader: 0.2.6(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + style-loader: 3.3.4(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + swc-loader: 0.2.6(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) - webpack-dev-middleware: 6.1.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) + webpack-dev-middleware: 6.1.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.5.0 optionalDependencies: @@ -32207,7 +32245,7 @@ snapshots: - uglify-js - webpack-cli - '@storybook/builder-webpack5@8.6.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': + '@storybook/builder-webpack5@8.6.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': dependencies: '@storybook/core-webpack': 8.6.14(storybook@8.6.14(prettier@3.5.3)) '@types/semver': 7.7.1 @@ -32215,23 +32253,23 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 constants-browserify: 1.0.0 - css-loader: 6.11.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + css-loader: 6.11.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) es-module-lexer: 1.7.0 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) - html-webpack-plugin: 5.6.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) + html-webpack-plugin: 5.6.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) magic-string: 0.30.21 path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.3 storybook: 8.6.14(prettier@3.5.3) - style-loader: 3.3.4(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + style-loader: 3.3.4(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) - webpack-dev-middleware: 6.1.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack-dev-middleware: 6.1.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 optionalDependencies: @@ -32261,7 +32299,7 @@ snapshots: semver: 7.7.3 storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) style-loader: 3.3.4(webpack@5.103.0) - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 @@ -32342,9 +32380,9 @@ snapshots: commander: 6.2.1 cross-spawn: 7.0.6 detect-indent: 6.1.0 - envinfo: 7.20.0 + envinfo: 7.21.0 execa: 5.1.1 - express: 4.21.2 + express: 4.22.1 find-up: 5.0.0 fs-extra: 11.3.2 get-npm-tarball-url: 2.1.0 @@ -32568,7 +32606,7 @@ snapshots: dependencies: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) - '@storybook/core-client@6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)))': + '@storybook/core-client@6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)))': dependencies: '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/channel-postmessage': 6.5.16 @@ -32592,7 +32630,7 @@ snapshots: ts-dedent: 2.2.0 unfetch: 4.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: typescript: 5.8.3 @@ -32620,7 +32658,7 @@ snapshots: ts-dedent: 2.2.0 unfetch: 4.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: typescript: 5.8.3 @@ -32657,7 +32695,7 @@ snapshots: '@storybook/client-logger': 7.4.6 '@storybook/preview-api': 7.4.6 - '@storybook/core-common@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': + '@storybook/core-common@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': dependencies: '@babel/core': 7.27.7 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.27.7) @@ -32685,15 +32723,15 @@ snapshots: '@storybook/semver': 7.3.2 '@types/node': 16.18.126 '@types/pretty-hrtime': 1.0.3 - babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) babel-plugin-macros: 3.1.0 babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) fs-extra: 9.1.0 glob: 7.2.3 handlebars: 4.7.8 @@ -32710,7 +32748,7 @@ snapshots: telejson: 6.0.8 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -32722,7 +32760,7 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/core-common@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/core-common@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@babel/core': 7.27.7 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.27.7) @@ -32755,7 +32793,7 @@ snapshots: babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0) @@ -32775,7 +32813,7 @@ snapshots: telejson: 6.0.8 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -32820,7 +32858,7 @@ snapshots: babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.26.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0) @@ -32885,7 +32923,7 @@ snapshots: babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0) @@ -32950,7 +32988,7 @@ snapshots: babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0) @@ -33015,7 +33053,7 @@ snapshots: babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.27.7) chalk: 4.1.2 core-js: 3.47.0 - express: 4.21.2 + express: 4.22.1 file-system-cache: 1.1.0 find-up: 5.0.0 fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@4.9.5)(webpack@5.103.0) @@ -33117,20 +33155,20 @@ snapshots: dependencies: ts-dedent: 2.2.0 - '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-webpack4': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack4': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/core-events': 6.5.16 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/csf-tools': 6.5.16 - '@storybook/manager-webpack4': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/manager-webpack4': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/node-logger': 6.5.16 '@storybook/semver': 7.3.2 '@storybook/store': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/telemetry': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/telemetry': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@types/node': 16.18.126 '@types/node-fetch': 2.6.13 '@types/pretty-hrtime': 1.0.3 @@ -33144,7 +33182,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33163,12 +33201,12 @@ snapshots: ts-dedent: 2.2.0 util-deprecate: 1.0.2 watchpack: 2.4.4 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) ws: 8.18.3 x-default-browser: 0.4.0 optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) - '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) typescript: 5.8.3 transitivePeerDependencies: - '@storybook/mdx2-csf' @@ -33210,7 +33248,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33249,20 +33287,20 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/core-server@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': + '@storybook/core-server@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': dependencies: '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-webpack4': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) - '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/builder-webpack4': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@storybook/core-events': 6.5.16 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/csf-tools': 6.5.16 - '@storybook/manager-webpack4': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/manager-webpack4': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@storybook/node-logger': 6.5.16 '@storybook/semver': 7.3.2 '@storybook/store': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/telemetry': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/telemetry': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@types/node': 16.18.126 '@types/node-fetch': 2.6.13 '@types/pretty-hrtime': 1.0.3 @@ -33276,7 +33314,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33295,7 +33333,7 @@ snapshots: ts-dedent: 2.2.0 util-deprecate: 1.0.2 watchpack: 2.4.4 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) ws: 8.18.3 x-default-browser: 0.4.0 optionalDependencies: @@ -33340,7 +33378,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33404,7 +33442,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33468,7 +33506,7 @@ snapshots: core-js: 3.47.0 cpy: 8.1.2 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 9.1.0 global: 4.4.0 globby: 11.1.0 @@ -33531,7 +33569,7 @@ snapshots: cli-table3: 0.6.5 compression: 1.8.1 detect-port: 1.6.1 - express: 4.21.2 + express: 4.22.1 fs-extra: 11.3.2 globby: 11.1.0 lodash: 4.17.21 @@ -33574,16 +33612,16 @@ snapshots: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) ts-dedent: 2.2.0 - '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': + '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0)': dependencies: '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0) - '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) - '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) typescript: 5.8.3 transitivePeerDependencies: - '@storybook/mdx2-csf' @@ -33622,13 +33660,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/core@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)))': + '@storybook/core@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)))': dependencies: - '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - '@storybook/core-server': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + '@storybook/core-server': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -33923,29 +33961,29 @@ snapshots: dependencies: storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) - '@storybook/manager-webpack4@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': + '@storybook/manager-webpack4@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': dependencies: '@babel/core': 7.27.7 '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.7) '@babel/preset-react': 7.27.1(@babel/core@7.27.7) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@storybook/node-logger': 6.5.16 '@storybook/theming': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/ui': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/node': 16.18.126 '@types/webpack': 4.41.40 - babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + babel-loader: 8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) case-sensitive-paths-webpack-plugin: 2.4.0 chalk: 4.1.2 core-js: 3.47.0 - css-loader: 3.6.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - express: 4.21.2 - file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + css-loader: 3.6.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + express: 4.22.1 + file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) find-up: 5.0.0 fs-extra: 9.1.0 - html-webpack-plugin: 4.5.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + html-webpack-plugin: 4.5.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) node-fetch: 2.6.13(encoding@0.1.13) pnp-webpack-plugin: 1.6.4(typescript@5.8.3) react: 18.2.0 @@ -33953,14 +33991,14 @@ snapshots: read-pkg-up: 7.0.1 regenerator-runtime: 0.13.11 resolve-from: 5.0.0 - style-loader: 1.3.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + style-loader: 1.3.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) telejson: 6.0.8 - terser-webpack-plugin: 4.2.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + terser-webpack-plugin: 4.2.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) ts-dedent: 2.2.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) - webpack-dev-middleware: 3.7.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) + webpack-dev-middleware: 3.7.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) webpack-virtual-modules: 0.2.2 optionalDependencies: typescript: 5.8.3 @@ -33974,14 +34012,14 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/manager-webpack4@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/manager-webpack4@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@babel/core': 7.27.7 '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.7) '@babel/preset-react': 7.27.1(@babel/core@7.27.7) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/node-logger': 6.5.16 '@storybook/theming': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/ui': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -33992,7 +34030,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 3.6.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 file-loader: 6.2.0(webpack@5.103.0) find-up: 5.0.0 fs-extra: 9.1.0 @@ -34010,7 +34048,7 @@ snapshots: ts-dedent: 2.2.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-dev-middleware: 3.7.3(webpack@5.103.0) webpack-virtual-modules: 0.2.2 optionalDependencies: @@ -34043,7 +34081,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 3.6.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 file-loader: 6.2.0(webpack@5.103.0) find-up: 5.0.0 fs-extra: 9.1.0 @@ -34094,7 +34132,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 3.6.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 file-loader: 6.2.0(webpack@5.103.0) find-up: 5.0.0 fs-extra: 9.1.0 @@ -34145,7 +34183,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 3.6.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 file-loader: 6.2.0(webpack@5.103.0) find-up: 5.0.0 fs-extra: 9.1.0 @@ -34196,7 +34234,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 3.6.0(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 file-loader: 6.2.0(webpack@5.103.0) find-up: 5.0.0 fs-extra: 9.1.0 @@ -34229,14 +34267,14 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@babel/core': 7.27.7 '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.7) '@babel/preset-react': 7.27.1(@babel/core@7.27.7) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/core-client': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/node-logger': 6.5.16 '@storybook/theming': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/ui': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -34246,7 +34284,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 5.2.7(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 find-up: 5.0.0 fs-extra: 9.1.0 html-webpack-plugin: 5.6.5(webpack@5.103.0) @@ -34259,10 +34297,10 @@ snapshots: resolve-from: 5.0.0 style-loader: 2.0.0(webpack@5.103.0) telejson: 6.0.8 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-dev-middleware: 4.3.0(webpack@5.103.0) webpack-virtual-modules: 0.4.6 optionalDependencies: @@ -34295,7 +34333,7 @@ snapshots: chalk: 4.1.2 core-js: 3.47.0 css-loader: 5.2.7(webpack@5.103.0) - express: 4.21.2 + express: 4.22.1 find-up: 5.0.0 fs-extra: 9.1.0 html-webpack-plugin: 5.6.5(webpack@5.103.0) @@ -34308,7 +34346,7 @@ snapshots: resolve-from: 5.0.0 style-loader: 2.0.0(webpack@5.103.0) telejson: 6.0.8 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) ts-dedent: 2.2.0 util-deprecate: 1.0.2 webpack: 5.103.0(webpack-cli@4.10.0) @@ -34440,11 +34478,11 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/preset-react-webpack@8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': + '@storybook/preset-react-webpack@8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': dependencies: '@storybook/core-webpack': 8.6.14(storybook@8.6.14(prettier@3.5.3)) '@storybook/react': 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) '@types/semver': 7.7.1 find-up: 5.0.0 magic-string: 0.30.21 @@ -34455,7 +34493,7 @@ snapshots: semver: 7.7.3 storybook: 8.6.14(prettier@3.5.3) tsconfig-paths: 4.2.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -34592,7 +34630,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)))': + '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)))': dependencies: debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 @@ -34602,7 +34640,7 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@5.8.3) tslib: 2.8.1 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - supports-color @@ -34616,11 +34654,11 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@5.8.3) tslib: 2.8.1 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) transitivePeerDependencies: - supports-color - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12))': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12))': dependencies: debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 @@ -34630,7 +34668,7 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@5.8.3) tslib: 2.8.1 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) transitivePeerDependencies: - supports-color @@ -34688,10 +34726,10 @@ snapshots: react-dom: 19.1.0(react@19.1.0) storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) - '@storybook/react-vite@9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.53.2)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3)': + '@storybook/react-vite@9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.53.3)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3)': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.1(typescript@5.8.3) - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) '@storybook/builder-vite': 9.1.16(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3)) '@storybook/react': 9.1.16(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3) find-up: 7.0.0 @@ -34765,10 +34803,10 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/react-webpack5@8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': + '@storybook/react-webpack5@8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3)': dependencies: - '@storybook/builder-webpack5': 8.6.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) - '@storybook/preset-react-webpack': 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) + '@storybook/builder-webpack5': 8.6.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) + '@storybook/preset-react-webpack': 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) '@storybook/react': 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.5.3)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.6.14(prettier@3.5.3))(typescript@5.8.3) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -34803,15 +34841,15 @@ snapshots: - uglify-js - webpack-cli - '@storybook/react@6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)': + '@storybook/react@6.5.16(@babel/core@7.27.7)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)': dependencies: '@babel/preset-flow': 7.27.1(@babel/core@7.27.7) '@babel/preset-react': 7.27.1(@babel/core@7.27.7) - '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2)(webpack-hot-middleware@2.26.1)(webpack@5.103.0) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 - '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1))(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)(webpack@5.103.0) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/docs-tools': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/node-logger': 6.5.16 @@ -34842,11 +34880,11 @@ snapshots: require-from-string: 2.0.2 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: '@babel/core': 7.27.7 - '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) - '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) typescript: 5.8.3 transitivePeerDependencies: - '@storybook/mdx2-csf' @@ -34931,19 +34969,19 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/react@6.5.16(@babel/core@7.27.7)(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)': + '@storybook/react@6.5.16(@babel/core@7.27.7)(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/preset-flow': 7.27.1(@babel/core@7.27.7) '@babel/preset-react': 7.27.1(@babel/core@7.27.7) - '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17)))(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack-hot-middleware@2.26.1)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) '@storybook/addons': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/client-logger': 6.5.16 - '@storybook/core': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/docs-tools': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/node-logger': 6.5.16 - '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) '@storybook/semver': 7.3.2 '@storybook/store': 6.5.16(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/estree': 0.0.51 @@ -34970,7 +35008,7 @@ snapshots: require-from-string: 2.0.2 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: '@babel/core': 7.27.7 typescript: 5.8.3 @@ -35382,10 +35420,10 @@ snapshots: '@storybook/client-logger': 7.4.6 '@storybook/preview-api': 7.4.6 - '@storybook/telemetry@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': + '@storybook/telemetry@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)': dependencies: '@storybook/client-logger': 6.5.16 - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3) chalk: 4.1.2 core-js: 3.47.0 detect-package-manager: 2.0.1 @@ -35409,10 +35447,10 @@ snapshots: - vue-template-compiler - webpack-cli - '@storybook/telemetry@6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': + '@storybook/telemetry@6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(encoding@0.1.13)(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1)': dependencies: '@storybook/client-logger': 6.5.16 - '@storybook/core-common': 6.5.16(@swc/core@1.15.2(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) + '@storybook/core-common': 6.5.16(@swc/core@1.15.3(@swc/helpers@0.5.17))(eslint@9.27.0(jiti@2.6.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.3)(webpack-cli@6.0.1) chalk: 4.1.2 core-js: 3.47.0 detect-package-manager: 2.0.1 @@ -35677,20 +35715,20 @@ snapshots: regenerator-runtime: 0.13.11 resolve-from: 5.0.0 - '@swagger-api/apidom-ast@1.0.0-rc.3': + '@swagger-api/apidom-ast@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) unraw: 3.0.0 - '@swagger-api/apidom-core@1.0.0-rc.3': + '@swagger-api/apidom-core@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-ast': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-ast': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@types/ramda': 0.30.2 minim: 0.23.8 ramda: 0.30.1 @@ -35698,213 +35736,213 @@ snapshots: short-unique-id: 5.3.2 ts-mixer: 6.0.4 - '@swagger-api/apidom-error@1.0.0-rc.3': + '@swagger-api/apidom-error@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-json-pointer@1.0.0-rc.3': + '@swagger-api/apidom-json-pointer@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@swaggerexpert/json-pointer': 2.10.2 - '@swagger-api/apidom-ns-api-design-systems@1.0.0-rc.3': + '@swagger-api/apidom-ns-api-design-systems@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 optional: true - '@swagger-api/apidom-ns-arazzo-1@1.0.0-rc.3': + '@swagger-api/apidom-ns-arazzo-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 optional: true - '@swagger-api/apidom-ns-asyncapi-2@1.0.0-rc.3': + '@swagger-api/apidom-ns-asyncapi-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 optional: true - '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-rc.3': + '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-rc.3': + '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-2019-09': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-2019-09': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-rc.3': + '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-ast': 1.0.0-rc.3 - '@swagger-api/apidom-core': 1.0.0-rc.3 + '@swagger-api/apidom-ast': 1.0.0-rc.4 + '@swagger-api/apidom-core': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-rc.3': + '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-rc.3': + '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-6': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-6': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-openapi-2@1.0.0-rc.3': + '@swagger-api/apidom-ns-openapi-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 optional: true - '@swagger-api/apidom-ns-openapi-3-0@1.0.0-rc.3': + '@swagger-api/apidom-ns-openapi-3-0@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-openapi-3-1@1.0.0-rc.3': + '@swagger-api/apidom-ns-openapi-3-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-ast': 1.0.0-rc.3 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-json-pointer': 1.0.0-rc.3 - '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.3 + '@swagger-api/apidom-ast': 1.0.0-rc.4 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-json-pointer': 1.0.0-rc.4 + '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-parser-adapter-api-design-systems-json@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-api-design-systems-json@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-api-design-systems': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-api-design-systems': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-api-design-systems-yaml@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-api-design-systems-yaml@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-api-design-systems': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-api-design-systems': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-arazzo-json-1@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-arazzo-json-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-arazzo-yaml-1@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-arazzo-yaml-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-asyncapi-json-2@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-asyncapi-json-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-json@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-json@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-ast': 1.0.0-rc.3 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-ast': 1.0.0-rc.4 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) @@ -35913,78 +35951,78 @@ snapshots: web-tree-sitter: 0.24.5 optional: true - '@swagger-api/apidom-parser-adapter-openapi-json-2@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-json-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-openapi-json-3-0@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-json-3-0@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-openapi-json-3-1@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-json-3-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-openapi-yaml-2@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-yaml-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optional: true - '@swagger-api/apidom-parser-adapter-yaml-1-2@1.0.0-rc.3': + '@swagger-api/apidom-parser-adapter-yaml-1-2@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-ast': 1.0.0-rc.3 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-ast': 1.0.0-rc.4 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@tree-sitter-grammars/tree-sitter-yaml': 0.7.1(tree-sitter@0.22.4) '@types/ramda': 0.30.2 ramda: 0.30.1 @@ -35993,11 +36031,11 @@ snapshots: web-tree-sitter: 0.24.5 optional: true - '@swagger-api/apidom-reference@1.0.0-rc.3': + '@swagger-api/apidom-reference@1.0.0-rc.4': dependencies: '@babel/runtime-corejs3': 7.28.4 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 '@types/ramda': 0.30.2 axios: 1.12.2 minimatch: 7.4.6 @@ -36005,26 +36043,26 @@ snapshots: ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) optionalDependencies: - '@swagger-api/apidom-json-pointer': 1.0.0-rc.3 - '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.3 - '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-api-design-systems-json': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-api-design-systems-yaml': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-arazzo-json-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-arazzo-yaml-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-asyncapi-json-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-json-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-json-3-0': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-json-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-yaml-2': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.3 + '@swagger-api/apidom-json-pointer': 1.0.0-rc.4 + '@swagger-api/apidom-ns-arazzo-1': 1.0.0-rc.4 + '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-2': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-api-design-systems-json': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-api-design-systems-yaml': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-arazzo-json-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-arazzo-yaml-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-asyncapi-json-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-asyncapi-yaml-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-json': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-json-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-json-3-0': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-json-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-yaml-2': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-0': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-openapi-yaml-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-rc.4 transitivePeerDependencies: - debug @@ -36036,51 +36074,51 @@ snapshots: dependencies: apg-lite: 1.0.5 - '@swc/core-darwin-arm64@1.15.2': + '@swc/core-darwin-arm64@1.15.3': optional: true - '@swc/core-darwin-x64@1.15.2': + '@swc/core-darwin-x64@1.15.3': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.2': + '@swc/core-linux-arm-gnueabihf@1.15.3': optional: true - '@swc/core-linux-arm64-gnu@1.15.2': + '@swc/core-linux-arm64-gnu@1.15.3': optional: true - '@swc/core-linux-arm64-musl@1.15.2': + '@swc/core-linux-arm64-musl@1.15.3': optional: true - '@swc/core-linux-x64-gnu@1.15.2': + '@swc/core-linux-x64-gnu@1.15.3': optional: true - '@swc/core-linux-x64-musl@1.15.2': + '@swc/core-linux-x64-musl@1.15.3': optional: true - '@swc/core-win32-arm64-msvc@1.15.2': + '@swc/core-win32-arm64-msvc@1.15.3': optional: true - '@swc/core-win32-ia32-msvc@1.15.2': + '@swc/core-win32-ia32-msvc@1.15.3': optional: true - '@swc/core-win32-x64-msvc@1.15.2': + '@swc/core-win32-x64-msvc@1.15.3': optional: true - '@swc/core@1.15.2(@swc/helpers@0.5.17)': + '@swc/core@1.15.3(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.2 - '@swc/core-darwin-x64': 1.15.2 - '@swc/core-linux-arm-gnueabihf': 1.15.2 - '@swc/core-linux-arm64-gnu': 1.15.2 - '@swc/core-linux-arm64-musl': 1.15.2 - '@swc/core-linux-x64-gnu': 1.15.2 - '@swc/core-linux-x64-musl': 1.15.2 - '@swc/core-win32-arm64-msvc': 1.15.2 - '@swc/core-win32-ia32-msvc': 1.15.2 - '@swc/core-win32-x64-msvc': 1.15.2 + '@swc/core-darwin-arm64': 1.15.3 + '@swc/core-darwin-x64': 1.15.3 + '@swc/core-linux-arm-gnueabihf': 1.15.3 + '@swc/core-linux-arm64-gnu': 1.15.3 + '@swc/core-linux-arm64-musl': 1.15.3 + '@swc/core-linux-x64-gnu': 1.15.3 + '@swc/core-linux-x64-musl': 1.15.3 + '@swc/core-win32-arm64-msvc': 1.15.3 + '@swc/core-win32-ia32-msvc': 1.15.3 + '@swc/core-win32-x64-msvc': 1.15.3 '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} @@ -36107,7 +36145,7 @@ snapshots: '@tanstack/query-core@5.77.1': {} - '@tanstack/query-core@5.90.10': {} + '@tanstack/query-core@5.90.11': {} '@tanstack/query-persist-client-core@4.27.0': dependencies: @@ -36814,11 +36852,11 @@ snapshots: - webpack-cli optional: true - '@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))': + '@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))': dependencies: '@types/node': 22.15.35 tapable: 2.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - '@swc/core' - esbuild @@ -36826,11 +36864,11 @@ snapshots: - webpack-cli optional: true - '@types/webpack@5.28.5(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1)': + '@types/webpack@5.28.5(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1)': dependencies: '@types/node': 22.15.35 tapable: 2.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -37155,10 +37193,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.47.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.48.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.8.3) - '@typescript-eslint/types': 8.47.0 + '@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.8.3) + '@typescript-eslint/types': 8.48.1 debug: 4.4.3(supports-color@8.1.1) typescript: 5.8.3 transitivePeerDependencies: @@ -37189,16 +37227,16 @@ snapshots: '@typescript-eslint/types': 8.33.1 '@typescript-eslint/visitor-keys': 8.33.1 - '@typescript-eslint/scope-manager@8.47.0': + '@typescript-eslint/scope-manager@8.48.1': dependencies: - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/visitor-keys': 8.47.0 + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/visitor-keys': 8.48.1 '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 - '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.48.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 @@ -37281,7 +37319,7 @@ snapshots: '@typescript-eslint/types@8.33.1': {} - '@typescript-eslint/types@8.47.0': {} + '@typescript-eslint/types@8.48.1': {} '@typescript-eslint/typescript-estree@2.34.0(typescript@3.9.10)': dependencies: @@ -37371,17 +37409,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.47.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.48.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.47.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.8.3) - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/visitor-keys': 8.47.0 + '@typescript-eslint/project-service': 8.48.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.8.3) + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/visitor-keys': 8.48.1 debug: 4.4.3(supports-color@8.1.1) - fast-glob: 3.3.3 - is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.3 + tinyglobby: 0.2.15 ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -37460,12 +37497,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.47.0(eslint@8.57.1)(typescript@5.8.3)': + '@typescript-eslint/utils@8.48.1(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.48.1 + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/typescript-estree': 8.48.1(typescript@5.8.3) eslint: 8.57.1 typescript: 5.8.3 transitivePeerDependencies: @@ -37496,9 +37533,9 @@ snapshots: '@typescript-eslint/types': 8.33.1 eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.47.0': + '@typescript-eslint/visitor-keys@8.48.1': dependencies: - '@typescript-eslint/types': 8.47.0 + '@typescript-eslint/types': 8.48.1 eslint-visitor-keys: 4.2.1 '@typespec/ts-http-runtime@0.3.2': @@ -37594,7 +37631,7 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vercel/oidc@3.0.3': {} + '@vercel/oidc@3.0.5': {} '@vitest/expect@2.0.5': dependencies: @@ -37776,7 +37813,7 @@ snapshots: - react-native-b4a - supports-color - '@vscode/vsce@3.7.0': + '@vscode/vsce@3.7.1': dependencies: '@azure/identity': 4.13.0 '@secretlint/node': 10.2.2 @@ -37915,7 +37952,7 @@ snapshots: '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.103.0)': dependencies: webpack: 5.103.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.103.0) + webpack-cli: 5.1.4(webpack-dev-server@5.2.2)(webpack@5.103.0) '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.103.0)': dependencies: @@ -37924,13 +37961,13 @@ snapshots: '@webpack-cli/info@1.5.0(webpack-cli@4.10.0)': dependencies: - envinfo: 7.20.0 + envinfo: 7.21.0 webpack-cli: 4.10.0(webpack-dev-server@5.2.2)(webpack@5.103.0) '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.103.0)': dependencies: webpack: 5.103.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.103.0) + webpack-cli: 5.1.4(webpack-dev-server@5.2.2)(webpack@5.103.0) '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.103.0)': dependencies: @@ -37961,7 +37998,7 @@ snapshots: '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.103.0)': dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.103.0) optionalDependencies: webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.103.0) @@ -38013,7 +38050,7 @@ snapshots: accepts@2.0.0: dependencies: - mime-types: 3.0.1 + mime-types: 3.0.2 negotiator: 1.0.0 acorn-globals@3.1.0: @@ -38090,19 +38127,19 @@ snapshots: clean-stack: 4.2.0 indent-string: 5.0.0 - ai@5.0.93(zod@3.25.76): + ai@5.0.106(zod@3.25.76): dependencies: - '@ai-sdk/gateway': 2.0.9(zod@3.25.76) + '@ai-sdk/gateway': 2.0.18(zod@3.25.76) '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@3.25.76) + '@ai-sdk/provider-utils': 3.0.18(zod@3.25.76) '@opentelemetry/api': 1.9.0 zod: 3.25.76 - ai@5.0.93(zod@4.1.11): + ai@5.0.106(zod@4.1.11): dependencies: - '@ai-sdk/gateway': 2.0.9(zod@4.1.11) + '@ai-sdk/gateway': 2.0.18(zod@4.1.11) '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.17(zod@4.1.11) + '@ai-sdk/provider-utils': 3.0.18(zod@4.1.11) '@opentelemetry/api': 1.9.0 zod: 4.1.11 @@ -38488,7 +38525,7 @@ snapshots: autoprefixer@10.4.22(postcss@8.5.6): dependencies: browserslist: 4.28.0 - caniuse-lite: 1.0.30001755 + caniuse-lite: 1.0.30001757 fraction.js: 5.3.4 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -38498,7 +38535,7 @@ snapshots: autoprefixer@6.7.7: dependencies: browserslist: 1.7.7 - caniuse-db: 1.0.30001755 + caniuse-db: 1.0.30001757 normalize-range: 0.1.2 num2fraction: 1.2.2 postcss: 5.2.18 @@ -38507,7 +38544,7 @@ snapshots: autoprefixer@7.1.6: dependencies: browserslist: 2.11.3 - caniuse-lite: 1.0.30001755 + caniuse-lite: 1.0.30001757 normalize-range: 0.1.2 num2fraction: 1.2.2 postcss: 6.0.23 @@ -38516,7 +38553,7 @@ snapshots: autoprefixer@9.8.8: dependencies: browserslist: 4.28.0 - caniuse-lite: 1.0.30001755 + caniuse-lite: 1.0.30001757 normalize-range: 0.1.2 num2fraction: 1.2.2 picocolors: 0.2.1 @@ -38746,7 +38783,7 @@ snapshots: dependencies: '@babel/core': 7.27.7 find-up: 5.0.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) babel-loader@7.1.2(babel-core@7.0.0-bridge.0(@babel/core@7.27.7))(webpack@5.103.0): dependencies: @@ -38754,7 +38791,7 @@ snapshots: find-cache-dir: 1.0.0 loader-utils: 1.4.2 mkdirp: 0.5.6 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) babel-loader@7.1.2(babel-core@7.0.0-bridge.0(@babel/core@7.28.5))(webpack@5.103.0): dependencies: @@ -38764,14 +38801,14 @@ snapshots: mkdirp: 0.5.6 webpack: 5.103.0(webpack-cli@5.1.4) - babel-loader@8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + babel-loader@8.4.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@babel/core': 7.27.7 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) babel-loader@8.4.1(@babel/core@7.27.7)(webpack@5.103.0): dependencies: @@ -38780,14 +38817,14 @@ snapshots: loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - babel-loader@9.2.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + babel-loader@9.2.1(@babel/core@7.27.7)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@babel/core': 7.27.7 find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) babel-loader@9.2.1(@babel/core@7.27.7)(webpack@5.103.0): dependencies: @@ -39354,7 +39391,7 @@ snapshots: bare-events@2.8.2: {} - bare-fs@4.5.1: + bare-fs@4.5.2: dependencies: bare-events: 2.8.2 bare-path: 3.0.0 @@ -39393,7 +39430,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.8.29: {} + baseline-browser-mapping@2.8.32: {} basic-auth@2.0.1: dependencies: @@ -39452,31 +39489,31 @@ snapshots: blueimp-md5@2.19.0: {} - body-parser@1.20.3: + body-parser@1.20.4: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 + qs: 6.14.0 + raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 - body-parser@2.2.0: + body-parser@2.2.1: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 4.4.3(supports-color@8.1.1) - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.0 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.1 + raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -39490,7 +39527,7 @@ snapshots: boundary@2.0.0: {} - bowser@2.12.1: {} + bowser@2.13.1: {} boxen@1.3.0: dependencies: @@ -39546,19 +39583,19 @@ snapshots: browserslist@1.7.7: dependencies: - caniuse-db: 1.0.30001755 - electron-to-chromium: 1.5.255 + caniuse-db: 1.0.30001757 + electron-to-chromium: 1.5.263 browserslist@2.11.3: dependencies: - caniuse-lite: 1.0.30001755 - electron-to-chromium: 1.5.255 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.263 browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.29 - caniuse-lite: 1.0.30001755 - electron-to-chromium: 1.5.255 + baseline-browser-mapping: 2.8.32 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.263 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -39727,10 +39764,10 @@ snapshots: normalize-url: 8.1.0 responselike: 3.0.0 - cacheable@2.2.0: + cacheable@2.3.0: dependencies: - '@cacheable/memory': 2.0.5 - '@cacheable/utils': 2.3.1 + '@cacheable/memory': 2.0.6 + '@cacheable/utils': 2.3.2 hookified: 1.13.0 keyv: 5.5.4 qified: 0.5.2 @@ -39797,20 +39834,20 @@ snapshots: caniuse-api@1.6.1: dependencies: browserslist: 1.7.7 - caniuse-db: 1.0.30001755 + caniuse-db: 1.0.30001757 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 caniuse-api@3.0.0: dependencies: browserslist: 4.28.0 - caniuse-lite: 1.0.30001755 + caniuse-lite: 1.0.30001757 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-db@1.0.30001755: {} + caniuse-db@1.0.30001757: {} - caniuse-lite@1.0.30001755: {} + caniuse-lite@1.0.30001757: {} canvas@3.2.0: dependencies: @@ -40067,9 +40104,9 @@ snapshots: is-wsl: 3.1.0 is64bit: 2.0.0 - clipboardy@5.0.0: + clipboardy@5.0.1: dependencies: - execa: 9.6.0 + execa: 9.6.1 is-wayland: 0.1.0 is-wsl: 3.1.0 is64bit: 2.0.0 @@ -40356,12 +40393,10 @@ snapshots: convert-source-map@2.0.0: {} - cookie-signature@1.0.6: {} + cookie-signature@1.0.7: {} cookie-signature@1.2.2: {} - cookie@0.7.1: {} - cookie@0.7.2: {} copy-concurrently@1.0.5: @@ -40384,7 +40419,7 @@ snapshots: schema-utils: 4.3.3 serialize-javascript: 6.0.2 tinyglobby: 0.2.15 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) copyfiles@2.4.1: dependencies: @@ -40505,13 +40540,13 @@ snapshots: dependencies: capture-stack-trace: 1.0.2 - create-jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + create-jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -40597,7 +40632,7 @@ snapshots: postcss-value-parser: 3.3.1 source-list-map: 2.0.1 - css-loader@3.6.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + css-loader@3.6.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: camelcase: 5.3.1 cssesc: 3.0.0 @@ -40612,7 +40647,7 @@ snapshots: postcss-value-parser: 4.2.0 schema-utils: 2.7.1 semver: 6.3.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) css-loader@3.6.0(webpack@5.103.0): dependencies: @@ -40629,7 +40664,7 @@ snapshots: postcss-value-parser: 4.2.0 schema-utils: 2.7.1 semver: 6.3.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) css-loader@5.2.7(webpack@5.103.0): dependencies: @@ -40645,7 +40680,7 @@ snapshots: semver: 7.7.3 webpack: 5.103.0(webpack-cli@5.1.4) - css-loader@6.11.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + css-loader@6.11.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -40656,9 +40691,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) - css-loader@6.11.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + css-loader@6.11.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -40669,7 +40704,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) css-loader@6.11.0(webpack@5.103.0): dependencies: @@ -40695,7 +40730,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) css-select@4.3.0: dependencies: @@ -41336,7 +41371,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.255: {} + electron-to-chromium@1.5.263: {} email-addresses@5.0.0: {} @@ -41411,7 +41446,7 @@ snapshots: env-paths@2.2.1: {} - envinfo@7.20.0: {} + envinfo@7.21.0: {} environment@1.1.0: {} @@ -41818,7 +41853,7 @@ snapshots: eslint-plugin-storybook@9.1.16(eslint@8.57.1)(storybook@9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3))(typescript@5.8.3): dependencies: - '@typescript-eslint/utils': 8.47.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 8.48.1(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 storybook: 9.1.16(@testing-library/dom@10.4.1)(prettier@3.5.3) transitivePeerDependencies: @@ -41965,13 +42000,13 @@ snapshots: '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.3 '@eslint/core': 0.13.0 - '@eslint/eslintrc': 3.3.1 + '@eslint/eslintrc': 3.3.3 '@eslint/js': 9.26.0 '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 - '@modelcontextprotocol/sdk': 1.22.0 + '@modelcontextprotocol/sdk': 1.24.0 '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 ajv: 6.12.6 @@ -42010,7 +42045,7 @@ snapshots: '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.3 '@eslint/core': 0.14.0 - '@eslint/eslintrc': 3.3.1 + '@eslint/eslintrc': 3.3.3 '@eslint/js': 9.27.0 '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.7 @@ -42223,7 +42258,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - execa@9.6.0: + execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.6 @@ -42287,61 +42322,62 @@ snapshots: exponential-backoff@3.1.3: {} - express-rate-limit@7.5.1(express@5.1.0): + express-rate-limit@7.5.1(express@5.2.1): dependencies: - express: 5.1.0 + express: 5.2.1 - express@4.21.2: + express@4.22.1: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.3 + body-parser: 1.20.4 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 + cookie: 0.7.2 + cookie-signature: 1.0.7 debug: 2.6.9 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.1 + finalhandler: 1.3.2 fresh: 0.5.2 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.13.0 + qs: 6.14.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.0 + send: 0.19.1 serve-static: 1.16.2 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 - express@5.1.0: + express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 + body-parser: 2.2.1 content-disposition: 1.0.1 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 debug: 4.4.3(supports-color@8.1.1) + depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.1 fresh: 2.0.0 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 2.0.0 - mime-types: 3.0.1 + mime-types: 3.0.2 on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 @@ -42385,7 +42421,7 @@ snapshots: async: 2.6.4 loader-utils: 1.4.2 schema-utils: 0.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-sources: 1.4.3 extract-zip@1.7.0: @@ -42531,7 +42567,7 @@ snapshots: dependencies: is-unicode-supported: 2.1.0 - file-entry-cache@10.1.4: + file-entry-cache@11.1.1: dependencies: flat-cache: 6.1.19 @@ -42557,19 +42593,19 @@ snapshots: dependencies: loader-utils: 1.4.2 schema-utils: 0.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) file-loader@6.2.0(webpack@5.103.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) file-system-cache@1.1.0: dependencies: @@ -42623,17 +42659,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.1: + finalhandler@1.3.2: dependencies: debug: 2.6.9 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 unpipe: 1.0.0 - finalhandler@2.1.0: + finalhandler@2.1.1: dependencies: debug: 4.4.3(supports-color@8.1.1) encodeurl: 2.0.0 @@ -42730,7 +42766,7 @@ snapshots: flat-cache@6.1.19: dependencies: - cacheable: 2.2.0 + cacheable: 2.3.0 flatted: 3.3.3 hookified: 1.13.0 @@ -42788,7 +42824,7 @@ snapshots: lodash.startswith: 4.2.1 minimatch: 3.1.2 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) fork-ts-checker-webpack-plugin@4.1.6: dependencies: @@ -42840,7 +42876,7 @@ snapshots: optionalDependencies: eslint: 9.27.0(jiti@2.6.1) - fork-ts-checker-webpack-plugin@6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + fork-ts-checker-webpack-plugin@6.5.3(eslint@9.27.0(jiti@2.6.1))(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@babel/code-frame': 7.27.1 '@types/json-schema': 7.0.15 @@ -42856,7 +42892,7 @@ snapshots: semver: 7.7.3 tapable: 1.1.3 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: eslint: 9.27.0(jiti@2.6.1) @@ -42876,11 +42912,11 @@ snapshots: semver: 7.7.3 tapable: 1.1.3 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: eslint: 9.27.0(jiti@2.6.1) - fork-ts-checker-webpack-plugin@8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -42895,9 +42931,9 @@ snapshots: semver: 7.7.3 tapable: 2.3.0 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) - fork-ts-checker-webpack-plugin@8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.8.3)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -42912,7 +42948,7 @@ snapshots: semver: 7.7.3 tapable: 2.3.0 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) fork-ts-checker-webpack-plugin@8.0.0(typescript@5.8.3)(webpack@5.103.0): dependencies: @@ -42946,7 +42982,7 @@ snapshots: semver: 7.7.3 tapable: 2.3.0 typescript: 5.8.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) form-data-encoder@2.1.4: {} @@ -43571,7 +43607,7 @@ snapshots: has@1.0.4: {} - hashery@1.2.0: + hashery@1.3.0: dependencies: hookified: 1.13.0 @@ -43664,7 +43700,7 @@ snapshots: hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 parse5: 7.3.0 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 @@ -43859,9 +43895,9 @@ snapshots: lodash: 4.17.21 pretty-error: 2.1.2 toposort: 1.0.7 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - html-webpack-plugin@4.5.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + html-webpack-plugin@4.5.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@types/html-minifier-terser': 5.1.2 '@types/tapable': 1.0.12 @@ -43872,7 +43908,7 @@ snapshots: pretty-error: 2.1.2 tapable: 1.1.3 util.promisify: 1.0.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) html-webpack-plugin@4.5.2(webpack@5.103.0): dependencies: @@ -43885,9 +43921,9 @@ snapshots: pretty-error: 2.1.2 tapable: 1.1.3 util.promisify: 1.0.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - html-webpack-plugin@5.6.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + html-webpack-plugin@5.6.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -43895,9 +43931,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.0 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) - html-webpack-plugin@5.6.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + html-webpack-plugin@5.6.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -43905,7 +43941,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.0 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) html-webpack-plugin@5.6.5(webpack@5.103.0): dependencies: @@ -43915,7 +43951,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.0 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) htmlparser2@10.0.0: dependencies: @@ -43950,6 +43986,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-parser-js@0.5.10: {} http-proxy-agent@4.0.1: @@ -44238,7 +44282,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.2.0: {} + ipaddr.js@2.3.0: {} is-absolute-url@2.1.0: {} @@ -44897,16 +44941,16 @@ snapshots: - supports-color - utf-8-validate - jest-cli@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest-cli@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + create-jest: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-config: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -44916,15 +44960,15 @@ snapshots: - supports-color - ts-node - jest-cli@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest-cli@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: - '@jest/core': 30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + '@jest/core': 30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) '@jest/test-result': 30.2.0 '@jest/types': 30.2.0 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-config: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-util: 30.2.0 jest-validate: 30.2.0 yargs: 17.7.2 @@ -44989,7 +45033,7 @@ snapshots: - supports-color - utf-8-validate - jest-config@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest-config@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: '@babel/core': 7.27.7 '@jest/test-sequencer': 29.7.0 @@ -45015,12 +45059,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 22.15.35 - ts-node: 10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest-config@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: '@babel/core': 7.27.7 '@jest/get-type': 30.1.0 @@ -45049,7 +45093,7 @@ snapshots: optionalDependencies: '@types/node': 22.15.35 esbuild-register: 3.6.0(esbuild@0.25.12) - ts-node: 10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -46026,24 +46070,24 @@ snapshots: - supports-color - utf-8-validate - jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-cli: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: - '@jest/core': 30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + '@jest/core': 30.2.0(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) '@jest/types': 30.2.0 import-local: 3.2.0 - jest-cli: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest-cli: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -46063,6 +46107,8 @@ snapshots: '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 + jose@6.1.3: {} + jpjs@1.2.1: {} js-base64@2.6.4: {} @@ -46330,7 +46376,7 @@ snapshots: jsonwebtoken@9.0.2: dependencies: - jws: 3.2.2 + jws: 3.2.3 lodash.includes: 4.3.0 lodash.isboolean: 3.0.3 lodash.isinteger: 4.0.4 @@ -46370,7 +46416,7 @@ snapshots: ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - jws@3.2.2: + jws@3.2.3: dependencies: jwa: 1.4.2 safe-buffer: 5.2.1 @@ -46484,7 +46530,7 @@ snapshots: dependencies: uc.micro: 2.1.0 - lint-staged@16.2.6: + lint-staged@16.2.7: dependencies: commander: 14.0.2 listr2: 9.0.5 @@ -46492,7 +46538,7 @@ snapshots: nano-spawn: 2.0.0 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.8.1 + yaml: 2.8.2 listenercount@1.0.1: {} @@ -46706,7 +46752,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.2: {} + lru-cache@11.2.4: {} lru-cache@4.1.5: dependencies: @@ -47057,7 +47103,7 @@ snapshots: unist-util-position: 4.0.4 unist-util-visit: 4.1.2 - mdast-util-to-hast@13.2.0: + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -47116,7 +47162,7 @@ snapshots: dependencies: fs-monkey: 1.1.0 - memfs@4.51.0: + memfs@4.51.1: dependencies: '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) @@ -47632,7 +47678,7 @@ snapshots: dependencies: mime-db: 1.52.0 - mime-types@3.0.1: + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -47982,7 +48028,7 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-forge@1.3.1: {} + node-forge@1.3.2: {} node-gyp-build@4.8.4: optional: true @@ -48049,7 +48095,7 @@ snapshots: node-releases@2.0.27: {} - node-sarif-builder@3.3.0: + node-sarif-builder@3.3.1: dependencies: '@types/sarif': 2.1.7 fs-extra: 11.3.2 @@ -48620,7 +48666,7 @@ snapshots: path-scurry@2.0.1: dependencies: - lru-cache: 11.2.2 + lru-cache: 11.2.4 minipass: 7.1.2 path-to-regexp@0.1.12: {} @@ -48720,7 +48766,7 @@ snapshots: pkce-challenge@4.1.0: {} - pkce-challenge@5.0.0: {} + pkce-challenge@5.0.1: {} pkg-dir@2.0.0: dependencies: @@ -48906,21 +48952,21 @@ snapshots: postcss-load-options: 1.2.0 postcss-load-plugins: 2.3.0 - postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3) - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 - yaml: 2.8.1 + yaml: 2.8.2 postcss-load-options@1.2.0: dependencies: @@ -48939,7 +48985,7 @@ snapshots: postcss-load-config: 1.2.0 schema-utils: 0.3.0 - postcss-loader@4.3.0(postcss@7.0.39)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + postcss-loader@4.3.0(postcss@7.0.39)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 @@ -48947,7 +48993,7 @@ snapshots: postcss: 7.0.39 schema-utils: 3.3.0 semver: 7.7.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) postcss-loader@4.3.0(postcss@7.0.39)(webpack@5.103.0): dependencies: @@ -48957,7 +49003,7 @@ snapshots: postcss: 7.0.39 schema-utils: 3.3.0 semver: 7.7.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.8.3)(webpack@5.103.0): dependencies: @@ -49081,7 +49127,7 @@ snapshots: dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 postcss-modules-scope@1.1.0: @@ -49097,7 +49143,7 @@ snapshots: postcss-modules-scope@3.2.1(postcss@8.5.6): dependencies: postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-modules-values@1.3.0: dependencies: @@ -49242,7 +49288,7 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.0: + postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -49565,10 +49611,6 @@ snapshots: dependencies: hookified: 1.13.0 - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -49613,31 +49655,31 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.2: + raw-body@2.5.3: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.1: + raw-body@3.0.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.7.0 unpipe: 1.0.0 - raw-loader@4.0.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + raw-loader@4.0.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) raw-loader@4.0.2(webpack@5.103.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) rc-config-loader@4.1.3: dependencies: @@ -49979,7 +50021,7 @@ snapshots: devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 react: 18.2.0 remark-parse: 11.0.0 remark-rehype: 11.1.2 @@ -50017,7 +50059,7 @@ snapshots: devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 react: 18.2.0 remark-parse: 11.0.0 remark-rehype: 11.1.2 @@ -50109,7 +50151,7 @@ snapshots: optionalDependencies: '@types/react': 18.2.0 - react-remove-scroll@2.7.1(@types/react@18.2.0)(react@18.2.0): + react-remove-scroll@2.7.2(@types/react@18.2.0)(react@18.2.0): dependencies: react: 18.2.0 react-remove-scroll-bar: 2.3.8(@types/react@18.2.0)(react@18.2.0) @@ -50120,7 +50162,7 @@ snapshots: optionalDependencies: '@types/react': 18.2.0 - react-remove-scroll@2.7.1(@types/react@18.2.0)(react@18.3.1): + react-remove-scroll@2.7.2(@types/react@18.2.0)(react@18.3.1): dependencies: react: 18.3.1 react-remove-scroll-bar: 2.3.8(@types/react@18.2.0)(react@18.3.1) @@ -50131,7 +50173,7 @@ snapshots: optionalDependencies: '@types/react': 18.2.0 - react-scripts-ts@3.1.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(babel-core@7.0.0-bridge.0(@babel/core@7.27.7))(babel-runtime@6.26.0)(typescript@5.8.3)(webpack-cli@6.0.1): + react-scripts-ts@3.1.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(babel-core@7.0.0-bridge.0(@babel/core@7.27.7))(babel-runtime@6.26.0)(typescript@5.8.3)(webpack-cli@6.0.1): dependencies: autoprefixer: 7.1.6 babel-jest: 20.0.3 @@ -50167,7 +50209,7 @@ snapshots: typescript: 5.8.3 uglifyjs-webpack-plugin: 1.2.5(webpack@5.103.0) url-loader: 0.6.2(file-loader@1.1.5(webpack@5.103.0)) - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.103.0) webpack-manifest-plugin: 1.3.2(webpack@5.103.0) whatwg-fetch: 2.0.3 @@ -50698,7 +50740,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 unified: 11.0.5 vfile: 6.0.3 @@ -50896,16 +50938,16 @@ snapshots: glob: 11.1.0 package-json-from-dist: 1.0.1 - rollup-plugin-import-css@3.5.8(rollup@4.53.2): + rollup-plugin-import-css@3.5.8(rollup@4.53.3): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.53.2) - rollup: 4.53.2 + '@rollup/pluginutils': 5.3.0(rollup@4.53.3) + rollup: 4.53.3 - rollup-plugin-peer-deps-external@2.2.4(rollup@4.53.2): + rollup-plugin-peer-deps-external@2.2.4(rollup@4.53.3): dependencies: - rollup: 4.53.2 + rollup: 4.53.3 - rollup-plugin-postcss@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): + rollup-plugin-postcss@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)): dependencies: chalk: 4.1.2 concat-with-sourcemaps: 1.1.0 @@ -50914,7 +50956,7 @@ snapshots: p-queue: 6.6.2 pify: 5.0.0 postcss: 8.5.6 - postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) postcss-modules: 4.3.1(postcss@8.5.6) promise.series: 0.2.0 resolve: 1.22.11 @@ -50959,12 +51001,12 @@ snapshots: tslib: 2.0.1 typescript: 3.9.10 - rollup-plugin-typescript2@0.36.0(rollup@4.53.2)(typescript@5.8.3): + rollup-plugin-typescript2@0.36.0(rollup@4.53.3)(typescript@5.8.3): dependencies: '@rollup/pluginutils': 4.2.1 find-cache-dir: 3.3.2 fs-extra: 10.1.0 - rollup: 4.53.2 + rollup: 4.53.3 semver: 7.7.3 tslib: 2.8.1 typescript: 5.8.3 @@ -50984,32 +51026,32 @@ snapshots: '@types/node': 22.15.35 acorn: 7.4.1 - rollup@4.53.2: + rollup@4.53.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.2 - '@rollup/rollup-android-arm64': 4.53.2 - '@rollup/rollup-darwin-arm64': 4.53.2 - '@rollup/rollup-darwin-x64': 4.53.2 - '@rollup/rollup-freebsd-arm64': 4.53.2 - '@rollup/rollup-freebsd-x64': 4.53.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 - '@rollup/rollup-linux-arm-musleabihf': 4.53.2 - '@rollup/rollup-linux-arm64-gnu': 4.53.2 - '@rollup/rollup-linux-arm64-musl': 4.53.2 - '@rollup/rollup-linux-loong64-gnu': 4.53.2 - '@rollup/rollup-linux-ppc64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-musl': 4.53.2 - '@rollup/rollup-linux-s390x-gnu': 4.53.2 - '@rollup/rollup-linux-x64-gnu': 4.53.2 - '@rollup/rollup-linux-x64-musl': 4.53.2 - '@rollup/rollup-openharmony-arm64': 4.53.2 - '@rollup/rollup-win32-arm64-msvc': 4.53.2 - '@rollup/rollup-win32-ia32-msvc': 4.53.2 - '@rollup/rollup-win32-x64-gnu': 4.53.2 - '@rollup/rollup-win32-x64-msvc': 4.53.2 + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 router@2.2.0: @@ -51109,21 +51151,21 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-loader@13.3.3(sass@1.94.1)(webpack@5.103.0): + sass-loader@13.3.3(sass@1.94.2)(webpack@5.103.0): dependencies: neo-async: 2.6.2 webpack: 5.103.0(webpack-cli@5.1.4) optionalDependencies: - sass: 1.94.1 + sass: 1.94.2 - sass-loader@16.0.6(sass@1.94.1)(webpack@5.103.0): + sass-loader@16.0.6(sass@1.94.2)(webpack@5.103.0): dependencies: neo-async: 2.6.2 optionalDependencies: - sass: 1.94.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + sass: 1.94.2 + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - sass@1.94.1: + sass@1.94.2: dependencies: chokidar: 4.0.3 immutable: 5.1.4 @@ -51212,7 +51254,7 @@ snapshots: selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.14 - node-forge: 1.3.1 + node-forge: 1.3.2 semver-diff@2.1.0: dependencies: @@ -51242,6 +51284,22 @@ snapshots: range-parser: 1.2.1 statuses: 2.0.1 + send@0.19.1: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + send@1.2.0: dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -51249,8 +51307,8 @@ snapshots: escape-html: 1.0.3 etag: 1.8.1 fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 + http-errors: 2.0.1 + mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 @@ -51983,11 +52041,11 @@ snapshots: loader-utils: 1.4.2 schema-utils: 0.3.0 - style-loader@1.3.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + style-loader@1.3.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 schema-utils: 2.7.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) style-loader@1.3.0(webpack@5.103.0): dependencies: @@ -51999,15 +52057,15 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - style-loader@3.3.4(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + style-loader@3.3.4(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) - style-loader@3.3.4(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + style-loader@3.3.4(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) style-loader@3.3.4(webpack@5.103.0): dependencies: @@ -52015,7 +52073,7 @@ snapshots: style-loader@4.0.0(webpack@5.103.0): dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) style-mod@4.1.3: {} @@ -52042,21 +52100,22 @@ snapshots: postcss: 8.5.6 postcss-selector-parser: 6.1.2 - stylelint-config-recommended@16.0.0(stylelint@16.25.0(typescript@5.8.3)): + stylelint-config-recommended@16.0.0(stylelint@16.26.1(typescript@5.8.3)): dependencies: - stylelint: 16.25.0(typescript@5.8.3) + stylelint: 16.26.1(typescript@5.8.3) - stylelint-config-standard@38.0.0(stylelint@16.25.0(typescript@5.8.3)): + stylelint-config-standard@38.0.0(stylelint@16.26.1(typescript@5.8.3)): dependencies: - stylelint: 16.25.0(typescript@5.8.3) - stylelint-config-recommended: 16.0.0(stylelint@16.25.0(typescript@5.8.3)) + stylelint: 16.26.1(typescript@5.8.3) + stylelint-config-recommended: 16.0.0(stylelint@16.26.1(typescript@5.8.3)) - stylelint@16.25.0(typescript@5.8.3): + stylelint@16.26.1(typescript@5.8.3): dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-syntax-patches-for-csstree': 1.0.20 '@csstools/css-tokenizer': 3.0.4 '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) '@dual-bundle/import-meta-resolve': 4.2.1 balanced-match: 2.0.0 colord: 2.9.3 @@ -52066,7 +52125,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 - file-entry-cache: 10.1.4 + file-entry-cache: 11.1.1 global-modules: 2.0.0 globby: 11.1.0 globjoin: 0.1.4 @@ -52083,7 +52142,7 @@ snapshots: postcss: 8.5.6 postcss-resolve-nested-selector: 0.1.6 postcss-safe-parser: 7.0.1(postcss@8.5.6) - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 string-width: 4.2.3 @@ -52101,14 +52160,14 @@ snapshots: dependencies: minimist: 1.2.8 - sucrase@3.35.0: + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.5.0 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 + tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 supports-color@2.0.0: {} @@ -52156,7 +52215,7 @@ snapshots: svg-url-loader@8.0.0(webpack@5.103.0): dependencies: file-loader: 6.2.0(webpack@5.103.0) - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) svg2ttf@4.3.0: dependencies: @@ -52220,7 +52279,7 @@ snapshots: del: 2.2.2 sw-precache: 5.2.1 uglify-js: 3.19.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) sw-precache@5.2.1: dependencies: @@ -52244,11 +52303,11 @@ snapshots: dependencies: '@babel/runtime-corejs3': 7.28.4 '@scarf/scarf': 1.4.0 - '@swagger-api/apidom-core': 1.0.0-rc.3 - '@swagger-api/apidom-error': 1.0.0-rc.3 - '@swagger-api/apidom-json-pointer': 1.0.0-rc.3 - '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.3 - '@swagger-api/apidom-reference': 1.0.0-rc.3 + '@swagger-api/apidom-core': 1.0.0-rc.4 + '@swagger-api/apidom-error': 1.0.0-rc.4 + '@swagger-api/apidom-json-pointer': 1.0.0-rc.4 + '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-rc.4 + '@swagger-api/apidom-reference': 1.0.0-rc.4 '@swaggerexpert/cookie': 2.0.2 deepmerge: 4.3.1 fast-json-patch: 3.1.1 @@ -52304,7 +52363,7 @@ snapshots: - '@types/react' - debug - swagger-ui-react@5.30.2(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + swagger-ui-react@5.30.3(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@babel/runtime-corejs3': 7.28.4 '@scarf/scarf': 1.4.0 @@ -52346,15 +52405,15 @@ snapshots: - '@types/react' - debug - swc-loader@0.2.6(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + swc-loader@0.2.6(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) '@swc/counter': 0.1.3 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) - swc-loader@0.2.6(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0): + swc-loader@0.2.6(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0): dependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) '@swc/counter': 0.1.3 webpack: 5.103.0(webpack-cli@5.1.4) @@ -52399,7 +52458,7 @@ snapshots: tailwind-merge@2.6.0: {} - tailwindcss@3.4.18(yaml@2.8.1): + tailwindcss@3.4.18(yaml@2.8.2): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -52418,11 +52477,11 @@ snapshots: postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) postcss-js: 4.1.0(postcss@8.5.6) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.1) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.11 - sucrase: 3.35.0 + sucrase: 3.35.1 transitivePeerDependencies: - tsx - yaml @@ -52440,7 +52499,7 @@ snapshots: pump: 3.0.3 tar-stream: 3.1.7 optionalDependencies: - bare-fs: 4.5.1 + bare-fs: 4.5.2 bare-path: 3.0.0 transitivePeerDependencies: - bare-abort-controller @@ -52529,7 +52588,7 @@ snapshots: ansi-escapes: 7.2.0 supports-hyperlinks: 3.2.0 - terser-webpack-plugin@4.2.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + terser-webpack-plugin@4.2.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: cacache: 15.3.0 find-cache-dir: 3.3.2 @@ -52539,7 +52598,7 @@ snapshots: serialize-javascript: 5.0.1 source-map: 0.6.1 terser: 5.44.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) webpack-sources: 1.4.3 terser-webpack-plugin@4.2.3(webpack@5.103.0): @@ -52552,33 +52611,33 @@ snapshots: serialize-javascript: 5.0.1 source-map: 0.6.1 terser: 5.44.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-sources: 1.4.3 - terser-webpack-plugin@5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + terser-webpack-plugin@5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) optionalDependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) esbuild: 0.25.12 - terser-webpack-plugin@5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + terser-webpack-plugin@5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) - terser-webpack-plugin@5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0): + terser-webpack-plugin@5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -52587,7 +52646,7 @@ snapshots: terser: 5.44.1 webpack: 5.103.0(webpack-cli@5.1.4) optionalDependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) terser@4.8.1: dependencies: @@ -52741,8 +52800,6 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - toml@3.0.0: {} - toposort@1.0.7: {} toposort@2.0.2: {} @@ -52873,12 +52930,12 @@ snapshots: typescript: 3.9.10 yargs-parser: 18.1.3 - ts-jest@29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -52893,12 +52950,12 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.27.7) - ts-jest@29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@30.2.0(@babel/core@7.27.7))(esbuild@0.25.12)(jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@30.2.0(@babel/core@7.27.7))(esbuild@0.25.12)(jest@30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) + jest: 30.2.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0)(esbuild-register@3.6.0(esbuild@0.25.12))(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -52943,7 +53000,7 @@ snapshots: '@ts-morph/common': 0.27.0 code-block-writer: 13.0.3 - ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.18)(typescript@5.8.3): + ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.18)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -52961,9 +53018,9 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) - ts-node@10.9.2(@swc/core@1.15.2(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3): + ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.17))(@types/node@22.15.35)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -52981,7 +53038,7 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.2(@swc/helpers@0.5.17) + '@swc/core': 1.15.3(@swc/helpers@0.5.17) optional: true ts-pnp@1.2.0(typescript@4.9.5): @@ -53277,7 +53334,7 @@ snapshots: dependencies: content-type: 1.0.5 media-typer: 1.1.0 - mime-types: 3.0.1 + mime-types: 3.0.2 type@2.7.3: {} @@ -53364,7 +53421,7 @@ snapshots: serialize-javascript: 1.9.1 source-map: 0.6.1 uglify-es: 3.3.9 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-sources: 1.4.3 worker-farm: 1.7.0 @@ -53666,21 +53723,21 @@ snapshots: mime: 1.6.0 schema-utils: 0.3.0 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optionalDependencies: - file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + file-loader: 6.2.0(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) url-loader@4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) optionalDependencies: file-loader: 6.2.0(webpack@5.103.0) @@ -53935,7 +53992,7 @@ snapshots: '@redhat-developer/locators': 1.17.0(@redhat-developer/page-objects@1.17.0(selenium-webdriver@4.38.0)(typescript@5.8.3))(selenium-webdriver@4.38.0) '@redhat-developer/page-objects': 1.17.0(selenium-webdriver@4.38.0)(typescript@5.8.3) '@types/selenium-webdriver': 4.35.4 - '@vscode/vsce': 3.7.0 + '@vscode/vsce': 3.7.1 c8: 10.1.3 commander: 13.1.0 compare-versions: 6.1.1 @@ -54154,7 +54211,7 @@ snapshots: colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.6 - envinfo: 7.20.0 + envinfo: 7.21.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 @@ -54173,7 +54230,7 @@ snapshots: colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.6 - envinfo: 7.20.0 + envinfo: 7.21.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 @@ -54190,12 +54247,12 @@ snapshots: colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 - envinfo: 7.20.0 + envinfo: 7.21.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.103.0) @@ -54209,7 +54266,7 @@ snapshots: colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 - envinfo: 7.20.0 + envinfo: 7.21.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 @@ -54217,13 +54274,13 @@ snapshots: webpack: 5.103.0(webpack-cli@6.0.1) webpack-merge: 6.0.1 - webpack-dev-middleware@3.7.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + webpack-dev-middleware@3.7.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: memory-fs: 0.4.1 mime: 2.6.0 mkdirp: 0.5.6 range-parser: 1.2.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) webpack-log: 2.0.0 webpack-dev-middleware@3.7.3(webpack@5.103.0): @@ -54232,7 +54289,7 @@ snapshots: mime: 2.6.0 mkdirp: 0.5.6 range-parser: 1.2.1 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-log: 2.0.0 webpack-dev-middleware@4.3.0(webpack@5.103.0): @@ -54243,9 +54300,9 @@ snapshots: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 3.3.0 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) - webpack-dev-middleware@6.1.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)): + webpack-dev-middleware@6.1.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)): dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -54253,9 +54310,9 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12) - webpack-dev-middleware@6.1.3(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + webpack-dev-middleware@6.1.3(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -54263,7 +54320,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) webpack-dev-middleware@6.1.3(webpack@5.103.0): dependencies: @@ -54275,23 +54332,23 @@ snapshots: optionalDependencies: webpack: 5.103.0(webpack-cli@5.1.4) - webpack-dev-middleware@7.4.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + webpack-dev-middleware@7.4.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: colorette: 2.0.20 - memfs: 4.51.0 - mime-types: 3.0.1 + memfs: 4.51.1 + mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) optional: true webpack-dev-middleware@7.4.5(webpack@5.103.0): dependencies: colorette: 2.0.20 - memfs: 4.51.0 - mime-types: 3.0.1 + memfs: 4.51.1 + mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.3 @@ -54314,10 +54371,10 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0 p-retry: 6.2.1 @@ -54354,10 +54411,10 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0 p-retry: 6.2.1 @@ -54393,10 +54450,10 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0 p-retry: 6.2.1 @@ -54408,7 +54465,7 @@ snapshots: webpack-dev-middleware: 7.4.5(webpack@5.103.0) ws: 8.18.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.103.0) transitivePeerDependencies: - bufferutil @@ -54416,7 +54473,7 @@ snapshots: - supports-color - utf-8-validate - webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + webpack-dev-server@5.2.2(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -54432,10 +54489,10 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0 p-retry: 6.2.1 @@ -54444,10 +54501,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + webpack-dev-middleware: 7.4.5(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) ws: 8.18.3 optionalDependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - bufferutil - debug @@ -54471,10 +54528,10 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0 p-retry: 6.2.1 @@ -54493,13 +54550,13 @@ snapshots: - supports-color - utf-8-validate - webpack-filter-warnings-plugin@1.2.1(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))): + webpack-filter-warnings-plugin@1.2.1(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))): dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)) webpack-filter-warnings-plugin@1.2.1(webpack@5.103.0): dependencies: - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-hot-middleware@2.26.1: dependencies: @@ -54516,7 +54573,7 @@ snapshots: dependencies: fs-extra: 0.30.0 lodash: 4.17.21 - webpack: 5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1) + webpack: 5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1) webpack-merge@5.10.0: dependencies: @@ -54551,7 +54608,7 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17)): + webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -54575,7 +54632,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -54583,7 +54640,7 @@ snapshots: - esbuild - uglify-js - webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12): + webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -54607,7 +54664,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(esbuild@0.25.12)) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)(webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(esbuild@0.25.12)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -54615,7 +54672,7 @@ snapshots: - esbuild - uglify-js - webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@5.1.4): + webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@5.1.4): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -54639,7 +54696,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: @@ -54649,7 +54706,7 @@ snapshots: - esbuild - uglify-js - webpack@5.103.0(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack-cli@6.0.1): + webpack@5.103.0(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -54673,7 +54730,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: @@ -54707,7 +54764,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: @@ -54741,11 +54798,11 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: - webpack-cli: 5.1.4(webpack@5.103.0) + webpack-cli: 5.1.4(webpack-dev-server@5.2.2)(webpack@5.103.0) transitivePeerDependencies: - '@swc/core' - esbuild @@ -54775,7 +54832,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.15.2(@swc/helpers@0.5.17))(webpack@5.103.0) + terser-webpack-plugin: 5.3.14(@swc/core@1.15.3(@swc/helpers@0.5.17))(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: @@ -55091,7 +55148,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} + yaml@2.8.2: {} yargs-parser@18.1.3: dependencies: @@ -55218,7 +55275,7 @@ snapshots: zenscroll@4.0.2: {} - zod-to-json-schema@3.24.6(zod@3.25.76): + zod-to-json-schema@3.25.0(zod@3.25.76): dependencies: zod: 3.25.76 @@ -55226,13 +55283,13 @@ snapshots: zod@4.1.11: {} - zustand@5.0.8(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)): + zustand@5.0.9(@types/react@18.2.0)(react@18.2.0)(use-sync-external-store@1.6.0(react@18.2.0)): optionalDependencies: '@types/react': 18.2.0 react: 18.2.0 use-sync-external-store: 1.6.0(react@18.2.0) - zustand@5.0.8(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)): + zustand@5.0.9(@types/react@18.2.0)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0)): optionalDependencies: '@types/react': 18.2.0 react: 19.1.0 diff --git a/package.json b/package.json index cab9d8f485f..70c0fe585c0 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "@eslint/plugin-kit": "^0.3.4", "on-headers": "^1.1.0", "form-data": "^4.0.4", - "tmp": "^0.2.4" + "tmp": "^0.2.4", + "express": "^4.22.1" } }, "scripts": { diff --git a/workspaces/api-designer/api-designer-extension/package.json b/workspaces/api-designer/api-designer-extension/package.json index 72a2b6ddeea..b52074ee9bf 100644 --- a/workspaces/api-designer/api-designer-extension/package.json +++ b/workspaces/api-designer/api-designer-extension/package.json @@ -83,7 +83,7 @@ "clean": "rimraf ./dist", "compile": "tsc -p .", "watch": "tsc -p . -w", - "package": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi", + "package": "node ../../common-libs/scripts/package-vsix.js", "build": "pnpm clean && pnpm run copyFonts && webpack --mode production --devtool hidden-source-map && pnpm run package && pnpm run postbuild", "compile-tests": "pnpm run compile", "watch-tests": "pnpm run watch", diff --git a/workspaces/apk/apk-extension/package.json b/workspaces/apk/apk-extension/package.json index cd3478bc546..f08b7fffdf4 100644 --- a/workspaces/apk/apk-extension/package.json +++ b/workspaces/apk/apk-extension/package.json @@ -51,7 +51,7 @@ "pretest": "npm run compile && npm run lint", "lint": "eslint src --ext ts", "test": "node ./out/test/runTest.js", - "build": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi && pnpm run postbuild", + "build": "node ../../common-libs/scripts/package-vsix.js && pnpm run postbuild", "postbuild": "pnpm run copyVSIX", "copyVSIX": "copyfiles *.vsix ./vsix", "copyVSIXToRoot": "copyfiles -f ./vsix/* ../../.." diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/constants.ts b/workspaces/ballerina/ballerina-core/src/interfaces/constants.ts index 1610359e428..0266888301a 100644 --- a/workspaces/ballerina/ballerina-core/src/interfaces/constants.ts +++ b/workspaces/ballerina/ballerina-core/src/interfaces/constants.ts @@ -32,7 +32,6 @@ export const BI_COMMANDS = { BI_RUN_PROJECT: 'BI.project.run', BI_DEBUG_PROJECT: 'BI.project.debug', REFRESH_COMMAND: 'BI.project-explorer.refresh', - FOCUS_PROJECT_EXPLORER: 'BI.project-explorer.focus', PROJECT_EXPLORER: 'BI.project-explorer', ADD_CONNECTIONS: 'BI.project-explorer.add-connection', ADD_CUSTOM_CONNECTOR: 'BI.project-explorer.add-custom-connector', @@ -52,5 +51,8 @@ export const BI_COMMANDS = { BI_EDIT_TEST_FUNCTION_DEF: 'BI.test.edit.function.def', ADD_NATURAL_FUNCTION: 'BI.project-explorer.add-natural-function', TOGGLE_TRACE_LOGS: 'BI.toggle.trace.logs', + CREATE_BI_PROJECT: 'BI.project.createBIProjectPure', + CREATE_BI_MIGRATION_PROJECT: 'BI.project.createBIProjectMigration', ADD_INTEGRATION: 'BI.project-explorer.add-integration', + NOTIFY_PROJECT_EXPLORER: 'BI.project-explorer.notify', }; diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts b/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts index 30f0c1a16c7..6ccb86a8d48 100644 --- a/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts +++ b/workspaces/ballerina/ballerina-core/src/interfaces/data-mapper.ts @@ -57,9 +57,10 @@ export enum IntermediateClauseType { LET = "let", WHERE = "where", FROM = "from", - ORDER_BY = "order by", + ORDER_BY = "order-by", LIMIT = "limit", JOIN = "join", + GROUP_BY = "group-by" } export enum ResultClauseType { @@ -95,6 +96,7 @@ export interface IOType { defaultValue?: unknown; optional?: boolean; isFocused?: boolean; + isSeq?: boolean; isRecursive?: boolean; isDeepNested?: boolean; ref?: string; @@ -141,6 +143,7 @@ export interface DMModel { triggerRefresh?: boolean; traversingRoot?: string; focusInputRootMap?: Record; + groupById?: string; } export interface ModelState { @@ -175,6 +178,7 @@ export interface IOTypeField { optional?: boolean; ref?: string; focusExpression?: string; + isSeq?: boolean; typeInfo?: TypeInfo; } @@ -192,7 +196,7 @@ export interface Query { output: string, inputs: string[]; diagnostics?: DMDiagnostic[]; - fromClause: FromClause; + fromClause: IntermediateClause; intermediateClauses?: IntermediateClause[]; resultClause: ResultClause; } diff --git a/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts b/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts index 5293d4ab909..913b4a08e61 100644 --- a/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts +++ b/workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts @@ -474,8 +474,10 @@ export interface GetDataMapperCodedataResponse { export interface PropertyRequest { filePath: string; codedata: CodeData; - propertyKey: string, targetField: string; +} + +export interface FieldPropertyRequest extends PropertyRequest { fieldId: string; } @@ -483,6 +485,17 @@ export interface PropertyResponse { property: Property; } +export interface ClausePositionRequest { + filePath: string; + codedata: CodeData; + targetField: string; + index: number; +} + +export interface ClausePositionResponse { + position: LinePosition; +} + export interface GraphqlDesignServiceParams { filePath: string; startLine: LinePosition; @@ -832,6 +845,7 @@ export interface BISourceCodeRequest { flowNode: FlowNode | FunctionNode; isConnector?: boolean; isFunctionNodeUpdate?: boolean; + isHelperPaneChange?: boolean; } export type BISourceCodeResponse = { diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/ai-panel/interfaces.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/ai-panel/interfaces.ts index 5e354ab38f1..4abe471c4c3 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/ai-panel/interfaces.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/ai-panel/interfaces.ts @@ -121,7 +121,7 @@ export interface ProjectImports { // Data-mapper related interfaces export interface MetadataWithAttachments { metadata: ExtendedDataMapperMetadata; - attachments?: Attachment[]; + attachments: Attachment[]; } export interface InlineMappingsSourceResult { diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts index 5419755de17..a10b6ab7e66 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/index.ts @@ -149,6 +149,7 @@ export interface BIDiagramAPI { handleReadmeContent: (params: ReadmeContentRequest) => Promise; getVisibleVariableTypes: (params: BIGetVisibleVariableTypesRequest) => Promise; getExpressionCompletions: (params: ExpressionCompletionsRequest) => Promise; + getDataMapperCompletions: (params: ExpressionCompletionsRequest) => Promise; getConfigVariables: () => Promise; updateConfigVariables: (params: UpdateConfigVariableRequest) => Promise; getConfigVariablesV2: (params: ConfigVariableRequest) => Promise; diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts index 2215ab4d577..48991978b42 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/bi-diagram/rpc-type.ts @@ -152,6 +152,7 @@ export const createComponent: RequestType = { method: `${_preFix}/handleReadmeContent` }; export const getVisibleVariableTypes: RequestType = { method: `${_preFix}/getVisibleVariableTypes` }; export const getExpressionCompletions: RequestType = { method: `${_preFix}/getExpressionCompletions` }; +export const getDataMapperCompletions: RequestType = { method: `${_preFix}/getDataMapperCompletions` }; export const getConfigVariables: RequestType = { method: `${_preFix}/getConfigVariables` }; export const updateConfigVariables: RequestType = { method: `${_preFix}/updateConfigVariables` }; export const getConfigVariablesV2: RequestType = { method: `${_preFix}/getConfigVariablesV2` }; diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/common/index.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/common/index.ts index 00a73090246..a98708821c9 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/common/index.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/common/index.ts @@ -32,7 +32,8 @@ import { FileOrDirRequest, WorkspaceRootResponse, ShowErrorMessageRequest, - WorkspaceTypeResponse + WorkspaceTypeResponse, + SampleDownloadRequest } from "./interfaces"; export interface CommonRPCAPI { @@ -51,4 +52,5 @@ export interface CommonRPCAPI { showErrorMessage: (params: ShowErrorMessageRequest) => void; getCurrentProjectTomlValues: () => Promise>; getWorkspaceType: () => Promise; + downloadSelectedSampleFromGithub: (params: SampleDownloadRequest) => Promise; } diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/common/interfaces.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/common/interfaces.ts index 1679814a771..26ffcf79e1d 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/common/interfaces.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/common/interfaces.ts @@ -113,3 +113,7 @@ export interface PackageTomlValues { export interface WorkspaceTypeResponse { type: "SINGLE_PROJECT" | "MULTIPLE_PROJECTS" | "BALLERINA_WORKSPACE" | "VSCODE_WORKSPACE" | "UNKNOWN" } + +export interface SampleDownloadRequest { + zipFileName: string; +} diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/common/rpc-type.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/common/rpc-type.ts index 581db37332b..9b7379b10d7 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/common/rpc-type.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/common/rpc-type.ts @@ -33,7 +33,8 @@ import { FileOrDirRequest, WorkspaceRootResponse, ShowErrorMessageRequest, - WorkspaceTypeResponse + WorkspaceTypeResponse, + SampleDownloadRequest } from "./interfaces"; import { RequestType, NotificationType } from "vscode-messenger-common"; @@ -53,3 +54,4 @@ export const getWorkspaceRoot: RequestType = { meth export const showErrorMessage: NotificationType = { method: `${_preFix}/showErrorMessage` }; export const getCurrentProjectTomlValues: RequestType = { method: `${_preFix}/getCurrentProjectTomlValues` }; export const getWorkspaceType: RequestType = { method: `${_preFix}/getWorkspaceType` }; +export const downloadSelectedSampleFromGithub: RequestType = { method: `${_preFix}/downloadSelectedSampleFromGithub` }; diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts index 8c4a13dd0d8..b117410c013 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/index.ts @@ -42,7 +42,10 @@ import { ProcessTypeReferenceResponse, ProcessTypeReferenceRequest, ExpandedDMModelResponse, - ClearTypeCacheResponse + ClearTypeCacheResponse, + FieldPropertyRequest, + ClausePositionRequest, + ClausePositionResponse } from "../../interfaces/extended-lang-client"; export interface DataMapperAPI { @@ -62,6 +65,8 @@ export interface DataMapperAPI { getDataMapperCodedata: (params: GetDataMapperCodedataRequest) => Promise; getSubMappingCodedata: (params: GetSubMappingCodedataRequest) => Promise; getProperty: (params: PropertyRequest) => Promise; + getFieldProperty: (params: FieldPropertyRequest) => Promise; + getClausePosition: (params: ClausePositionRequest) => Promise; getExpandedDMFromDMModel: (params: DMModelRequest) => Promise; getProcessTypeReference: (params: ProcessTypeReferenceRequest) => Promise; clearTypeCache: () => Promise; diff --git a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts index cb1a0b2eaad..876b413a300 100644 --- a/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts +++ b/workspaces/ballerina/ballerina-core/src/rpc-types/data-mapper/rpc-type.ts @@ -44,7 +44,10 @@ import { ProcessTypeReferenceResponse, ProcessTypeReferenceRequest, ExpandedDMModelResponse, - ClearTypeCacheResponse + ClearTypeCacheResponse, + FieldPropertyRequest, + ClausePositionRequest, + ClausePositionResponse } from "../../interfaces/extended-lang-client"; import { RequestType } from "vscode-messenger-common"; @@ -65,6 +68,8 @@ export const mapWithTransformFn: RequestType = { method: `${_preFix}/getDataMapperCodedata` }; export const getSubMappingCodedata: RequestType = { method: `${_preFix}/getSubMappingCodedata` }; export const getProperty: RequestType = { method: `${_preFix}/getProperty` }; +export const getFieldProperty: RequestType = { method: `${_preFix}/getFieldProperty` }; +export const getClausePosition: RequestType = { method: `${_preFix}/getClausePosition` }; export const getExpandedDMFromDMModel: RequestType = { method: `${_preFix}/getExpandedDMFromDMModel` }; export const getProcessTypeReference: RequestType = { method: `${_preFix}/getProcessTypeReference` }; export const clearTypeCache: RequestType = { method: `${_preFix}/clearTypeCache` }; diff --git a/workspaces/ballerina/ballerina-core/src/state-machine-types.ts b/workspaces/ballerina/ballerina-core/src/state-machine-types.ts index 89912db8444..5bac1d2f6e9 100644 --- a/workspaces/ballerina/ballerina-core/src/state-machine-types.ts +++ b/workspaces/ballerina/ballerina-core/src/state-machine-types.ts @@ -99,7 +99,8 @@ export enum MACHINE_VIEW { AIAgentDesigner = "AI Agent Designer", AIChatAgentWizard = "AI Chat Agent Wizard", ResolveMissingDependencies = "Resolve Missing Dependencies", - ServiceFunctionForm = "Service Function Form" + ServiceFunctionForm = "Service Function Form", + BISamplesView = "BI Samples View" } export interface MachineEvent { diff --git a/workspaces/ballerina/ballerina-extension/CHANGELOG.md b/workspaces/ballerina/ballerina-extension/CHANGELOG.md index d12251ea60c..37c8c539578 100644 --- a/workspaces/ballerina/ballerina-extension/CHANGELOG.md +++ b/workspaces/ballerina/ballerina-extension/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to the **Ballerina** extension will be documented in this fi The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/). +## [5.6.3](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.5.2...ballerina-integrator-1.5.3) - 2025-12-01 + +### Changed + +- **Data Mapper** — Improved completion support for the expression bar and clause editor. Re-enabled array aggregating options. + +### Fixed + +- **Data Mapper** — Fixed expression bar focusing, inline undo button, and crashes during mapping clearance. +- **AI Data Mapper** — Fixed error handling, output formatting, and compilation errors. ## [5.6.2](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.5.1...ballerina-integrator-1.5.2) - 2025-11-18 diff --git a/workspaces/ballerina/ballerina-extension/grammar/ballerina-grammar b/workspaces/ballerina/ballerina-extension/grammar/ballerina-grammar index eb62358724d..10325fc5436 160000 --- a/workspaces/ballerina/ballerina-extension/grammar/ballerina-grammar +++ b/workspaces/ballerina/ballerina-extension/grammar/ballerina-grammar @@ -1 +1 @@ -Subproject commit eb62358724deaad784458ae1d5ec33c4d164e483 +Subproject commit 10325fc5436a87606407ba68bf668bcd59dc180d diff --git a/workspaces/ballerina/ballerina-extension/package.json b/workspaces/ballerina/ballerina-extension/package.json index 14d293ba716..fed69ae6fad 100644 --- a/workspaces/ballerina/ballerina-extension/package.json +++ b/workspaces/ballerina/ballerina-extension/package.json @@ -2,7 +2,7 @@ "name": "ballerina", "displayName": "Ballerina", "description": "Ballerina Language support, debugging, graphical visualization, AI-based data-mapping and many more.", - "version": "5.6.1", + "version": "5.6.3", "publisher": "wso2", "icon": "resources/images/ballerina.png", "homepage": "https://wso2.com/ballerina/vscode/docs", @@ -26,7 +26,6 @@ "activationEvents": [ "onStartupFinished", "onLanguage:ballerina", - "onCommand:ballerina.showExamples", "workspaceContains:**/Ballerina.toml", "onNotebook:ballerina-notebook", "onUri" @@ -348,11 +347,6 @@ } ], "commands": [ - { - "command": "ballerina.showExamples", - "title": "Show Examples", - "category": "Ballerina" - }, { "command": "ballerina.project.build", "title": "Build", @@ -771,7 +765,8 @@ }, { "view": "testing", - "contents": "[Add Unit Test](command:BI.test.add.function)" + "contents": "[Add Unit Test](command:BI.test.add.function)", + "when": "isBIProject || isBallerinaProject" } ], "viewsContainers": { @@ -815,7 +810,7 @@ }, { "command": "BI.test.add.function", - "when": "view == workbench.view.testing", + "when": "(isBIProject || isBallerinaProject) && view == workbench.view.testing", "group": "navigation" }, { @@ -1181,11 +1176,12 @@ "test-coverage": "cross-env COVER_CONFIG=html pnpm run test", "build-tm-grammar": "js-yaml grammar/ballerina-grammar/syntaxes/ballerina.tmLanguage.yaml > grammar/ballerina-grammar/syntaxes/ballerina.tmLanguage.json", "lint": "tslint --fix 'src/**/*{.ts,.tsx}'", - "package": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi", + "package": "node ../../common-libs/scripts/package-vsix.js", "copyFonts": "copyfiles -f ./node_modules/@wso2/font-wso2-vscode/dist/* ./resources/font-wso2-vscode/dist/", "copyVSIX": "copyfiles *.vsix ./vsix", "copyVSIXToRoot": "copyfiles -f ./vsix/*.vsix ../../..", "download-ls": "node scripts/download-ls.js", + "download-ls:prerelease": "node scripts/download-ls.js --prerelease --replace", "build": "pnpm run compile && pnpm run lint && pnpm run postbuild", "rebuild": "pnpm run clean && pnpm run compile && pnpm run postbuild", "postbuild": "if [ \"$isPreRelease\" = \"true\" ]; then pnpm run download-ls --prerelease; else pnpm run download-ls; fi && pnpm run copyFonts && pnpm run copyJSLibs && pnpm run package && pnpm run copyVSIX", @@ -1194,14 +1190,15 @@ "dependencies": { "@ai-sdk/amazon-bedrock": "^3.0.25", "@ai-sdk/anthropic": "^2.0.20", + "@iarna/toml": "^2.2.5", "@types/lodash": "^4.14.200", "@vscode/test-electron": "^2.5.2", "@vscode/vsce": "^3.7.0", "@wso2/ballerina-core": "workspace:*", "@wso2/ballerina-visualizer": "workspace:*", - "@wso2/trace-visualizer": "workspace:*", "@wso2/font-wso2-vscode": "workspace:*", "@wso2/syntax-tree": "workspace:*", + "@wso2/trace-visualizer": "workspace:*", "@wso2/wso2-platform-core": "workspace:*", "ai": "^5.0.56", "cors-anywhere": "^0.4.4", @@ -1216,8 +1213,9 @@ "node-fetch": "^3.3.2", "node-schedule": "^2.1.1", "portfinder": "^1.0.32", + "protobufjs": "^7.2.5", "source-map-support": "^0.5.21", - "toml": "^3.0.0", + "unzipper": "~0.12.3", "uuid": "^11.1.0", "vscode-debugadapter": "^1.51.0", "vscode-debugprotocol": "^1.51.0", @@ -1231,8 +1229,7 @@ "vscode-uri": "^3.0.8", "xml-js": "^1.6.11", "xstate": "^4.38.3", - "zod": "^4.1.8", - "protobufjs": "^7.2.5" + "zod": "^4.1.8" }, "devDependencies": { "@sentry/webpack-plugin": "^1.20.1", @@ -1248,7 +1245,7 @@ "copyfiles": "^2.4.1", "cross-env": "^7.0.3", "decache": "^4.6.2", - "express": "^4.18.2", + "express": "^4.22.1", "istanbul": "^0.4.5", "js-yaml": "^4.1.1", "jwt-decode": "^3.1.2", diff --git a/workspaces/ballerina/ballerina-extension/scripts/download-ls.js b/workspaces/ballerina/ballerina-extension/scripts/download-ls.js index aff1cd55daa..71a6ba0d39f 100644 --- a/workspaces/ballerina/ballerina-extension/scripts/download-ls.js +++ b/workspaces/ballerina/ballerina-extension/scripts/download-ls.js @@ -10,6 +10,7 @@ const GITHUB_REPO_URL = 'https://api.github.com/repos/ballerina-platform/balleri const args = process.argv.slice(2); const usePrerelease = args.includes('--prerelease') || process.env.isPreRelease === 'true'; +const forceReplace = args.includes('--replace'); function checkExistingJar() { try { @@ -177,11 +178,16 @@ async function getLatestRelease(usePrerelease) { async function main() { try { - if (checkExistingJar()) { + if (!forceReplace && checkExistingJar()) { process.exit(0); } - console.log(`Downloading Ballerina language server${usePrerelease ? ' (prerelease)' : ''}...`); + console.log(`Downloading Ballerina language server${usePrerelease ? ' (prerelease)' : ''}${forceReplace ? ' (force replace)' : ''}...`); + + if (forceReplace && fs.existsSync(LS_DIR)) { + console.log('Force replace enabled: clearing existing language server directory...'); + fs.rmSync(LS_DIR, { recursive: true, force: true }); + } if (!fs.existsSync(LS_DIR)) { fs.mkdirSync(LS_DIR, { recursive: true }); diff --git a/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts b/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts index 935ccdded7f..816c4f46e56 100644 --- a/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts +++ b/workspaces/ballerina/ballerina-extension/src/core/extended-language-client.ts @@ -272,7 +272,10 @@ import { ProjectInfoRequest, ProjectInfo, onMigratedProject, - ProjectMigrationResult + ProjectMigrationResult, + FieldPropertyRequest, + ClausePositionResponse, + ClausePositionRequest } from "@wso2/ballerina-core"; import { BallerinaExtension } from "./index"; import { debug, handlePullModuleProgress } from "../utils"; @@ -354,6 +357,7 @@ enum EXTENDED_APIS { BI_GEN_ERROR_HANDLER = 'flowDesignService/addErrorHandler', BI_GET_ENCLOSED_FUNCTION = 'flowDesignService/getEnclosedFunctionDef', BI_EXPRESSION_COMPLETIONS = 'expressionEditor/completion', + BI_DATA_MAPPER_COMPLETIONS = 'expressionEditor/dataMapperCompletion', VISIBLE_VARIABLE_TYPES = 'expressionEditor/visibleVariableTypes', DATA_MAPPER_MAPPINGS = 'dataMapper/mappings', DATA_MAPPER_GET_SOURCE = 'dataMapper/getSource', @@ -369,7 +373,9 @@ enum EXTENDED_APIS { DATA_MAPPER_MAP_WITH_TRANSFORM_FN = 'dataMapper/transformationFunction', DATA_MAPPER_CODEDATA = 'dataMapper/nodePosition', DATA_MAPPER_SUB_MAPPING_CODEDATA = 'dataMapper/subMapping', - DATA_MAPPER_PROPERTY = 'dataMapper/fieldPosition', + DATA_MAPPER_PROPERTY = 'dataMapper/targetFieldPosition', + DATA_MAPPER_FIELD_PROPERTY = 'dataMapper/fieldPosition', + DATA_MAPPER_CLAUSE_POSITION = 'dataMapper/clausePosition', DATA_MAPPER_CLEAR_TYPE_CACHE = 'dataMapper/clearTypeCache', VIEW_CONFIG_VARIABLES = 'configEditor/getConfigVariables', UPDATE_CONFIG_VARIABLES = 'configEditor/updateConfigVariables', @@ -844,6 +850,14 @@ export class ExtendedLangClient extends LanguageClient implements ExtendedLangCl return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_PROPERTY, params); } + async getFieldProperty(params: FieldPropertyRequest): Promise { + return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_FIELD_PROPERTY, params); + } + + async getClausePosition(params: ClausePositionRequest): Promise { + return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_CLAUSE_POSITION, params); + } + async clearTypeCache(): Promise { return this.sendRequest(EXTENDED_APIS.DATA_MAPPER_CLEAR_TYPE_CACHE); } @@ -1145,6 +1159,10 @@ export class ExtendedLangClient extends LanguageClient implements ExtendedLangCl return this.sendRequest(EXTENDED_APIS.BI_EXPRESSION_COMPLETIONS, params); } + async getDataMapperCompletions(params: ExpressionCompletionsRequest): Promise { + return this.sendRequest(EXTENDED_APIS.BI_DATA_MAPPER_COMPLETIONS, params); + } + async getModuleNodes(params: BIModuleNodesRequest): Promise { return this.sendRequest(EXTENDED_APIS.BI_MODULE_NODES, params); } diff --git a/workspaces/ballerina/ballerina-extension/src/extension.ts b/workspaces/ballerina/ballerina-extension/src/extension.ts index 491b256b5e8..e2e72faca83 100644 --- a/workspaces/ballerina/ballerina-extension/src/extension.ts +++ b/workspaces/ballerina/ballerina-extension/src/extension.ts @@ -154,8 +154,9 @@ export async function activateBallerina(): Promise { activateEditorSupport(ballerinaExtInstance); // <------------ MAIN FEATURES -----------> - // Enable Ballerina by examples - activateBBE(ballerinaExtInstance); + // TODO: Enable Ballerina by examples once the samples are available + // https://github.com/wso2/product-ballerina-integrator/issues/1967 + // activateBBE(ballerinaExtInstance); //Enable BI Feature activateBIFeatures(ballerinaExtInstance); diff --git a/workspaces/ballerina/ballerina-extension/src/features/ai/dataMapping.ts b/workspaces/ballerina/ballerina-extension/src/features/ai/dataMapping.ts index e7ff27cd30b..755b2db02b5 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/ai/dataMapping.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/ai/dataMapping.ts @@ -29,10 +29,11 @@ import { DefaultableParam, FunctionDefinition, IncludedRecordParam, ModulePart, import { addMissingRequiredFields, attemptRepairProject, checkProjectDiagnostics } from "../../../src/rpc-managers/ai-panel/repair-utils"; import { NullablePrimitiveType, PrimitiveArrayType, PrimitiveType } from "./constants"; import { INVALID_RECORD_REFERENCE } from "../../../src/views/ai-panel/errorCodes"; -import { PackageInfo, TypesGenerationResult } from "./service/datamapper/types"; +import { CodeRepairResult, PackageInfo, TypesGenerationResult } from "./service/datamapper/types"; import { URI } from "vscode-uri"; import { getAllDataMapperSource } from "./service/datamapper/datamapper"; import { StateMachine } from "../../stateMachine"; +import { CopilotEventHandler } from "./service/event"; // Set to false to include mappings with default values const OMIT_DEFAULT_MAPPINGS_ENABLED = true; @@ -473,13 +474,15 @@ export async function createTempFileAndGenerateMetadata(params: CreateTempFileRe export async function generateMappings( metadataWithAttachments: MetadataWithAttachments, - context: any + context: any, + eventHandler: CopilotEventHandler ): Promise { const targetFilePath = metadataWithAttachments.metadata.codeData.lineRange.fileName || context.documentUri; const generatedMappings = await generateMappingExpressionsFromModel( metadataWithAttachments.metadata.mappingsModel as DMModel, - metadataWithAttachments.attachments || [] + metadataWithAttachments.attachments || [], + eventHandler ); const customFunctionMappings = generatedMappings.filter(mapping => mapping.isFunctionCall); @@ -1060,6 +1063,7 @@ export async function generateInlineMappingsSource( inlineMappingRequest: MetadataWithAttachments, langClient: ExtendedLangClient, context: any, + eventHandler: CopilotEventHandler ): Promise { if (!inlineMappingRequest) { throw new Error("Inline mapping request is required"); @@ -1096,16 +1100,18 @@ export async function generateInlineMappingsSource( // Prepare mapping request payload const mappingRequestPayload: MetadataWithAttachments = { - metadata: tempFileMetadata + metadata: tempFileMetadata, + attachments: [] }; - if (inlineMappingRequest.attachments && inlineMappingRequest.attachments.length > 0) { + if (inlineMappingRequest.attachments.length > 0) { mappingRequestPayload.attachments = inlineMappingRequest.attachments; } // Generate mappings and source code const allMappingsRequest = await generateMappings( mappingRequestPayload, - context + context, + eventHandler ); const generatedSourceResponse = await getAllDataMapperSource(allMappingsRequest); @@ -1315,7 +1321,7 @@ export async function repairCodeAndGetUpdatedContent( params: RepairCodeParams, langClient: ExtendedLangClient, projectRoot: string -): Promise<{ finalContent: string; customFunctionsContent: string }> { +): Promise { // Read main file content let finalContent = fs.readFileSync(params.tempFileMetadata.codeData.lineRange.fileName, 'utf8'); diff --git a/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts b/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts index a0a27074cd9..64a1a6262a0 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts @@ -17,6 +17,7 @@ import { CoreMessage, ModelMessage, generateObject } from "ai"; import { getAnthropicClient, ANTHROPIC_SONNET_4 } from "../connection"; import { + CodeRepairResult, DatamapperResponse, DataModelStructure, MappingFields, @@ -24,12 +25,13 @@ import { } from "./types"; import { GeneratedMappingSchema, RepairedSourceFilesSchema } from "./schema"; import { AIPanelAbortController } from "../../../../../src/rpc-managers/ai-panel/utils"; -import { DataMapperModelResponse, DMModel, Mapping, repairCodeRequest, SourceFile, DiagnosticList, ImportInfo, ProcessMappingParametersRequest, Command, MetadataWithAttachments, InlineMappingsSourceResult, ProcessContextTypeCreationRequest, ProjectImports, ImportStatements, TemplateId, GetModuleDirParams, TextEdit, DataMapperSourceResponse, DataMapperSourceRequest, AllDataMapperSourceRequest } from "@wso2/ballerina-core"; +import { DataMapperModelResponse, DMModel, Mapping, repairCodeRequest, SourceFile, DiagnosticList, ImportInfo, ProcessMappingParametersRequest, Command, MetadataWithAttachments, InlineMappingsSourceResult, ProcessContextTypeCreationRequest, ProjectImports, ImportStatements, TemplateId, GetModuleDirParams, TextEdit, DataMapperSourceResponse, DataMapperSourceRequest, AllDataMapperSourceRequest, DataMapperModelRequest, DeleteMappingRequest } from "@wso2/ballerina-core"; import { getDataMappingPrompt } from "./dataMappingPrompt"; import { getBallerinaCodeRepairPrompt } from "./codeRepairPrompt"; import { CopilotEventHandler, createWebviewEventHandler } from "../event"; import { getErrorMessage } from "../utils"; -import { buildMappingFileArray, buildRecordMap, collectExistingFunctions, collectModuleInfo, createTempBallerinaDir, createTempFileAndGenerateMetadata, getFunctionDefinitionFromSyntaxTree, getUniqueFunctionFilePaths, prepareMappingContext, generateInlineMappingsSource, generateTypesFromContext, repairCodeAndGetUpdatedContent, extractImports, generateDataMapperModel, determineCustomFunctionsPath, generateMappings, getCustomFunctionsContent } from "../../dataMapping"; +import { buildMappingFileArray, buildRecordMap, collectExistingFunctions, collectModuleInfo, createTempBallerinaDir, createTempFileAndGenerateMetadata, getFunctionDefinitionFromSyntaxTree, getUniqueFunctionFilePaths, prepareMappingContext, generateInlineMappingsSource, generateTypesFromContext, repairCodeAndGetUpdatedContent, extractImports, generateDataMapperModel, determineCustomFunctionsPath, generateMappings, getCustomFunctionsContent, repairAndCheckDiagnostics } from "../../dataMapping"; +import { addCheckExpressionErrors } from "../../../../../src/rpc-managers/ai-panel/repair-utils"; import { BiDiagramRpcManager, getBallerinaFiles } from "../../../../../src/rpc-managers/bi-diagram/rpc-manager"; import { updateSourceCode } from "../../../../../src/utils/source-utils"; import { StateMachine } from "../../../../stateMachine"; @@ -38,6 +40,14 @@ import { commands, Uri, window } from "vscode"; import { CLOSE_AI_PANEL_COMMAND, OPEN_AI_PANEL_COMMAND } from "../../constants"; import path from "path"; import { URI } from "vscode-uri"; +import fs from 'fs'; +import { writeBallerinaFileDidOpenTemp } from "../../../../../src/utils/modification"; + +const NO_MAPPINGS_GENERATED_WARNING = `**No Relevant Mappings Generated**\n\n` + + `The AI was unable to identify compatible field mappings between the input and output structures.\n\n` + + `**Suggestions:**\n` + + `- Check if input and output record structures are correct\n` + + `- Try providing mapping hints or examples\n`; // ============================================================================= // ENHANCED MAIN ORCHESTRATOR FUNCTION @@ -250,12 +260,10 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara throw new Error("Function name is required in the mapping parameters"); } - if (!eventHandler) { - throw new Error("Event handler is required for code generation"); - } - // Initialize generation process eventHandler({ type: "start" }); + eventHandler({ type: "content_block", content: "Building the transformation logic using your provided data structures and mapping hints\n\n" }); + eventHandler({ type: "content_block", content: "Reading project files and collecting imports..." }); let assistantResponse: string = ""; const biDiagramRpcManager = new BiDiagramRpcManager(); const langClient = StateMachine.langClient(); @@ -298,7 +306,6 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara const fileContentResults = await Promise.all( uniqueFunctionFilePaths.map(async (filePath) => { const projectFsPath = URI.parse(filePath).fsPath; - const fs = require("fs"); const fileContent = await fs.promises.readFile(projectFsPath, "utf-8"); return { filePath, content: fileContent }; }) @@ -337,7 +344,14 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara const allMappingsRequest = await generateMappings({ metadata: tempFileMetadata, attachments: mappingRequest.attachments - }, context); + }, context, eventHandler); + + // Check if no mappings were generated + if (!allMappingsRequest.mappings || allMappingsRequest.mappings.length === 0) { + eventHandler({ type: "content_block", content: NO_MAPPINGS_GENERATED_WARNING }); + eventHandler({ type: "stop", command: Command.DataMap }); + return; + } const sourceCodeResponse = await getAllDataMapperSource(allMappingsRequest); @@ -366,11 +380,11 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara const isSameFile = customFunctionsTargetPath && path.resolve(mainFilePath) === path.resolve(path.join(tempDirectory, customFunctionsFileName)); - let codeRepairResult: { finalContent: string; customFunctionsContent: string }; + let codeRepairResult: CodeRepairResult; const customContent = await getCustomFunctionsContent(allMappingsRequest.customFunctionsFilePath); + eventHandler({ type: "content_block", content: "\nRepairing generated code..." }); if (isSameFile) { - const fs = require('fs'); const mainContent = fs.readFileSync(mainFilePath, 'utf8'); if (customContent) { @@ -397,12 +411,35 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara }, langClient, projectRoot); } - const generatedFunctionDefinition = await getFunctionDefinitionFromSyntaxTree( + // Handle check expression errors and repair diagnostics + const filePaths = await handleCheckExpressionErrorsAndRepair( + langClient, + projectRoot, + tempFileMetadata, + allMappingsRequest, + tempDirectory, + isSameFile, + codeRepairResult + ); + + // Remove compilation error mappings + const { updatedMainContent, updatedCustomContent } = await removeCompilationErrorMappingFields( + langClient, + projectRoot, + mainFilePath, + targetFunctionName, + allMappingsRequest, + tempDirectory, + filePaths, + isSameFile + ); + + let generatedFunctionDefinition = await getFunctionDefinitionFromSyntaxTree( langClient, tempFileMetadata.codeData.lineRange.fileName, targetFunctionName ); - await new Promise((resolve) => setTimeout(resolve, 200)); + await new Promise((resolve) => setTimeout(resolve, 100)); // For workspace projects, compute relative file path from workspace root const workspacePath = context.workspacePath; @@ -416,13 +453,13 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara const generatedSourceFiles = buildMappingFileArray( targetFilePath, - codeRepairResult.finalContent, + updatedMainContent, customFunctionsTargetPath, - codeRepairResult.customFunctionsContent, + updatedCustomContent, ); // Build assistant response - assistantResponse = `Mappings consist of the following:\n`; + assistantResponse = `The generated data mapping details are as follows:\n`; if (mappingRequest.parameters.inputRecord.length === 1) { assistantResponse += `- **Input Record**: ${mappingContext.mappingDetails.inputParams[0]}\n`; } else { @@ -431,14 +468,26 @@ export async function generateMappingCodeCore(mappingRequest: ProcessMappingPara assistantResponse += `- **Output Record**: ${mappingContext.mappingDetails.outputParam}\n`; assistantResponse += `- **Function Name**: ${targetFunctionName}\n`; + if (mappingRequest.attachments.length > 0) { + const attachmentNames = []; + for (const att of (mappingRequest.attachments)) { + attachmentNames.push(att.name); + } + assistantResponse += `- **Attachments**: ${attachmentNames.join(", ")}\n`; + } + + if (tempFileMetadata.mappingsModel.mappings.length > 0) { + assistantResponse += `\n**Note**: When you click **Add to Integration**, it will override your existing mappings.\n`; + } + if (isSameFile) { const mergedContent = `${generatedFunctionDefinition.source}\n${customContent}`; assistantResponse += `\n\`\`\`ballerina\n${mergedContent}\n\`\`\`\n`; } else { assistantResponse += `\n\`\`\`ballerina\n${generatedFunctionDefinition.source}\n\`\`\`\n`; - if (codeRepairResult.customFunctionsContent) { - assistantResponse += `\n\`\`\`ballerina\n${codeRepairResult.customFunctionsContent}\n\`\`\`\n`; + if (updatedCustomContent) { + assistantResponse += `\n\`\`\`ballerina\n${updatedCustomContent}\n\`\`\`\n`; } } @@ -467,7 +516,6 @@ async function collectAllImportsFromProject(): Promise { const importStatements: ImportStatements[] = []; for (const ballerinaFile of ballerinaSourceFiles) { - const fs = require("fs"); const sourceFileContent = fs.readFileSync(ballerinaFile, "utf8"); const extractedImports = extractImports(sourceFileContent, ballerinaFile); importStatements.push(extractedImports); @@ -498,7 +546,6 @@ function getCurrentActiveFileName(): string { function getModuleDirectory(params: GetModuleDirParams): string { const { filePath, moduleName } = params; const generatedPath = path.join(filePath, "generated", moduleName); - const fs = require("fs"); if (fs.existsSync(generatedPath) && fs.statSync(generatedPath).isDirectory()) { return "generated"; } else { @@ -634,12 +681,10 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada throw new Error("Code data is required in the metadata"); } - if (!eventHandler) { - throw new Error("Event handler is required for code generation"); - } - // Initialize generation process eventHandler({ type: "start" }); + eventHandler({ type: "content_block", content: "Building the transformation logic using your provided data structures and mapping hints\n\n" }); + eventHandler({ type: "content_block", content: "Reading project files and collecting imports..." }); let assistantResponse: string = ""; const projectImports = await collectAllImportsFromProject(); const allImportStatements = projectImports.imports.flatMap(file => file.statements || []); @@ -660,14 +705,22 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada const projectRoot = context.projectPath; const inlineMappingsResult: InlineMappingsSourceResult = - await generateInlineMappingsSource(inlineMappingRequest, langClient, context); + await generateInlineMappingsSource(inlineMappingRequest, langClient, context, eventHandler); + + // Check if no mappings were generated + if (!inlineMappingsResult.allMappingsRequest.mappings || inlineMappingsResult.allMappingsRequest.mappings.length === 0) { + eventHandler({ type: "content_block", content: NO_MAPPINGS_GENERATED_WARNING }); + eventHandler({ type: "stop", command: Command.DataMap }); + return; + } await updateSourceCode({ textEdits: inlineMappingsResult.sourceResponse.textEdits, skipPayloadCheck: true }); await new Promise((resolve) => setTimeout(resolve, 100)); let customFunctionsTargetPath: string | undefined; let customFunctionsFileName: string | undefined; - + let codeToDisplay: string; + if (inlineMappingsResult.allMappingsRequest.customFunctionsFilePath) { const absoluteCustomFunctionsPath = determineCustomFunctionsPath(projectRoot, targetFileName); customFunctionsFileName = path.basename(absoluteCustomFunctionsPath); @@ -687,11 +740,11 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada const isSameFile = customFunctionsTargetPath && path.resolve(mainFilePath) === path.resolve(path.join(inlineMappingsResult.tempDir, customFunctionsFileName)); - let codeRepairResult: { finalContent: string; customFunctionsContent: string }; + let codeRepairResult: CodeRepairResult; const customContent = await getCustomFunctionsContent(inlineMappingsResult.allMappingsRequest.customFunctionsFilePath); + eventHandler({ type: "content_block", content: "\nRepairing generated code..." }); if (isSameFile) { - const fs = require('fs'); const mainContent = fs.readFileSync(mainFilePath, 'utf8'); if (customContent) { @@ -726,19 +779,36 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada targetFilePath = path.relative(workspacePath, context.documentUri); } - const generatedSourceFiles = buildMappingFileArray( - targetFilePath, - codeRepairResult.finalContent, - customFunctionsTargetPath, - codeRepairResult.customFunctionsContent, + const variableName = inlineMappingRequest.metadata.name || inlineMappingsResult.tempFileMetadata.name; + + // Handle check expression errors and repair diagnostics for inline mappings + const { inlineFilePaths, updatedCodeToDisplay } = await handleInlineCheckExpressionErrorsAndRepair( + langClient, + projectRoot, + inlineMappingsResult, + isSameFile, + codeRepairResult, + variableName ); - const variableName = inlineMappingRequest.metadata.name || inlineMappingsResult.tempFileMetadata.name; + if (updatedCodeToDisplay) { + codeToDisplay = updatedCodeToDisplay; + } + + // Remove compilation error mappings for inline mappings + const { updatedMainContent, updatedCustomContent } = await removeInlineCompilationErrorMappingFields( + langClient, + projectRoot, + mainFilePath, + variableName, + inlineMappingsResult, + inlineFilePaths, + isSameFile + ); - let codeToDisplay = codeRepairResult.finalContent; if (variableName) { const extractedVariableDefinition = await extractVariableDefinitionSource( - inlineMappingsResult.tempFileMetadata.codeData.lineRange.fileName, + mainFilePath, inlineMappingsResult.tempFileMetadata.codeData, variableName ); @@ -747,9 +817,26 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada } } + const generatedSourceFiles = buildMappingFileArray( + context.documentUri, + updatedMainContent, + customFunctionsTargetPath, + updatedCustomContent, + ); + // Build assistant response assistantResponse = `Here are the data mappings:\n\n`; - assistantResponse += `\n**Note**: When you click **Add to Integration**, it will override your existing mappings.\n`; + if (inlineMappingRequest.attachments.length > 0) { + const attachmentNames = []; + for (const att of (inlineMappingRequest.attachments)) { + attachmentNames.push(att.name); + } + assistantResponse += `- **Attachments**: ${attachmentNames.join(", ")}\n`; + } + + if (inlineMappingRequest.metadata.mappingsModel.mappings.length > 0) { + assistantResponse += `\n**Note**: When you click **Add to Integration**, it will override your existing mappings.\n`; + } if (isSameFile) { const mergedCodeDisplay = customContent ? `${codeToDisplay}\n${customContent}` : codeToDisplay; @@ -757,8 +844,8 @@ export async function generateInlineMappingCodeCore(inlineMappingRequest: Metada } else { assistantResponse += `\n\`\`\`ballerina\n${codeToDisplay}\n\`\`\`\n`; - if (codeRepairResult.customFunctionsContent) { - assistantResponse += `\n\`\`\`ballerina\n${codeRepairResult.customFunctionsContent}\n\`\`\`\n`; + if (updatedCustomContent) { + assistantResponse += `\n\`\`\`ballerina\n${updatedCustomContent}\n\`\`\`\n`; } } @@ -785,14 +872,10 @@ export async function generateInlineMappingCode(inlineMappingRequest: MetadataWi // Core context type creation function that emits events and generates Ballerina record types export async function generateContextTypesCore(typeCreationRequest: ProcessContextTypeCreationRequest, eventHandler: CopilotEventHandler): Promise { - if (!typeCreationRequest.attachments || typeCreationRequest.attachments.length === 0) { + if (typeCreationRequest.attachments.length === 0) { throw new Error("Attachments are required for type creation"); } - if (!eventHandler) { - throw new Error("Event handler is required for type creation"); - } - // Initialize generation process eventHandler({ type: "start" }); let assistantResponse: string = ""; @@ -800,6 +883,7 @@ export async function generateContextTypesCore(typeCreationRequest: ProcessConte try { const biDiagramRpcManager = new BiDiagramRpcManager(); const langClient = StateMachine.langClient(); + const context = StateMachine.context(); const projectComponents = await biDiagramRpcManager.getProjectComponents(); // Generate types from context with validation @@ -809,10 +893,21 @@ export async function generateContextTypesCore(typeCreationRequest: ProcessConte langClient ); + // For workspace projects, compute relative file path from workspace root + const workspacePath = context.workspacePath; + const projectRoot = context.projectPath; + let targetFilePath = filePath; + + if (workspacePath && projectRoot) { + // Workspace project: need to include package path prefix (e.g., "foo/types.bal") + const absoluteFilePath = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath); + targetFilePath = path.relative(workspacePath, absoluteFilePath); + } + // Build assistant response - const sourceAttachmentNames = typeCreationRequest.attachments?.map(a => a.name).join(", ") || "attachment"; - const fileText = typeCreationRequest.attachments?.length === 1 ? "file" : "files"; - assistantResponse = `Record types generated from the ${sourceAttachmentNames} ${fileText} shown below.\n`; + const sourceAttachmentNames = typeCreationRequest.attachments.map(a => a.name).join(", "); + const fileText = typeCreationRequest.attachments.length === 1 ? "file" : "files"; + assistantResponse = `Types generated from the ${sourceAttachmentNames} ${fileText} shown below.\n`; assistantResponse += `\n\`\`\`ballerina\n${typesCode}\n\`\`\`\n`; // Send assistant response through event handler @@ -836,14 +931,15 @@ export async function generateContextTypes(typeCreationRequest: ProcessContextTy } } +// Opens the AI panel with data mapper chat interface export async function openChatWindowWithCommand(): Promise { const langClient = StateMachine.langClient(); const context = StateMachine.context(); const model = await generateDataMapperModel({}, langClient, context); - // Automatically open AI mapping chat window with the generated model const { identifier, dataMapperMetadata } = context; + // Automatically close and open AI mapping chat window with the generated model commands.executeCommand(CLOSE_AI_PANEL_COMMAND); commands.executeCommand(OPEN_AI_PANEL_COMMAND, { type: 'command-template', @@ -856,3 +952,308 @@ export async function openChatWindowWithCommand(): Promise { } }); } + +// Removes mapping fields with compilation errors for inline mappings and reads updated content +async function removeInlineCompilationErrorMappingFields( + langClient: any, + projectRoot: string, + mainFilePath: string, + variableName: string, + inlineMappingsResult: InlineMappingsSourceResult, + inlineFilePaths: string[], + isSameFile: boolean +): Promise<{ updatedMainContent: string; updatedCustomContent: string }> { + // For inline mappings, we use the variable's location from the codedata + const updatedDataMapperMetadata: DataMapperModelRequest = { + filePath: mainFilePath, + codedata: inlineMappingsResult.allMappingsRequest.codedata, + targetField: variableName, + position: inlineMappingsResult.allMappingsRequest.codedata.lineRange.startLine + }; + + // Get DM model with mappings to check for mapping-level diagnostics + const dataMapperModel = await langClient.getDataMapperMappings(updatedDataMapperMetadata) as DataMapperModelResponse; + const dmModel = dataMapperModel.mappingsModel as DMModel; + + // Check if any mappings have diagnostics + if (dmModel && dmModel.mappings && dmModel.mappings.length > 0) { + const mappingsWithDiagnostics = dmModel.mappings.filter((mapping: Mapping) => + mapping.diagnostics && mapping.diagnostics.length > 0 + ); + + if (mappingsWithDiagnostics.length > 0) { + // Delete each mapping with diagnostics using the deleteMapping API + for (const mapping of mappingsWithDiagnostics) { + const deleteRequest: DeleteMappingRequest = { + filePath: mainFilePath, + codedata: updatedDataMapperMetadata.codedata, + mapping: mapping, + varName: inlineMappingsResult.allMappingsRequest.varName, + targetField: variableName, + }; + + const deleteResponse = await langClient.deleteMapping(deleteRequest); + + // Apply the text edits from the delete operation directly to temp files + if (Object.keys(deleteResponse.textEdits).length > 0) { + await applyTextEditsToTempFile(deleteResponse.textEdits, mainFilePath); + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } + + await repairAndCheckDiagnostics(langClient, projectRoot, { + tempDir: inlineMappingsResult.tempDir, + filePaths: inlineFilePaths + }); + } + } + + // Read updated content after diagnostics handling + const updatedMainContent = fs.readFileSync(mainFilePath, 'utf8'); + let updatedCustomContent = ''; + if (inlineMappingsResult.allMappingsRequest.customFunctionsFilePath && !isSameFile) { + updatedCustomContent = fs.readFileSync(inlineMappingsResult.allMappingsRequest.customFunctionsFilePath, 'utf8'); + } + + return { updatedMainContent, updatedCustomContent }; +} + +// Handles check expression errors (BCE3032) and repairs diagnostics for inline mapping files +async function handleInlineCheckExpressionErrorsAndRepair( + langClient: any, + projectRoot: string, + inlineMappingsResult: InlineMappingsSourceResult, + isSameFile: boolean, + codeRepairResult: CodeRepairResult, + variableName: string +): Promise<{ inlineFilePaths: string[]; updatedCodeToDisplay?: string }> { + // Build file paths array for both main file and custom functions file + const inlineFilePaths = [inlineMappingsResult.tempFileMetadata.codeData.lineRange.fileName]; + if (inlineMappingsResult.allMappingsRequest.customFunctionsFilePath && !isSameFile) { + inlineFilePaths.push(inlineMappingsResult.allMappingsRequest.customFunctionsFilePath); + } + + // Repair and check diagnostics for all files + let diags = await repairAndCheckDiagnostics(langClient, projectRoot, { + tempDir: inlineMappingsResult.tempDir, + filePaths: inlineFilePaths + }); + + // Check for inline mappings with 'check' expressions (BCE3032 error) + const hasCheckError = diags.diagnosticsList.some(diagEntry => + diagEntry.diagnostics.some(d => d.code === "BCE3032") + ); + + let updatedCodeToDisplay: string; + + if (hasCheckError) { + const isModified = await addCheckExpressionErrors(diags.diagnosticsList, langClient); + if (isModified) { + // Re-read the files after modifications + const tempFilePath = inlineMappingsResult.tempFileMetadata.codeData.lineRange.fileName; + codeRepairResult.finalContent = fs.readFileSync(tempFilePath, 'utf8'); + + // Update the code to display if we're working with a variable + if (variableName) { + const extractedVariableDefinition = await extractVariableDefinitionSource( + tempFilePath, + inlineMappingsResult.tempFileMetadata.codeData, + variableName + ); + if (extractedVariableDefinition) { + updatedCodeToDisplay = extractedVariableDefinition; + } + } + + if (inlineMappingsResult.allMappingsRequest.customFunctionsFilePath && !isSameFile) { + codeRepairResult.customFunctionsContent = fs.readFileSync( + inlineMappingsResult.allMappingsRequest.customFunctionsFilePath, + 'utf8' + ); + } + } + } + + return { inlineFilePaths, updatedCodeToDisplay }; +} + +// Handles check expression errors (BCE3032) and repairs diagnostics for mapping files +async function handleCheckExpressionErrorsAndRepair( + langClient: any, + projectRoot: string, + tempFileMetadata: any, + allMappingsRequest: AllDataMapperSourceRequest, + tempDirectory: string, + isSameFile: boolean, + codeRepairResult: CodeRepairResult +): Promise { + // Build file paths array for both main file and custom functions file + const filePaths = [tempFileMetadata.codeData.lineRange.fileName]; + if (allMappingsRequest.customFunctionsFilePath && !isSameFile) { + filePaths.push(allMappingsRequest.customFunctionsFilePath); + } + + // Repair and check diagnostics for all files + let diags = await repairAndCheckDiagnostics(langClient, projectRoot, { + tempDir: tempDirectory, + filePaths + }); + + // Check for mappings with 'check' expressions (BCE3032 error) + const hasCheckError = diags.diagnosticsList.some((diagEntry) => + diagEntry.diagnostics.some(d => d.code === "BCE3032") + ); + + if (hasCheckError) { + const isModified = await addCheckExpressionErrors(diags.diagnosticsList, langClient); + if (isModified) { + // Re-read the files after modifications + const mainFilePath = tempFileMetadata.codeData.lineRange.fileName; + codeRepairResult.finalContent = fs.readFileSync(mainFilePath, 'utf8'); + + if (allMappingsRequest.customFunctionsFilePath && !isSameFile) { + codeRepairResult.customFunctionsContent = fs.readFileSync( + allMappingsRequest.customFunctionsFilePath, + 'utf8' + ); + } + } + } + + return filePaths; +} + +// Removes mapping fields with compilation errors to avoid syntax errors in generated code and reads updated content +async function removeCompilationErrorMappingFields( + langClient: any, + projectRoot: string, + mainFilePath: string, + targetFunctionName: string, + allMappingsRequest: AllDataMapperSourceRequest, + tempDirectory: string, + filePaths: string[], + isSameFile: boolean +): Promise<{ updatedMainContent: string; updatedCustomContent: string }> { + // Get function definition from syntax tree + const funcDefinitionNode = await getFunctionDefinitionFromSyntaxTree( + langClient, + mainFilePath, + targetFunctionName + ); + + const updatedDataMapperMetadata: DataMapperModelRequest = { + filePath: mainFilePath, + codedata: { + lineRange: { + fileName: mainFilePath, + startLine: { + line: funcDefinitionNode.position.startLine, + offset: funcDefinitionNode.position.startColumn, + }, + endLine: { + line: funcDefinitionNode.position.endLine, + offset: funcDefinitionNode.position.endColumn, + }, + }, + }, + targetField: targetFunctionName, + position: { + line: funcDefinitionNode.position.startLine, + offset: funcDefinitionNode.position.startColumn + } + }; + + // Get DM model with mappings to check for mapping-level diagnostics + const dataMapperModel = await langClient.getDataMapperMappings(updatedDataMapperMetadata) as DataMapperModelResponse; + const dmModel = dataMapperModel.mappingsModel as DMModel; + + // Check if any mappings have diagnostics + if (dmModel && dmModel.mappings && dmModel.mappings.length > 0) { + const mappingsWithDiagnostics = dmModel.mappings.filter((mapping: Mapping) => + mapping.diagnostics && mapping.diagnostics.length > 0 + ); + + if (mappingsWithDiagnostics.length > 0) { + // Delete each mapping with diagnostics using the deleteMapping API + for (const mapping of mappingsWithDiagnostics) { + const deleteRequest: DeleteMappingRequest = { + filePath: mainFilePath, + codedata: updatedDataMapperMetadata.codedata, + mapping: mapping, + varName: allMappingsRequest.varName, + targetField: targetFunctionName, + }; + + const deleteResponse = await langClient.deleteMapping(deleteRequest); + + // Apply the text edits from the delete operation directly to temp files + if (Object.keys(deleteResponse.textEdits).length > 0) { + await applyTextEditsToTempFile(deleteResponse.textEdits, mainFilePath); + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } + + await repairAndCheckDiagnostics(langClient, projectRoot, { + tempDir: tempDirectory, + filePaths: filePaths + }); + } + } + + // Read updated content after diagnostics handling + const updatedMainContent = fs.readFileSync(mainFilePath, 'utf8'); + let updatedCustomContent = ''; + if (allMappingsRequest.customFunctionsFilePath && !isSameFile) { + updatedCustomContent = fs.readFileSync(allMappingsRequest.customFunctionsFilePath, 'utf8'); + } + + return { updatedMainContent, updatedCustomContent }; +} + +// Applies text edits to a temporary file without using VS Code workspace APIs +async function applyTextEditsToTempFile(textEdits: { [key: string]: TextEdit[] }, targetFilePath: string): Promise { + // Read current file content + let fileContent = fs.readFileSync(targetFilePath, 'utf8'); + const lines = fileContent.split('\n'); + + // Get edits for this file + const editsForFile = textEdits[targetFilePath] || textEdits[Uri.file(targetFilePath).toString()]; + + if (!editsForFile || editsForFile.length === 0) { + return; + } + + // Sort edits in reverse order (bottom to top) to maintain line positions + const sortedEdits = [...editsForFile].sort((a, b) => { + if (b.range.start.line !== a.range.start.line) { + return b.range.start.line - a.range.start.line; + } + return b.range.start.character - a.range.start.character; + }); + + // Apply each edit + for (const edit of sortedEdits) { + const startLine = edit.range.start.line; + const startChar = edit.range.start.character; + const endLine = edit.range.end.line; + const endChar = edit.range.end.character; + + // Handle single line edit + if (startLine === endLine) { + const line = lines[startLine]; + lines[startLine] = line.substring(0, startChar) + edit.newText + line.substring(endChar); + } else { + // Handle multi-line edit + const firstLine = lines[startLine].substring(0, startChar); + const lastLine = lines[endLine].substring(endChar); + const newContent = firstLine + edit.newText + lastLine; + + // Remove the lines in the range and replace with new content + lines.splice(startLine, endLine - startLine + 1, newContent); + } + } + + // Write updated content back to file + const updatedContent = lines.join('\n'); + writeBallerinaFileDidOpenTemp(targetFilePath, updatedContent); +} diff --git a/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/types.ts b/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/types.ts index 830839612a8..cf477d48e9a 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/types.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/types.ts @@ -53,6 +53,11 @@ export interface RepairedFiles { repairedFiles: SourceFile[]; } +export interface CodeRepairResult { + finalContent: string; + customFunctionsContent: string; +} + // ============================================================================= // MAPPING HINTS // ============================================================================= diff --git a/workspaces/ballerina/ballerina-extension/src/features/bi/activator.ts b/workspaces/ballerina/ballerina-extension/src/features/bi/activator.ts index 9e953006eaa..82f8ea4605c 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/bi/activator.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/bi/activator.ts @@ -35,6 +35,7 @@ import { readFileSync, readdirSync, statSync } from "fs"; import path from "path"; import { isPositionEqual, isPositionWithinDeletedComponent } from "../../utils/history/util"; import { startDebugging } from "../editor-support/activator"; +import { createBIProjectFromMigration, createBIProjectPure } from "../../utils/bi"; import { createVersionNumber, isSupportedSLVersion } from ".././../utils"; import { extension } from "../../BalExtensionContext"; @@ -60,7 +61,7 @@ function handleCommandWithContext( // Scenario 1: Multi-package workspace invoked from command palette if (isBalWorkspace && !item) { const packageList = StateMachine.context().projectInfo?.children.map((child) => child.projectPath); - + if (!packageList || packageList.length === 0) { openView(EVENT_TYPE.OPEN_VIEW, { view, ...additionalViewParams }); return; @@ -70,10 +71,10 @@ function handleCommandWithContext( placeHolder: "Select a package" }).then((selectedPackage) => { if (selectedPackage) { - openView(EVENT_TYPE.OPEN_VIEW, { - view, - projectPath: selectedPackage, - ...additionalViewParams + openView(EVENT_TYPE.OPEN_VIEW, { + view, + projectPath: selectedPackage, + ...additionalViewParams }); } }); @@ -81,12 +82,12 @@ function handleCommandWithContext( // Scenario 2: Invoked from tree view with item context else if (item?.resourceUri) { const projectPath = item.resourceUri.fsPath; - openView(EVENT_TYPE.OPEN_VIEW, { - view, - projectPath, - ...additionalViewParams + openView(EVENT_TYPE.OPEN_VIEW, { + view, + projectPath, + ...additionalViewParams }); - } + } // Scenario 3: Default - no specific context else { openView(EVENT_TYPE.OPEN_VIEW, { view, ...additionalViewParams }); @@ -95,7 +96,7 @@ function handleCommandWithContext( export function activate(context: BallerinaExtension) { const isWorkspaceSupported = isSupportedSLVersion(extension.ballerinaExtInstance, createVersionNumber(2201, 13, 0)); - + // Set context for command visibility commands.executeCommand('setContext', 'ballerina.bi.workspaceSupported', isWorkspaceSupported); @@ -154,7 +155,7 @@ export function activate(context: BallerinaExtension) { window.showErrorMessage('This command requires Ballerina version 2201.13.0 or higher. '); return; } - + const projectPath = StateMachine.context().projectPath || StateMachine.context().workspacePath; if (projectPath) { openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.BIAddProjectForm }); @@ -173,6 +174,14 @@ export function activate(context: BallerinaExtension) { commands.registerCommand(BI_COMMANDS.TOGGLE_TRACE_LOGS, toggleTraceLogs); + commands.registerCommand(BI_COMMANDS.CREATE_BI_PROJECT, (params) => { + return createBIProjectPure(params); + }); + + commands.registerCommand(BI_COMMANDS.CREATE_BI_MIGRATION_PROJECT, (params) => { + return createBIProjectFromMigration(params); + }); + commands.registerCommand(BI_COMMANDS.DELETE_COMPONENT, async (item?: TreeItem & { info?: string }) => { // Guard: DELETE requires a tree item context if (!item) { @@ -198,6 +207,9 @@ export function activate(context: BallerinaExtension) { function openBallerinaTomlFile(context: BallerinaExtension) { const projectPath = StateMachine.context().projectPath || StateMachine.context().workspacePath; + if (!projectPath) { + return; + } const ballerinaTomlFile = path.join(projectPath, "Ballerina.toml"); try { const content = readFileSync(ballerinaTomlFile, "utf8"); diff --git a/workspaces/ballerina/ballerina-extension/src/features/config-generator/utils.ts b/workspaces/ballerina/ballerina-extension/src/features/config-generator/utils.ts index c5dd385cd0c..a91436e6909 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/config-generator/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/config-generator/utils.ts @@ -17,7 +17,7 @@ */ import { debug } from "../../utils/logger"; -import toml from "toml"; +import { parse } from "@iarna/toml"; import { CompletionItem, CompletionItemKind, Position, TextDocument, Uri } from "vscode"; import { BallerinaExtension } from "../../core"; import { findPropertyValues, getConfigValue, getCurrentBallerinaProjectFromContext } from "./configGenerator"; @@ -33,7 +33,7 @@ export const typeOfComment = 'Type of'; */ export function parseTomlToConfig(tomlContent: string): object { try { - return toml.parse(tomlContent); + return parse(tomlContent); } catch (error) { debug("Error while parsing the Config.toml file content: " + error); } diff --git a/workspaces/ballerina/ballerina-extension/src/features/project/cmds/cmd-runner.ts b/workspaces/ballerina/ballerina-extension/src/features/project/cmds/cmd-runner.ts index bb23ba35c5e..26edf3ed08b 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/project/cmds/cmd-runner.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/project/cmds/cmd-runner.ts @@ -50,7 +50,6 @@ export const PALETTE_COMMANDS = { SHOW_DIAGRAM: 'ballerina.show.diagram', SHOW_SOURCE: 'ballerina.show.source', SHOW_ARCHITECTURE_VIEW: 'ballerina.view.architectureView', - SHOW_EXAMPLES: 'ballerina.showExamples', REFRESH_SHOW_ARCHITECTURE_VIEW: "ballerina.view.architectureView.refresh", RUN_CONFIG: 'ballerina.project.run.config', CONFIG_CREATE_COMMAND: 'ballerina.project.config.create', diff --git a/workspaces/ballerina/ballerina-extension/src/features/test-explorer/activator.ts b/workspaces/ballerina/ballerina-extension/src/features/test-explorer/activator.ts index 96d792c193b..ce5727aed37 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/test-explorer/activator.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/test-explorer/activator.ts @@ -17,17 +17,35 @@ * under the License. */ -import { tests, workspace, TestRunProfileKind, TestController } from "vscode"; +import { tests, workspace, TestRunProfileKind, TestController, Uri } from "vscode"; import { BallerinaExtension } from "../../core"; import { runHandler } from "./runner"; import { activateEditBiTest } from "./commands"; import { discoverTestFunctionsInProject, handleFileChange as handleTestFileUpdate, handleFileDelete as handleTestFileDelete } from "./discover"; +import { getCurrentBallerinaProject, getWorkspaceRoot } from "../../utils/project-utils"; +import { checkIsBallerinaPackage, checkIsBallerinaWorkspace } from "../../utils"; +import { PROJECT_TYPE } from "../project"; export let testController: TestController; export async function activate(ballerinaExtInstance: BallerinaExtension) { testController = tests.createTestController('ballerina-integrator-tests', 'WSO2 Integrator: BI Tests'); + const workspaceRoot = getWorkspaceRoot(); + + if (!workspaceRoot) { + return; + } + + const isBallerinaWorkspace = await checkIsBallerinaWorkspace(Uri.file(workspaceRoot)); + const isBallerinaProject = !isBallerinaWorkspace && await checkIsBallerinaPackage(Uri.file(workspaceRoot)); + const currentProject = !isBallerinaWorkspace && !isBallerinaProject && await getCurrentBallerinaProject(); + const isSingleFile = currentProject && currentProject.kind === PROJECT_TYPE.SINGLE_FILE; + + if (!isBallerinaWorkspace && !isBallerinaProject && !isSingleFile) { + return; + } + // Create test profiles to display. testController.createRunProfile('Run Tests', TestRunProfileKind.Run, runHandler, true); testController.createRunProfile('Debug Tests', TestRunProfileKind.Debug, runHandler, true); diff --git a/workspaces/ballerina/ballerina-extension/src/features/tracing/utils.ts b/workspaces/ballerina/ballerina-extension/src/features/tracing/utils.ts index 64915867015..cb97e79655d 100644 --- a/workspaces/ballerina/ballerina-extension/src/features/tracing/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/features/tracing/utils.ts @@ -17,7 +17,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { parse } from 'toml'; +import { parse, stringify } from '@iarna/toml'; import { OTLP_PORT } from './constants'; /** @@ -145,7 +145,7 @@ function updateOrAddSection(content: string, sectionName: string, values: Record // Build the new section content let sectionLines: string[] = [sectionHeader]; for (const [key, value] of Object.entries(values)) { - const formattedValue = typeof value === 'string' ? `"${value}"` : String(value); + const formattedValue = stringify.value(value); sectionLines.push(`${key} = ${formattedValue}`); } const sectionContent = sectionLines.join('\n'); diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/repair-utils.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/repair-utils.ts index ada4a69c2f2..b9d3bfbf54b 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/repair-utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/repair-utils.ts @@ -330,3 +330,98 @@ export async function addMissingRequiredFields( return projectModified; } + +export async function addCheckExpressionErrors( + diagnosticsResult: Diagnostics[], + langClient: ExtendedLangClient +): Promise { + let projectModified = false; + + for (const diag of diagnosticsResult) { + const fileUri = diag.uri; + const diagnostics = diag.diagnostics; + + // Filter BCE3032 diagnostics (check expression errors) + const checkExprDiagnostics = diagnostics.filter(d => d.code === "BCE3032"); + if (!checkExprDiagnostics.length) { + continue; + } + + const astModifications: STModification[] = []; + + // Process each diagnostic individually + for (const diagnostic of checkExprDiagnostics) { + try { + // Get code actions for the diagnostic + const codeActions = await langClient.codeAction({ + textDocument: { uri: fileUri }, + range: { + start: diagnostic.range.start, + end: diagnostic.range.end + }, + context: { + diagnostics: [diagnostic], + only: ['quickfix'], + triggerKind: 1 + } + }); + + if (!codeActions?.length) { + console.warn(`No code actions returned for ${fileUri} at line ${diagnostic.range.start.line}`); + continue; + } + + // Find the action that adds error to return type + // The language server typically provides actions like "Change return type to ..." + const action = codeActions.find( + action => action.title && ( + action.title.toLowerCase().includes("change") && + action.title.toLowerCase().includes("return") && + action.title.toLowerCase().includes("error") + ) + ); + + if (!action?.edit?.documentChanges?.length) { + continue; + } + + const docEdit = action.edit.documentChanges[0] as TextDocumentEdit; + + // Process all edits from the code action + for (const edit of docEdit.edits) { + astModifications.push({ + startLine: edit.range.start.line, + startColumn: edit.range.start.character, + endLine: edit.range.end.line, + endColumn: edit.range.end.character, + type: "INSERT", + isImport: false, + config: { STATEMENT: edit.newText } + }); + } + } catch (err) { + console.warn(`Could not apply code action for ${fileUri} at line ${diagnostic.range.start.line}:`, err); + } + } + + // Apply modifications to syntax tree + if (astModifications.length > 0) { + const syntaxTree = await langClient.stModify({ + documentIdentifier: { uri: fileUri }, + astModifications: astModifications + }); + + // Update file content + const { source } = syntaxTree as SyntaxTree; + if (!source) { + // Handle the case where source is undefined, when compiler issue occurs + return false; + } + const absolutePath = fileURLToPath(fileUri); + writeBallerinaFileDidOpenTemp(absolutePath, source); + projectModified = true; + } + } + + return projectModified; +} diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/rpc-manager.ts index b38822402e2..7a4186e246e 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/rpc-manager.ts @@ -41,6 +41,7 @@ import { LoginMethod, MetadataWithAttachments, OperationType, + PackageTomlValues, PostProcessRequest, PostProcessResponse, ProcessContextTypeCreationRequest, @@ -64,7 +65,7 @@ import * as crypto from 'crypto'; import * as fs from 'fs'; import * as os from 'os'; import path from "path"; -import { parse } from 'toml'; +import { parse } from "@iarna/toml"; import { workspace } from 'vscode'; import { isNumber } from "lodash"; @@ -673,7 +674,23 @@ export class AiPanelRpcManager implements AIPanelAPI { throw new Error("Not a Ballerina project."); } await addToIntegration(projectPath, params.fileChanges); - updateView(); + + const context = StateMachine.context(); + const dataMapperMetadata = context.dataMapperMetadata; + if (!dataMapperMetadata || !dataMapperMetadata.codeData) { + updateView(); + return true; + } + + // Refresh data mapper with the updated code + let filePath = dataMapperMetadata.codeData.lineRange?.fileName; + const varName = dataMapperMetadata.name; + if (!filePath || !varName) { + updateView(); + return true; + } + + await refreshDataMapper(filePath, dataMapperMetadata.codeData, varName); return true; } catch (error) { console.error(">>> Failed to add files to the project", error); @@ -796,8 +813,8 @@ async function getCurrentProjectSource(requestType: OperationType, projectPath?: const tomlContent = await fs.promises.readFile(ballerinaTomlPath, 'utf-8'); // Simple parsing to extract the package.name field try { - const tomlObj = parse(tomlContent); - packageName = tomlObj.package.name; + const tomlObj = parse(tomlContent) as Partial; + packageName = tomlObj?.package?.name; } catch (error) { packageName = ''; } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/utils.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/utils.ts index f2b6341e81e..2d55200a43c 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/ai-panel/utils.ts @@ -28,6 +28,7 @@ import { getAskResponse } from "../../../src/features/ai/service/ask/ask"; import { MappingFileRecord} from "./types"; import { generateAutoMappings, generateRepairCode } from "../../../src/features/ai/service/datamapper/datamapper"; import { ArtifactNotificationHandler, ArtifactsUpdated } from "../../utils/project-artifacts-handler"; +import { CopilotEventHandler } from "../../../src/features/ai/service/event"; // const BACKEND_BASE_URL = BACKEND_URL.replace(/\/v2\.0$/, ""); //TODO: Temp workaround as custom domain seem to block file uploads @@ -154,15 +155,18 @@ async function convertAttachmentToFileData(attachment: Attachment): Promise { let dataMapperResponse: DataMapperModelResponse = { mappingsModel: dataMapperModel as DMModel }; if (mappingInstructionFiles.length > 0) { + eventHandler({ type: "content_block", content: "\nProcessing mapping hints from attachments..." }); const enhancedResponse = await enrichModelWithMappingInstructions(mappingInstructionFiles, dataMapperResponse); dataMapperResponse = enhancedResponse as DataMapperModelResponse; } + eventHandler({ type: "content_block", content: "\nGenerating data mappings..." }); const generatedMappings = await generateAutoMappings(dataMapperResponse); return generatedMappings.map(mapping => ({ diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts index db61df3bb88..eb91491530b 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-handler.ts @@ -75,6 +75,7 @@ import { GetConfigVariableNodeTemplateRequest, getConfigVariables, getConfigVariablesV2, + getDataMapperCompletions, getDesignModel, getDevantMetadata, getEnclosedFunction, @@ -182,6 +183,7 @@ export function registerBiDiagramRpcHandlers(messenger: Messenger) { messenger.onRequest(handleReadmeContent, (args: ReadmeContentRequest) => rpcManger.handleReadmeContent(args)); messenger.onRequest(getVisibleVariableTypes, (args: BIGetVisibleVariableTypesRequest) => rpcManger.getVisibleVariableTypes(args)); messenger.onRequest(getExpressionCompletions, (args: ExpressionCompletionsRequest) => rpcManger.getExpressionCompletions(args)); + messenger.onRequest(getDataMapperCompletions, (args: ExpressionCompletionsRequest) => rpcManger.getDataMapperCompletions(args)); messenger.onRequest(getConfigVariables, () => rpcManger.getConfigVariables()); messenger.onRequest(updateConfigVariables, (args: UpdateConfigVariableRequest) => rpcManger.updateConfigVariables(args)); messenger.onRequest(getConfigVariablesV2, (args: ConfigVariableRequest) => rpcManger.getConfigVariablesV2(args)); diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts index b21914b468d..7d3e31e45a5 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/bi-diagram/rpc-manager.ts @@ -231,7 +231,7 @@ export class BiDiagramRpcManager implements BIDiagramAPI { const artifacts = await updateSourceCode({ textEdits: model.textEdits, description: this.getSourceDescription(params) }); resolve({ artifacts }); } else { - const artifacts = await updateSourceCode({ textEdits: model.textEdits, artifactData: this.getArtifactDataFromNodeKind(params.flowNode.codedata.node), description: this.getSourceDescription(params) }); + const artifacts = await updateSourceCode({ textEdits: model.textEdits, artifactData: this.getArtifactDataFromNodeKind(params.flowNode.codedata.node), description: this.getSourceDescription(params)}, params.isHelperPaneChange); resolve({ artifacts }); } }) @@ -894,6 +894,19 @@ export class BiDiagramRpcManager implements BIDiagramAPI { }); } + async getDataMapperCompletions(params: ExpressionCompletionsRequest): Promise { + return new Promise((resolve, reject) => { + StateMachine.langClient() + .getDataMapperCompletions(params) + .then((completions) => { + resolve(completions); + }) + .catch((error) => { + reject("Error fetching data mapper completions from ls"); + }); + }); + } + async getConfigVariables(): Promise { return new Promise(async (resolve) => { const projectPath = StateMachine.context().projectPath; @@ -2060,6 +2073,7 @@ export class BiDiagramRpcManager implements BIDiagramAPI { }); }); } + } export function getRepoRoot(projectRoot: string): string | undefined { diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-handler.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-handler.ts index c47b09628ba..f618654ce4d 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-handler.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-handler.ts @@ -20,14 +20,10 @@ import { BallerinaDiagnosticsRequest, CommandsRequest, - FileOrDirRequest, - GoToSourceRequest, - OpenExternalUrlRequest, - RunExternalCommandRequest, - ShowErrorMessageRequest, - WorkspaceFileRequest, + downloadSelectedSampleFromGithub, executeCommand, experimentalEnabled, + FileOrDirRequest, getBallerinaDiagnostics, getCurrentProjectTomlValues, getTypeCompletions, @@ -35,12 +31,18 @@ import { getWorkspaceRoot, getWorkspaceType, goToSource, + GoToSourceRequest, isNPSupported, openExternalUrl, + OpenExternalUrlRequest, runBackgroundTerminalCommand, + RunExternalCommandRequest, + SampleDownloadRequest, selectFileOrDirPath, selectFileOrFolderPath, - showErrorMessage + showErrorMessage, + ShowErrorMessageRequest, + WorkspaceFileRequest } from "@wso2/ballerina-core"; import { Messenger } from "vscode-messenger"; import { CommonRpcManager } from "./rpc-manager"; @@ -62,4 +64,5 @@ export function registerCommonRpcHandlers(messenger: Messenger) { messenger.onNotification(showErrorMessage, (args: ShowErrorMessageRequest) => rpcManger.showErrorMessage(args)); messenger.onRequest(getCurrentProjectTomlValues, () => rpcManger.getCurrentProjectTomlValues()); messenger.onRequest(getWorkspaceType, () => rpcManger.getWorkspaceType()); + messenger.onRequest(downloadSelectedSampleFromGithub, (args: SampleDownloadRequest) => rpcManger.downloadSelectedSampleFromGithub(args)); } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-manager.ts index 4c49e256156..d0c0b6b8a0a 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/rpc-manager.ts @@ -31,19 +31,24 @@ import { FileOrDirResponse, GoToSourceRequest, OpenExternalUrlRequest, + PackageTomlValues, RunExternalCommandRequest, RunExternalCommandResponse, + SampleDownloadRequest, ShowErrorMessageRequest, SyntaxTree, - PackageTomlValues, TypeResponse, WorkspaceFileRequest, WorkspaceRootResponse, WorkspacesFileResponse, - WorkspaceTypeResponse, + WorkspaceTypeResponse } from "@wso2/ballerina-core"; import child_process from 'child_process'; -import { Uri, commands, env, window, workspace, MarkdownString } from "vscode"; +import path from "path"; +import os from "os"; +import fs from "fs"; +import * as unzipper from 'unzipper'; +import { commands, env, MarkdownString, ProgressLocation, Uri, window, workspace } from "vscode"; import { URI } from "vscode-uri"; import { extension } from "../../BalExtensionContext"; import { StateMachine } from "../../stateMachine"; @@ -60,9 +65,11 @@ import { askFilePath, askProjectPath, BALLERINA_INTEGRATOR_ISSUES_URL, - getUpdatedSource + getUpdatedSource, + handleDownloadFile, + selectSampleDownloadPath } from "./utils"; -import path from "path"; +import { VisualizerWebview } from "../../views/visualizer/webview"; export class CommonRpcManager implements CommonRPCAPI { async getTypeCompletions(): Promise { @@ -258,8 +265,9 @@ export class CommonRpcManager implements CommonRPCAPI { return extension.ballerinaExtInstance.isNPSupported; } - async getCurrentProjectTomlValues(): Promise { - return getProjectTomlValues(StateMachine.context().projectPath); + async getCurrentProjectTomlValues(): Promise> { + const tomlValues = await getProjectTomlValues(StateMachine.context().projectPath); + return tomlValues ?? {}; } async getWorkspaceType(): Promise { @@ -304,4 +312,149 @@ export class CommonRpcManager implements CommonRPCAPI { return { type: "UNKNOWN" }; } + + + async downloadSelectedSampleFromGithub(params: SampleDownloadRequest): Promise { + const repoUrl = 'https://raw.githubusercontent.com/wso2/integration-samples/refs/heads/main/ballerina-integrator/samples/'; + const rawFileLink = repoUrl + params.zipFileName + '.zip'; + const defaultDownloadsPath = path.join(os.homedir(), 'Downloads'); // Construct the default downloads path + const pathFromDialog = await selectSampleDownloadPath(); + if (pathFromDialog === "") { + return false; + } + const selectedPath = pathFromDialog === "" ? defaultDownloadsPath : pathFromDialog; + const filePath = path.join(selectedPath, params.zipFileName + '.zip'); + let isSuccess = false; + + if (fs.existsSync(filePath)) { + // already downloaded + isSuccess = true; + } else { + await window.withProgress({ + location: ProgressLocation.Notification, + title: 'Downloading file', + cancellable: true + }, async (progress, cancellationToken) => { + + let cancelled: boolean = false; + cancellationToken.onCancellationRequested(async () => { + cancelled = true; + // Clean up partial download + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + }); + + try { + await handleDownloadFile(rawFileLink, filePath, progress); + isSuccess = true; + return; + } catch (error) { + window.showErrorMessage(`Error while downloading the file: ${error}`); + } + }); + } + + if (isSuccess) { + const successMsg = `The Integration sample file has been downloaded successfully to the following directory: ${filePath}.`; + const zipReadStream = fs.createReadStream(filePath); + if (fs.existsSync(path.join(selectedPath, params.zipFileName))) { + // already extracted + let uri = Uri.file(path.join(selectedPath, params.zipFileName)); + commands.executeCommand("vscode.openFolder", uri, true); + return true; + } + + let extractionError: Error | null = null; + const parseStream = unzipper.Parse(); + + // Handle errors on the read stream + zipReadStream.on("error", (error) => { + extractionError = error; + window.showErrorMessage(`Failed to read zip file: ${error.message}`); + }); + + // Handle errors on the parse stream + parseStream.on("error", (error) => { + extractionError = error; + window.showErrorMessage(`Failed to parse zip file. The file may be corrupted: ${error.message}`); + }); + + parseStream.on("entry", function (entry) { + // Skip processing if we've already encountered an error + if (extractionError) { + entry.autodrain(); + return; + } + + var isDir = entry.type === "Directory"; + var fullpath = path.join(selectedPath, entry.path); + var directory = isDir ? fullpath : path.dirname(fullpath); + + try { + if (!fs.existsSync(directory)) { + fs.mkdirSync(directory, { recursive: true }); + } + } catch (error) { + extractionError = error as Error; + window.showErrorMessage(`Failed to create directory "${directory}": ${error instanceof Error ? error.message : String(error)}`); + entry.autodrain(); + return; + } + + if (!isDir) { + const writeStream = fs.createWriteStream(fullpath); + + // Handle write stream errors + writeStream.on("error", (error) => { + extractionError = error; + window.showErrorMessage(`Failed to write file "${fullpath}": ${error.message}. This may be due to insufficient disk space or permission issues.`); + entry.autodrain(); + }); + + // Handle entry stream errors + entry.on("error", (error) => { + extractionError = error; + window.showErrorMessage(`Failed to extract entry "${entry.path}": ${error.message}`); + writeStream.destroy(); + }); + + entry.pipe(writeStream); + } + }); + + parseStream.on("close", () => { + if (extractionError) { + console.error("Extraction failed:", extractionError); + window.showErrorMessage(`Sample extraction failed: ${extractionError.message}`); + return; + } + + console.log("Extraction complete!"); + window.showInformationMessage('Where would you like to open the project?', + { modal: true }, + 'Current Window', + 'New Window' + ).then(selection => { + if (selection === "Current Window") { + // Dispose the current webview + VisualizerWebview.currentPanel?.dispose(); + const folderUri = Uri.file(path.join(selectedPath, params.zipFileName)); + const workspaceFolders = workspace.workspaceFolders || []; + if (!workspaceFolders.some(folder => folder.uri.fsPath === folderUri.fsPath)) { + workspace.updateWorkspaceFolders(workspaceFolders.length, 0, { uri: folderUri }); + } + } else if (selection === "New Window") { + commands.executeCommand('vscode.openFolder', Uri.file(path.join(selectedPath, params.zipFileName))); + } + }); + }); + + zipReadStream.pipe(parseStream); + window.showInformationMessage( + successMsg, + ); + } + return isSuccess; + } } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/utils.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/utils.ts index 872a3843427..5c7f55181ab 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/common/utils.ts @@ -18,11 +18,18 @@ import * as os from 'os'; import { NodePosition } from "@wso2/syntax-tree"; -import { Position, Range, Uri, window, workspace, WorkspaceEdit } from "vscode"; +import { Position, Progress, Range, Uri, window, workspace, WorkspaceEdit } from "vscode"; import { TextEdit } from "@wso2/ballerina-core"; +import axios from 'axios'; +import fs from 'fs'; export const BALLERINA_INTEGRATOR_ISSUES_URL = "https://github.com/wso2/product-ballerina-integrator/issues"; +interface ProgressMessage { + message: string; + increment?: number; +} + export function getUpdatedSource( statement: string, currentFileContent: string, @@ -111,3 +118,75 @@ export async function applyBallerinaTomlEdit(tomlPath: Uri, textEdit: TextEdit) } }); } + +export async function selectSampleDownloadPath(): Promise { + const folderPath = await window.showOpenDialog({ title: 'Sample download directory', canSelectFolders: true, canSelectFiles: false, openLabel: 'Select Folder' }); + if (folderPath && folderPath.length > 0) { + const newlySelectedFolder = folderPath[0].fsPath; + return newlySelectedFolder; + } + return ""; +} + +async function downloadFile(url: string, filePath: string, progressCallback?: (downloadProgress: any) => void) { + const writer = fs.createWriteStream(filePath); + let totalBytes = 0; + try { + const response = await axios.get(url, { + responseType: 'stream', + headers: { + "User-Agent": "Mozilla/5.0" + }, + onDownloadProgress: (progressEvent) => { + totalBytes = progressEvent.total ?? 0; + if (totalBytes === 0) { + // Cannot calculate progress without total size + return; + } + const formatSize = (sizeInBytes: number) => { + const sizeInKB = sizeInBytes / 1024; + if (sizeInKB < 1024) { + return `${Math.floor(sizeInKB)} KB`; + } else { + return `${Math.floor(sizeInKB / 1024)} MB`; + } + }; + const progress = { + percentage: Math.round((progressEvent.loaded * 100) / totalBytes), + downloadedAmount: formatSize(progressEvent.loaded), + downloadSize: formatSize(totalBytes) + }; + if (progressCallback) { + progressCallback(progress); + } + } + }); + response.data.pipe(writer); + await new Promise((resolve, reject) => { + writer.on('finish', () => { + writer.close(); + resolve(); + }); + + writer.on('error', (error) => { + reject(error); + }); + }); + } catch (error) { + window.showErrorMessage(`Error while downloading the file: ${error}`); + throw error; + } +} + +export async function handleDownloadFile(rawFileLink: string, defaultDownloadsPath: string, progress: Progress) { + const handleProgress = (progressPercentage) => { + progress.report({ message: "Downloading file...", increment: progressPercentage }); + }; + try { + await downloadFile(rawFileLink, defaultDownloadsPath, handleProgress); + } catch (error) { + window.showErrorMessage(`Failed to download file: ${error}`); + } + progress.report({ message: "Download finished" }); +} + diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts index ef60effd2ff..d4d063a30e8 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-handler.ts @@ -24,6 +24,7 @@ import { addNewArrayElement, addSubMapping, AddSubMappingRequest, + ClausePositionRequest, clearTypeCache, convertToQuery, ConvertToQueryRequest, @@ -36,11 +37,14 @@ import { deleteSubMapping, DeleteSubMappingRequest, DMModelRequest, + FieldPropertyRequest, + getClausePosition, getDataMapperCodedata, GetDataMapperCodedataRequest, getDataMapperModel, getDataMapperSource, getExpandedDMFromDMModel, + getFieldProperty, getInitialIDMSource, getProcessTypeReference, getProperty, @@ -53,7 +57,7 @@ import { mapWithTransformFn, ProcessTypeReferenceRequest, PropertyRequest, - VisualizableFieldsRequest + VisualizableFieldsRequest, } from "@wso2/ballerina-core"; import { Messenger } from "vscode-messenger"; import { DataMapperRpcManager } from "./rpc-manager"; @@ -76,6 +80,8 @@ export function registerDataMapperRpcHandlers(messenger: Messenger) { messenger.onRequest(getDataMapperCodedata, (args: GetDataMapperCodedataRequest) => rpcManger.getDataMapperCodedata(args)); messenger.onRequest(getSubMappingCodedata, (args: GetSubMappingCodedataRequest) => rpcManger.getSubMappingCodedata(args)); messenger.onRequest(getProperty, (args: PropertyRequest) => rpcManger.getProperty(args)); + messenger.onRequest(getFieldProperty, (args: FieldPropertyRequest) => rpcManger.getFieldProperty(args)); + messenger.onRequest(getClausePosition, (args: ClausePositionRequest) => rpcManger.getClausePosition(args)); messenger.onRequest(getExpandedDMFromDMModel, (args: DMModelRequest) => rpcManger.getExpandedDMFromDMModel(args)); messenger.onRequest(getProcessTypeReference, (args: ProcessTypeReferenceRequest) => rpcManger.getProcessTypeReference(args)); messenger.onRequest(clearTypeCache, () => rpcManger.clearTypeCache()); diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts index a9e94e73ce9..9a30023aeba 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/rpc-manager.ts @@ -21,6 +21,8 @@ import { AddArrayElementRequest, AddClausesRequest, AddSubMappingRequest, + ClausePositionRequest, + ClausePositionResponse, ClearTypeCacheResponse, ConvertToQueryRequest, DataMapperAPI, @@ -34,6 +36,7 @@ import { DMModelRequest, ExpandedDMModel, ExpandedDMModelResponse, + FieldPropertyRequest, GetDataMapperCodedataRequest, GetDataMapperCodedataResponse, GetSubMappingCodedataRequest, @@ -48,7 +51,7 @@ import { VisualizableFieldsResponse } from "@wso2/ballerina-core"; -import { StateMachine } from "../../stateMachine"; +import { StateMachine, undoRedoManager } from "../../stateMachine"; import { expandDMModel, @@ -69,6 +72,7 @@ export class DataMapperRpcManager implements DataMapperAPI { const varName = params.flowNode.properties?.variable?.value as string ?? null; updateSource(model.textEdits, params.filePath, params.flowNode.codedata, varName) .then(codeData => { + undoRedoManager?.reset(); resolve({ textEdits: model.textEdits, codedata: codeData }); }); }) @@ -233,6 +237,26 @@ export class DataMapperRpcManager implements DataMapperAPI { }); } + async getFieldProperty(params: FieldPropertyRequest): Promise { + return new Promise(async (resolve) => { + const property = await StateMachine + .langClient() + .getFieldProperty(params) as PropertyResponse; + + resolve(property); + }); + } + + async getClausePosition(params: ClausePositionRequest): Promise { + return new Promise(async (resolve) => { + const position: any = await StateMachine + .langClient() + .getClausePosition(params); + + resolve(position); + }); + } + async deleteMapping(params: DeleteMappingRequest): Promise { return new Promise(async (resolve) => { await StateMachine @@ -394,4 +418,5 @@ export class DataMapperRpcManager implements DataMapperAPI { }); }); } + } diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts index 36c87a3a3e1..b3357ad2696 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/data-mapper/utils.ts @@ -19,9 +19,6 @@ import { CodeData, ELineRange, Flow, - AllDataMapperSourceRequest, - DataMapperSourceRequest, - DataMapperSourceResponse, NodePosition, ProjectStructureArtifactResponse, TextEdit, @@ -34,7 +31,8 @@ import { IORoot, ExpandModelOptions, ExpandedDMModel, - MACHINE_VIEW + MACHINE_VIEW, + IntermediateClauseType } from "@wso2/ballerina-core"; import { updateSourceCode, UpdateSourceCodeRequest } from "../../utils"; import { StateMachine, updateDataMapperView } from "../../stateMachine"; @@ -598,6 +596,9 @@ function processArray( let fieldId = generateFieldId(parentId, member.name); let isFocused = false; + let isGroupByIdUpdated = false; + const prevGroupById = model.groupById; + if (model.focusInputs) { const focusMember = model.focusInputs[parentId]; if (focusMember) { @@ -605,9 +606,14 @@ function processArray( parentId = member.name; fieldId = member.name; isFocused = true; + model.focusInputRootMap[fieldId] = model.traversingRoot; - if (model.traversingRoot){ - model.focusInputRootMap[parentId] = model.traversingRoot; + if(member.isSeq && model.query!.fromClause.properties.name === fieldId){ + const groupByClause = model.query!.intermediateClauses?.find(clause => clause.type === IntermediateClauseType.GROUP_BY); + if(groupByClause){ + model.groupById = groupByClause.properties.name; + isGroupByIdUpdated = true; + } } } } @@ -625,6 +631,10 @@ function processArray( const typeSpecificProps = processTypeKind(member, parentId, model, visitedRefs); + if(isGroupByIdUpdated){ + model.groupById = prevGroupById; + } + return { ...ioType, ...typeSpecificProps @@ -718,13 +728,31 @@ function processTypeFields( if (!type.fields) { return []; } return type.fields.map(field => { - const fieldId = generateFieldId(parentId, field.name!); + let fieldId = generateFieldId(parentId, field.name!); + + let isFocused = false; + let isSeq = !!model.groupById; + if (model.focusInputs) { + const focusMember = model.focusInputs[fieldId]; + if (focusMember) { + field = focusMember; + fieldId = field.name; + isFocused = true; + model.focusInputRootMap[fieldId] = model.traversingRoot; + if (fieldId === model.groupById){ + isSeq = false; + } + } + } + const ioType: IOType = { id: fieldId, name: field.name, displayName: field.displayName, typeName: field.typeName, kind: field.kind, + ...(isFocused && { isFocused }), + ...(isSeq && { isSeq }), ...(field.optional !== undefined && { optional: field.optional }), ...(field.typeInfo && { typeInfo: field.typeInfo }) }; diff --git a/workspaces/ballerina/ballerina-extension/src/rpc-managers/visualizer/rpc-manager.ts b/workspaces/ballerina/ballerina-extension/src/rpc-managers/visualizer/rpc-manager.ts index aa800f16d1a..9646d28a782 100644 --- a/workspaces/ballerina/ballerina-extension/src/rpc-managers/visualizer/rpc-manager.ts +++ b/workspaces/ballerina/ballerina-extension/src/rpc-managers/visualizer/rpc-manager.ts @@ -122,7 +122,7 @@ export class VisualizerRpcManager implements VisualizerAPI { const currentArtifact = await this.updateCurrentArtifactLocation({ artifacts: payload.data }); clearTimeout(timeoutId); StateMachine.setReadyMode(); - if (!currentArtifact) { + if (!currentArtifact && StateMachine.context().view !== MACHINE_VIEW.InlineDataMapper) { openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.PackageOverview }); resolve("Undo successful"); // resolve the undo string } diff --git a/workspaces/ballerina/ballerina-extension/src/stateMachine.ts b/workspaces/ballerina/ballerina-extension/src/stateMachine.ts index 12bf5841874..15a5831b80b 100644 --- a/workspaces/ballerina/ballerina-extension/src/stateMachine.ts +++ b/workspaces/ballerina/ballerina-extension/src/stateMachine.ts @@ -2,12 +2,39 @@ import { ExtendedLangClient } from './core'; import { createMachine, assign, interpret } from 'xstate'; import { activateBallerina } from './extension'; -import { EVENT_TYPE, SyntaxTree, History, MachineStateValue, IUndoRedoManager, VisualizerLocation, webviewReady, MACHINE_VIEW, DIRECTORY_MAP, SCOPE, ProjectStructureResponse, ProjectStructureArtifactResponse, CodeData, ProjectDiagnosticsResponse, Type, dependencyPullProgress } from "@wso2/ballerina-core"; +import { + EVENT_TYPE, + SyntaxTree, + History, + MachineStateValue, + IUndoRedoManager, + VisualizerLocation, + webviewReady, + MACHINE_VIEW, + DIRECTORY_MAP, + SCOPE, + ProjectStructureResponse, + ProjectStructureArtifactResponse, + CodeData, + ProjectDiagnosticsResponse, + Type, + dependencyPullProgress, + BI_COMMANDS, + NodePosition, + ProjectInfo +} from "@wso2/ballerina-core"; import { fetchAndCacheLibraryData } from './features/library-browser'; import { VisualizerWebview } from './views/visualizer/webview'; import { commands, extensions, Uri, window, workspace, WorkspaceFolder } from 'vscode'; import { notifyCurrentWebview, RPCLayer } from './RPCLayer'; -import { generateUid, getComponentIdentifier, getNodeByIndex, getNodeByName, getNodeByUid, getView } from './utils/state-machine-utils'; +import { + generateUid, + getComponentIdentifier, + getNodeByIndex, + getNodeByName, + getNodeByUid, + getView +} from './utils/state-machine-utils'; import * as path from 'path'; import { extension } from './BalExtensionContext'; import { AIStateMachine } from './views/ai-panel/aiMachine'; @@ -74,21 +101,23 @@ const stateMachine = createMachine( commands.executeCommand("BI.project-explorer.refresh"); console.log('Notifying current webview'); // Check if the current view is Service desginer and if so don't notify the webview - if (StateMachine.context().view !== MACHINE_VIEW.ServiceDesigner) { + if (StateMachine.context().view !== MACHINE_VIEW.ServiceDesigner && StateMachine.context().view !== MACHINE_VIEW.BIDiagram) { notifyCurrentWebview(); } }); } ] }, - UPDATE_PROJECT_ROOT: { + UPDATE_PROJECT_ROOT_AND_INFO: { actions: [ assign({ - projectPath: (context, event) => event.projectPath + projectPath: (context, event) => event.projectPath, + projectInfo: (context, event) => event.projectInfo }), async (context, event) => { - await buildProjectsStructure(context.projectInfo, StateMachine.langClient(), true); + await buildProjectsStructure(event.projectInfo, StateMachine.langClient(), true); notifyCurrentWebview(); + notifyTreeView(event.projectPath, context.documentUri, context.position, context.view); // Resolve the next pending promise waiting for project root update completion pendingProjectRootUpdateResolvers.shift()?.(); } @@ -137,7 +166,13 @@ const stateMachine = createMachine( position: (context, event) => event.viewLocation.position ? event.viewLocation.position : context.position, identifier: (context, event) => event.viewLocation.identifier ? event.viewLocation.identifier : context.identifier, addType: (context, event) => event.viewLocation?.addType !== undefined ? event.viewLocation.addType : context?.addType, - }) + }), + (context, event) => notifyTreeView( + context.projectPath, + event.viewLocation.documentUri || context.documentUri, + event.viewLocation.position || context.position, + context.view + ) ] } }, @@ -149,26 +184,42 @@ const stateMachine = createMachine( { target: "renderInitialView", cond: (context, event) => event.data && event.data.isBI, - actions: assign({ - isBI: (context, event) => event.data.isBI, - projectPath: (context, event) => event.data.projectPath, - workspacePath: (context, event) => event.data.workspacePath, - scope: (context, event) => event.data.scope, - org: (context, event) => event.data.orgName, - package: (context, event) => event.data.packageName - }) + actions: [ + assign({ + isBI: (context, event) => event.data.isBI, + projectPath: (context, event) => event.data.projectPath, + workspacePath: (context, event) => event.data.workspacePath, + scope: (context, event) => event.data.scope, + org: (context, event) => event.data.orgName, + package: (context, event) => event.data.packageName + }), + (context, event) => notifyTreeView( + event.data.projectPath, + context.documentUri, + context.position, + context.view + ) + ] }, { target: "activateLS", cond: (context, event) => event.data && event.data.isBI === false, - actions: assign({ - isBI: (context, event) => event.data.isBI, - projectPath: (context, event) => event.data.projectPath, - workspacePath: (context, event) => event.data.workspacePath, - scope: (context, event) => event.data.scope, - org: (context, event) => event.data.orgName, - package: (context, event) => event.data.packageName - }) + actions: [ + assign({ + isBI: (context, event) => event.data.isBI, + projectPath: (context, event) => event.data.projectPath, + workspacePath: (context, event) => event.data.workspacePath, + scope: (context, event) => event.data.scope, + org: (context, event) => event.data.orgName, + package: (context, event) => event.data.packageName + }), + (context, event) => notifyTreeView( + event.data.projectPath, + context.documentUri, + context.position, + context.view + ) + ] } ], onError: { @@ -248,23 +299,31 @@ const stateMachine = createMachine( on: { OPEN_VIEW: { target: "viewActive", - actions: assign({ - org: (context, event) => event.viewLocation?.org, - package: (context, event) => event.viewLocation?.package, - view: (context, event) => event.viewLocation.view, - documentUri: (context, event) => event.viewLocation.documentUri, - projectPath: (context, event) => event.viewLocation?.projectPath || context?.projectPath, - position: (context, event) => event.viewLocation.position, - identifier: (context, event) => event.viewLocation.identifier, - serviceType: (context, event) => event.viewLocation.serviceType, - type: (context, event) => event.viewLocation?.type, - isGraphql: (context, event) => event.viewLocation?.isGraphql, - metadata: (context, event) => event.viewLocation?.metadata, - addType: (context, event) => event.viewLocation?.addType, - dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata, - artifactInfo: (context, event) => event.viewLocation?.artifactInfo, - rootDiagramId: (context, event) => event.viewLocation?.rootDiagramId - }) + actions: [ + assign({ + org: (context, event) => event.viewLocation?.org, + package: (context, event) => event.viewLocation?.package, + view: (context, event) => event.viewLocation.view, + documentUri: (context, event) => event.viewLocation.documentUri, + position: (context, event) => event.viewLocation.position, + projectPath: (context, event) => event.viewLocation?.projectPath || context?.projectPath, + identifier: (context, event) => event.viewLocation.identifier, + serviceType: (context, event) => event.viewLocation.serviceType, + type: (context, event) => event.viewLocation?.type, + isGraphql: (context, event) => event.viewLocation?.isGraphql, + metadata: (context, event) => event.viewLocation?.metadata, + addType: (context, event) => event.viewLocation?.addType, + dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata, + artifactInfo: (context, event) => event.viewLocation?.artifactInfo, + rootDiagramId: (context, event) => event.viewLocation?.rootDiagramId + }), + (context, event) => notifyTreeView( + context.projectPath, + event.viewLocation?.documentUri, + event.viewLocation?.position, + event.viewLocation?.view + ) + ] } } }, @@ -325,37 +384,53 @@ const stateMachine = createMachine( on: { OPEN_VIEW: { target: "viewInit", - actions: assign({ - view: (context, event) => event.viewLocation.view, - documentUri: (context, event) => event.viewLocation.documentUri, - position: (context, event) => event.viewLocation.position, - identifier: (context, event) => event.viewLocation.identifier, - serviceType: (context, event) => event.viewLocation.serviceType, - projectPath: (context, event) => event.viewLocation?.projectPath || context?.projectPath, - org: (context, event) => event.viewLocation?.org || context?.org, - package: (context, event) => event.viewLocation?.package || context?.package, - type: (context, event) => event.viewLocation?.type, - isGraphql: (context, event) => event.viewLocation?.isGraphql, - metadata: (context, event) => event.viewLocation?.metadata, - addType: (context, event) => event.viewLocation?.addType, - dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata, - artifactInfo: (context, event) => event.viewLocation?.artifactInfo, - rootDiagramId: (context, event) => event.viewLocation?.rootDiagramId - }) + actions: [ + assign({ + view: (context, event) => event.viewLocation.view, + documentUri: (context, event) => event.viewLocation.documentUri, + position: (context, event) => event.viewLocation.position, + identifier: (context, event) => event.viewLocation.identifier, + serviceType: (context, event) => event.viewLocation.serviceType, + projectPath: (context, event) => event.viewLocation?.projectPath || context?.projectPath, + org: (context, event) => event.viewLocation?.org || context?.org, + package: (context, event) => event.viewLocation?.package || context?.package, + type: (context, event) => event.viewLocation?.type, + isGraphql: (context, event) => event.viewLocation?.isGraphql, + metadata: (context, event) => event.viewLocation?.metadata, + addType: (context, event) => event.viewLocation?.addType, + dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata, + artifactInfo: (context, event) => event.viewLocation?.artifactInfo, + rootDiagramId: (context, event) => event.viewLocation?.rootDiagramId + }), + (context, event) => notifyTreeView( + event.viewLocation?.projectPath || context?.projectPath, + event.viewLocation?.documentUri, + event.viewLocation?.position, + event.viewLocation?.view + ) + ] }, VIEW_UPDATE: { target: "webViewLoaded", - actions: assign({ - documentUri: (context, event) => event.viewLocation.documentUri, - position: (context, event) => event.viewLocation.position, - view: (context, event) => event.viewLocation.view, - identifier: (context, event) => event.viewLocation.identifier, - serviceType: (context, event) => event.viewLocation.serviceType, - type: (context, event) => event.viewLocation?.type, - isGraphql: (context, event) => event.viewLocation?.isGraphql, - addType: (context, event) => event.viewLocation?.addType, - dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata - }) + actions: [ + assign({ + documentUri: (context, event) => event.viewLocation.documentUri, + position: (context, event) => event.viewLocation.position, + view: (context, event) => event.viewLocation.view, + identifier: (context, event) => event.viewLocation.identifier, + serviceType: (context, event) => event.viewLocation.serviceType, + type: (context, event) => event.viewLocation?.type, + isGraphql: (context, event) => event.viewLocation?.isGraphql, + addType: (context, event) => event.viewLocation?.addType, + dataMapperMetadata: (context, event) => event.viewLocation?.dataMapperMetadata + }), + (context, event) => notifyTreeView( + context.projectPath, + event.viewLocation?.documentUri, + event.viewLocation?.position, + event.viewLocation?.view + ) + ] }, FILE_EDIT: { target: "viewEditing" @@ -395,8 +470,13 @@ const stateMachine = createMachine( fetchProjectInfo: (context, event) => { return new Promise(async (resolve, reject) => { try { - const projectInfo = await context.langClient.getProjectInfo({ projectPath: context.workspacePath || context.projectPath }); - resolve({ projectInfo }); + const projectPath = context.workspacePath || context.projectPath; + if (!projectPath) { + resolve({ projectInfo: undefined }); + } else { + const projectInfo = await context.langClient.getProjectInfo({ projectPath }); + resolve({ projectInfo }); + } } catch (error) { throw new Error("Error occurred while fetching project info.", error); } @@ -724,10 +804,10 @@ export const StateMachine = { }, sendEvent: (eventType: EVENT_TYPE) => { stateService.send({ type: eventType }); }, updateProjectStructure: (payload: ProjectStructureResponse) => { stateService.send({ type: "UPDATE_PROJECT_STRUCTURE", payload }); }, - updateProjectRoot: (projectPath: string): Promise => { + updateProjectRootAndInfo: (projectPath: string, projectInfo: ProjectInfo): Promise => { return new Promise((resolve) => { pendingProjectRootUpdateResolvers.push(resolve); - stateService.send({ type: "UPDATE_PROJECT_ROOT", projectPath }); + stateService.send({ type: "UPDATE_PROJECT_ROOT_AND_INFO", projectPath, projectInfo }); }); }, refreshProjectInfo: () => { @@ -945,6 +1025,29 @@ async function handleSingleWorkspaceFolder(workspaceURI: Uri): Promise; + const existingPackages: string[] = tomlData?.workspace?.packages ?? []; if (existingPackages.includes(packageName)) { return; // Package already exists @@ -388,8 +388,8 @@ export function deleteProjectFromWorkspace(workspacePath: string, packagePath: s try { const ballerinaTomlContent = fs.readFileSync(ballerinaTomlPath, 'utf8'); - const tomlData: WorkspaceTomlValues = parse(ballerinaTomlContent); - const existingPackages: string[] = tomlData.workspace?.packages || []; + const tomlData = parse(ballerinaTomlContent) as Partial; + const existingPackages: string[] = tomlData?.workspace?.packages ?? []; if (!existingPackages.includes(relativeProjectPath)) { return; // Package not found diff --git a/workspaces/ballerina/ballerina-extension/src/utils/config.ts b/workspaces/ballerina/ballerina-extension/src/utils/config.ts index f3b6c780b59..f9ea67888bc 100644 --- a/workspaces/ballerina/ballerina-extension/src/utils/config.ts +++ b/workspaces/ballerina/ballerina-extension/src/utils/config.ts @@ -21,7 +21,7 @@ import { BallerinaExtension } from '../core'; import { WorkspaceConfiguration, workspace, Uri, RelativePattern } from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; -import { parse } from 'toml'; +import { parse } from '@iarna/toml'; export enum VERSION { BETA = 'beta', @@ -303,12 +303,12 @@ export function getOrgPackageName(projectPath: string): { orgName: string, packa } } -export async function getProjectTomlValues(projectPath: string): Promise { +export async function getProjectTomlValues(projectPath: string): Promise | undefined> { const ballerinaTomlPath = path.join(projectPath, 'Ballerina.toml'); if (fs.existsSync(ballerinaTomlPath)) { const tomlContent = await fs.promises.readFile(ballerinaTomlPath, 'utf-8'); try { - return parse(tomlContent); + return parse(tomlContent) as Partial; } catch (error) { console.error("Failed to load Ballerina.toml content for project at path: ", projectPath, error); return; @@ -316,12 +316,12 @@ export async function getProjectTomlValues(projectPath: string): Promise { +export async function getWorkspaceTomlValues(workspacePath: string): Promise | undefined> { const ballerinaTomlPath = path.join(workspacePath, 'Ballerina.toml'); if (fs.existsSync(ballerinaTomlPath)) { const tomlContent = await fs.promises.readFile(ballerinaTomlPath, 'utf-8'); try { - return parse(tomlContent); + return parse(tomlContent) as Partial; } catch (error) { console.error("Failed to load Ballerina.toml content for workspace at path: ", workspacePath, error); return; diff --git a/workspaces/ballerina/ballerina-extension/src/utils/source-utils.ts b/workspaces/ballerina/ballerina-extension/src/utils/source-utils.ts index ed399c82c75..dc3b1ffbc95 100644 --- a/workspaces/ballerina/ballerina-extension/src/utils/source-utils.ts +++ b/workspaces/ballerina/ballerina-extension/src/utils/source-utils.ts @@ -39,7 +39,7 @@ export interface UpdateSourceCodeRequest { isRenameOperation?: boolean; // This is used to identify if the update is a rename operation. } -export async function updateSourceCode(updateSourceCodeRequest: UpdateSourceCodeRequest): Promise { +export async function updateSourceCode(updateSourceCodeRequest: UpdateSourceCodeRequest, isChangeFromHelperPane?: boolean): Promise { try { let tomlFilesUpdated = false; StateMachine.setEditMode(); @@ -176,7 +176,7 @@ export async function updateSourceCode(updateSourceCodeRequest: UpdateSourceCode clearTimeout(timeoutId); resolve(payload.data); StateMachine.setReadyMode(); - checkAndNotifyWebview(payload.data, updateSourceCodeRequest); + checkAndNotifyWebview(payload.data, updateSourceCodeRequest, isChangeFromHelperPane); unsubscribe(); } }); @@ -214,7 +214,11 @@ export async function updateSourceCode(updateSourceCodeRequest: UpdateSourceCode //** // Notify webview unless a new TYPE artifact is created outside the type diagram view // */ -function checkAndNotifyWebview(response: ProjectStructureArtifactResponse[], request: UpdateSourceCodeRequest) { +function checkAndNotifyWebview( + response: ProjectStructureArtifactResponse[], + request: UpdateSourceCodeRequest, + isChangeFromHelperPane?: boolean +) { const newArtifact = response.find(artifact => artifact.isNew); const selectedArtifact = response.find(artifact => artifact.id === request.identifier); const stateContext = StateMachine.context().view; @@ -226,7 +230,7 @@ function checkAndNotifyWebview(response: ProjectStructureArtifactResponse[], req if ((selectedArtifact?.type === "TYPE " || newArtifact?.type === "TYPE") && stateContext !== MACHINE_VIEW.TypeDiagram) { return; - } else { + } else if (!isChangeFromHelperPane) { notifyCurrentWebview(); } } diff --git a/workspaces/ballerina/ballerina-extension/src/views/ai-panel/activate.ts b/workspaces/ballerina/ballerina-extension/src/views/ai-panel/activate.ts index df064c0e375..4dab56881ab 100644 --- a/workspaces/ballerina/ballerina-extension/src/views/ai-panel/activate.ts +++ b/workspaces/ballerina/ballerina-extension/src/views/ai-panel/activate.ts @@ -54,7 +54,6 @@ export function activateAiPanel(ballerinaExtInstance: BallerinaExtension) { return; } - // StateMachine.updateProjectRoot(selectedPackage); openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.PackageOverview, projectPath: selectedPackage }); } catch (error) { console.error("Error selecting package:", error); diff --git a/workspaces/ballerina/ballerina-extension/src/views/bbe/activator.ts b/workspaces/ballerina/ballerina-extension/src/views/bbe/activator.ts index eda692f24a5..c05206026ea 100644 --- a/workspaces/ballerina/ballerina-extension/src/views/bbe/activator.ts +++ b/workspaces/ballerina/ballerina-extension/src/views/bbe/activator.ts @@ -104,12 +104,6 @@ function showExamples(context: ExtensionContext, langClient: ExtendedLangClient) } export function activate(ballerinaExtInstance: BallerinaExtension) { - const context = ballerinaExtInstance.context; - const langClient = ballerinaExtInstance.langClient; - const examplesListRenderer = commands.registerCommand(PALETTE_COMMANDS.SHOW_EXAMPLES, () => { - sendTelemetryEvent(ballerinaExtInstance, TM_EVENT_OPEN_EXAMPLES, CMP_EXAMPLES_VIEW); - showExamples(context, langClient); - }); - - context.subscriptions.push(examplesListRenderer); + // TODO: Implement this once the samples are available + // https://github.com/wso2/product-ballerina-integrator/issues/1967 } diff --git a/workspaces/ballerina/ballerina-extension/src/views/visualizer/activate.ts b/workspaces/ballerina/ballerina-extension/src/views/visualizer/activate.ts index ef92daa4f04..0a59af5ea2a 100644 --- a/workspaces/ballerina/ballerina-extension/src/views/visualizer/activate.ts +++ b/workspaces/ballerina/ballerina-extension/src/views/visualizer/activate.ts @@ -80,13 +80,27 @@ export function activateSubscriptions() { const projectRoot = await findBallerinaPackageRoot(documentPath); const isBallerinaWorkspace = !!StateMachine.context().workspacePath; - if (isBallerinaWorkspace && pathOrItem instanceof vscode.TreeItem) { + if (isBallerinaWorkspace) { + if (pathOrItem instanceof vscode.TreeItem) { + openView( + EVENT_TYPE.OPEN_VIEW, + { + projectPath: pathOrItem.resourceUri?.fsPath, + view: MACHINE_VIEW.PackageOverview + }, + true + ); + return; + } + const documentUri = documentPath || vscode.window.activeTextEditor?.document.uri.fsPath; openView( EVENT_TYPE.OPEN_VIEW, { - projectPath: pathOrItem.resourceUri?.fsPath, - view: MACHINE_VIEW.PackageOverview + projectPath: projectRoot, + documentUri: documentUri, + position: nodePosition }, + true ); return; } @@ -95,8 +109,8 @@ export function activateSubscriptions() { // Initialize project structure if not already set by finding and loading the Ballerina project root // Can happen when the user opens a directory containing multiple Ballerina projects if (projectRoot) { - // TODO: Need to create the project structure for the workspace - await StateMachine.updateProjectRoot(projectRoot); + const projectInfo = await StateMachine.langClient().getProjectInfo({ projectPath: projectRoot }); + await StateMachine.updateProjectRootAndInfo(projectRoot, projectInfo); } } diff --git a/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/batch-processing.ts b/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/batch-processing.ts index d16eba8e1c7..eab486a6be7 100644 --- a/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/batch-processing.ts +++ b/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/batch-processing.ts @@ -102,18 +102,4 @@ async function setupTestEnvironmentForBatch(projectPath: string): Promise // Give VSCode time to detect the workspace and trigger activation await new Promise(resolve => setTimeout(resolve, TIMING.WORKSPACE_SETTLE_DELAY)); - - // Force extension activation by opening a Ballerina file - try { - const testBalFile = Uri.file(path.join(projectPath, FILES.MAIN_BAL)); - await commands.executeCommand(VSCODE_COMMANDS.OPEN, testBalFile); - await new Promise(resolve => setTimeout(resolve, TIMING.FILE_OPEN_DELAY)); - } catch (error) { - // Fallback: try to execute a ballerina command to force activation - try { - await commands.executeCommand(VSCODE_COMMANDS.SHOW_EXAMPLES); - } catch (cmdError) { - // Extension might still be loading - } - } } diff --git a/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/constants.ts b/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/constants.ts index 002872c0b9a..6225a495d57 100644 --- a/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/constants.ts +++ b/workspaces/ballerina/ballerina-extension/test/ai/evals/code/utils/constants.ts @@ -76,6 +76,5 @@ observabilityIncluded = true export const VSCODE_COMMANDS = { CLOSE_ALL_EDITORS: "workbench.action.closeAllEditors", OPEN: "vscode.open", - SHOW_EXAMPLES: "ballerina.showExamples", AI_GENERATE_CODE_CORE: "ballerina.test.ai.generateCodeCore" } as const; diff --git a/workspaces/ballerina/ballerina-extension/test/ai/integration_tests/libs/setup.ts b/workspaces/ballerina/ballerina-extension/test/ai/integration_tests/libs/setup.ts index 2000537bf9a..5e966615075 100644 --- a/workspaces/ballerina/ballerina-extension/test/ai/integration_tests/libs/setup.ts +++ b/workspaces/ballerina/ballerina-extension/test/ai/integration_tests/libs/setup.ts @@ -35,8 +35,7 @@ const PATHS = { const VSCODE_COMMANDS = { CLOSE_ALL_EDITORS: "workbench.action.closeAllEditors", - OPEN: "vscode.open", - SHOW_EXAMPLES: "ballerina.showExamples", + OPEN: "vscode.open" }; /** @@ -59,21 +58,6 @@ export async function setupTestEnvironment(): Promise { // Wait for workspace to settle and extension to activate await new Promise(resolve => setTimeout(resolve, TIMING.WORKSPACE_SETTLE_DELAY)); - // Force extension activation by opening a Ballerina file - try { - const PROJECT_ROOT = path.resolve(__dirname, PATHS.PROJECT_ROOT_RELATIVE); - const testBalFile = Uri.file(path.join(PROJECT_ROOT, "main.bal")); - await commands.executeCommand(VSCODE_COMMANDS.OPEN, testBalFile); - await new Promise(resolve => setTimeout(resolve, TIMING.FILE_OPEN_DELAY)); - } catch (error) { - // Fallback: try to execute a ballerina command to force activation - try { - await commands.executeCommand(VSCODE_COMMANDS.SHOW_EXAMPLES); - } catch (cmdError) { - // Extension might still be loading - } - } - // Wait for extension to activate (it activates onStartupFinished) // Give it sufficient time to load language server and initialize console.log("Waiting for extension activation and language server initialization..."); diff --git a/workspaces/ballerina/ballerina-low-code-diagram/package.json b/workspaces/ballerina/ballerina-low-code-diagram/package.json index c4ecb72a6e6..89be7a03d29 100644 --- a/workspaces/ballerina/ballerina-low-code-diagram/package.json +++ b/workspaces/ballerina/ballerina-low-code-diagram/package.json @@ -21,9 +21,9 @@ "storybook:setup": "node tools/setup-storybook.js" }, "dependencies": { + "@date-io/date-fns": "^3.2.1", "@wso2/ballerina-core": "workspace:*", "@wso2/syntax-tree": "workspace:*", - "@date-io/date-fns": "^3.2.1", "classnames": "^2.5.1", "clipboard-copy": "^4.0.1", "clsx": "^2.1.1", @@ -38,14 +38,14 @@ "lodash.camelcase": "^4.3.0", "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", + "monaco-editor": "0.52.2", "react": "18.2.0", "react-dom": "18.2.0", "react-intl": "^7.1.11", "react-lottie": "^1.2.10", "react-zoom-pan-pinch": "^3.7.0", "uuid": "^11.1.0", - "vscode-languageserver-protocol": "^3.17.5", - "monaco-editor": "0.52.2" + "vscode-languageserver-protocol": "^3.17.5" }, "devDependencies": { "@babel/core": "^7.27.1", @@ -73,6 +73,7 @@ "copy-webpack-plugin": "^13.0.0", "copyfiles": "^2.4.1", "css-loader": "^7.1.2", + "express": "^4.22.1", "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "glob": "^11.1.0", @@ -101,8 +102,7 @@ "typescript": "5.8.3", "webpack": "^5.99.8", "webpack-cli": "^6.0.1", - "webpack-dev-server": "^5.2.1", - "express": "^5.1.0" + "webpack-dev-server": "^5.2.1" }, "repository": { "type": "git", diff --git a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts index 4caa723cdd3..95e8bc53f4f 100644 --- a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts +++ b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/bi-diagram/rpc-client.ts @@ -149,6 +149,7 @@ import { getConfigVariableNodeTemplate, getConfigVariables, getConfigVariablesV2, + getDataMapperCompletions, getDesignModel, getDevantMetadata, getEnclosedFunction, @@ -309,6 +310,10 @@ export class BiDiagramRpcClient implements BIDiagramAPI { return this._messenger.sendRequest(getExpressionCompletions, HOST_EXTENSION, params); } + getDataMapperCompletions(params: ExpressionCompletionsRequest): Promise { + return this._messenger.sendRequest(getDataMapperCompletions, HOST_EXTENSION, params); + } + getConfigVariables(): Promise { return this._messenger.sendRequest(getConfigVariables, HOST_EXTENSION); } diff --git a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/common/rpc-client.ts b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/common/rpc-client.ts index 21bb01bcc7c..a7731461765 100644 --- a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/common/rpc-client.ts +++ b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/common/rpc-client.ts @@ -27,30 +27,32 @@ import { FileOrDirResponse, GoToSourceRequest, OpenExternalUrlRequest, + PackageTomlValues, RunExternalCommandRequest, RunExternalCommandResponse, + SampleDownloadRequest, ShowErrorMessageRequest, TypeResponse, WorkspaceFileRequest, WorkspaceRootResponse, + WorkspaceTypeResponse, WorkspacesFileResponse, + downloadSelectedSampleFromGithub, executeCommand, experimentalEnabled, getBallerinaDiagnostics, + getCurrentProjectTomlValues, getTypeCompletions, getWorkspaceFiles, getWorkspaceRoot, + getWorkspaceType, goToSource, isNPSupported, openExternalUrl, runBackgroundTerminalCommand, selectFileOrDirPath, - getCurrentProjectTomlValues, - PackageTomlValues, selectFileOrFolderPath, - showErrorMessage, - WorkspaceTypeResponse, - getWorkspaceType + showErrorMessage } from "@wso2/ballerina-core"; import { HOST_EXTENSION } from "vscode-messenger-common"; import { Messenger } from "vscode-messenger-webview"; @@ -114,11 +116,15 @@ export class CommonRpcClient implements CommonRPCAPI { return this._messenger.sendNotification(showErrorMessage, HOST_EXTENSION, params); } - getCurrentProjectTomlValues(): Promise { + getCurrentProjectTomlValues(): Promise> { return this._messenger.sendRequest(getCurrentProjectTomlValues, HOST_EXTENSION); } getWorkspaceType(): Promise { return this._messenger.sendRequest(getWorkspaceType, HOST_EXTENSION); } + + downloadSelectedSampleFromGithub(params: SampleDownloadRequest): Promise { + return this._messenger.sendRequest(downloadSelectedSampleFromGithub, HOST_EXTENSION, params); + } } diff --git a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts index a4c8b9bf67f..7c8219b7f43 100644 --- a/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts +++ b/workspaces/ballerina/ballerina-rpc-client/src/rpc-clients/data-mapper/rpc-client.ts @@ -21,7 +21,8 @@ import { AddArrayElementRequest, AddClausesRequest, AddSubMappingRequest, - AllDataMapperSourceRequest, + ClausePositionRequest, + ClausePositionResponse, ClearTypeCacheResponse, ConvertToQueryRequest, DMModelRequest, @@ -34,6 +35,7 @@ import { DeleteMappingRequest, DeleteSubMappingRequest, ExpandedDMModelResponse, + FieldPropertyRequest, GetDataMapperCodedataRequest, GetDataMapperCodedataResponse, GetSubMappingCodedataRequest, @@ -54,10 +56,12 @@ import { deleteClause, deleteMapping, deleteSubMapping, + getClausePosition, getDataMapperCodedata, getDataMapperModel, getDataMapperSource, getExpandedDMFromDMModel, + getFieldProperty, getInitialIDMSource, getProcessTypeReference, getProperty, @@ -140,6 +144,14 @@ export class DataMapperRpcClient implements DataMapperAPI { return this._messenger.sendRequest(getProperty, HOST_EXTENSION, params); } + getFieldProperty(params: FieldPropertyRequest): Promise { + return this._messenger.sendRequest(getFieldProperty, HOST_EXTENSION, params); + } + + getClausePosition(params: ClausePositionRequest): Promise { + return this._messenger.sendRequest(getClausePosition, HOST_EXTENSION, params); + } + getExpandedDMFromDMModel(params: DMModelRequest): Promise { return this._messenger.sendRequest(getExpandedDMFromDMModel, HOST_EXTENSION, params); } diff --git a/workspaces/ballerina/ballerina-side-panel/package.json b/workspaces/ballerina/ballerina-side-panel/package.json index 1c0db97214a..a0d36fc7c3e 100644 --- a/workspaces/ballerina/ballerina-side-panel/package.json +++ b/workspaces/ballerina/ballerina-side-panel/package.json @@ -34,7 +34,10 @@ "@codemirror/commands": "~6.10.0", "@codemirror/state": "~6.5.2", "@codemirror/view": "~6.38.6", - "@codemirror/autocomplete": "~6.19.1" + "@codemirror/autocomplete": "~6.19.1", + "@codemirror/lang-sql": "~6.10.0", + "@codemirror/language": "~6.11.3", + "@lezer/highlight": "~1.2.3" }, "devDependencies": { "@storybook/react": "^6.5.16", diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/ModeSwitcher/index.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/ModeSwitcher/index.tsx index e9cfe023f82..4cd26249f0d 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/ModeSwitcher/index.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/ModeSwitcher/index.tsx @@ -32,7 +32,7 @@ const ModeSwitcher: React.FC = ({ value, isRecordTypeField, o const isChecked = value === InputMode.EXP; const defaultMode = useMemo( - () => isRecordTypeField ? InputMode.GUIDED : getDefaultExpressionMode(valueTypeConstraint), + () => isRecordTypeField ? InputMode.RECORD : getDefaultExpressionMode(valueTypeConstraint), [valueTypeConstraint, isRecordTypeField] ); diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx index b66c118a6e7..4ea059de9f7 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/EditorFactory.tsx @@ -24,7 +24,7 @@ import { FormField } from "../Form/types"; import { MultiSelectEditor } from "./MultiSelectEditor"; import { TextEditor } from "./TextEditor"; import { TypeEditor } from "./TypeEditor"; -import { ContextAwareExpressionEditor } from "./ExpressionEditor"; +import { ContextAwareExpressionEditor, DataMapperJoinClauseRhsEditor } from "./ExpressionEditor"; import { ParamManagerEditor } from "../ParamManager/ParamManager"; import { DropdownEditor } from "./DropdownEditor"; import { FileSelect } from "./FileSelect"; @@ -218,6 +218,19 @@ export const EditorFactory = (props: FormFieldEditorProps) => { field={field} /> ); + } else if (field.type === "DM_JOIN_CLAUSE_RHS_EXPRESSION") { + // Expression field for Data Mapper join on condition RHS + return ( + recordField.key === field.key)} + /> + ); } else { // Default to text editor // Readonly fields are also treated as text editor diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/controls/TemplateMarkdownToolbar.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/controls/TemplateMarkdownToolbar.tsx index 12cc21662d7..a26e550497e 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/controls/TemplateMarkdownToolbar.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/controls/TemplateMarkdownToolbar.tsx @@ -18,7 +18,7 @@ import React from "react"; import styled from "@emotion/styled"; -import { ThemeColors, Icon, Switch } from "@wso2/ui-toolkit"; +import { ThemeColors, Icon } from "@wso2/ui-toolkit"; import { EditorView } from "@codemirror/view"; import { insertMarkdownFormatting, @@ -178,21 +178,6 @@ export const TemplateMarkdownToolbar = React.forwardRef - - {onTogglePreview && ( - - )} ); }); diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/modes/TemplateMode.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/modes/TemplateMode.tsx index 2213b4f3bbe..42681e0ab15 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/modes/TemplateMode.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpandedEditor/modes/TemplateMode.tsx @@ -26,6 +26,7 @@ import { MarkdownPreview } from "../controls/MarkdownPreview"; import { transformExpressionToMarkdown } from "../utils/transformToMarkdown"; import { useFormContext } from "../../../../context/form"; import { ErrorBanner } from "@wso2/ui-toolkit"; +import { RawTemplateEditorConfig } from "../../MultiModeExpressionEditor/Configurations"; const ExpressionContainer = styled.div` width: 100%; @@ -150,6 +151,7 @@ export const TemplateMode: React.FC = ({ onEditorViewReady={setEditorView} toolbarRef={toolbarRef} enableListContinuation={true} + configuration={new RawTemplateEditorConfig()} /> )} diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionEditor.tsx index bc8dbf0e081..d0eb01de2b2 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionEditor.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionEditor.tsx @@ -32,6 +32,7 @@ import { getPropertyFromFormField, sanitizeType } from './utils'; import { FormField, FormExpressionEditorProps, HelperpaneOnChangeOptions } from '../Form/types'; import { useFormContext } from '../../context'; import { + ExpressionProperty, LineRange, RecordTypeField, SubPanel, @@ -303,6 +304,33 @@ export const ContextAwareExpressionEditor = (props: ContextAwareExpressionEditor ); }; +export const DataMapperJoinClauseRhsEditor = (props: ContextAwareExpressionEditorProps) => { + const { form, expressionEditor, targetLineRange, fileName } = useFormContext(); + + const modifiedExpressionEditor = { + ...expressionEditor + }; + + modifiedExpressionEditor.retrieveCompletions = async (value: string, property: ExpressionProperty, offset: number, triggerCharacter?: string) => { + const varName = form.watch('name'); + const expression = form.watch('expression'); + const prefixExpr = `from var ${varName} in ${expression} select `; + return await expressionEditor.retrieveCompletions(prefixExpr + value, property, prefixExpr.length + offset, triggerCharacter); + } + + return ( + + ); +}; + + export const ExpressionEditor = (props: ExpressionEditorProps) => { const { autoFocus, @@ -341,13 +369,13 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { const key = fieldKey ?? field.key; const [focused, setFocused] = useState(false); - const [inputMode, setInputMode] = useState(recordTypeField ? InputMode.GUIDED : InputMode.EXP); + const [inputMode, setInputMode] = useState(recordTypeField ? InputMode.RECORD : InputMode.EXP); const inputModeRef = useRef(inputMode); const [isExpressionEditorHovered, setIsExpressionEditorHovered] = useState(false); const [showModeSwitchWarning, setShowModeSwitchWarning] = useState(false); - const [targetInputMode, setTargetInputMode] = useState(null); const [formDiagnostics, setFormDiagnostics] = useState(field.diagnostics); const [isExpandedModalOpen, setIsExpandedModalOpen] = useState(false); + const targetInputModeRef = useRef(null); // Update formDiagnostics when field.diagnostics changes useEffect(() => { @@ -408,46 +436,34 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { useEffect(() => { // If recordTypeField is present, always use GUIDED mode if (recordTypeField) { - setInputMode(InputMode.GUIDED); + setInputMode(InputMode.RECORD); return; } let newInputMode = getInputModeFromTypes(field.valueTypeConstraint) - if (isModeSwitcherRestricted()) { + if (!newInputMode) { setInputMode(InputMode.EXP); return; } - if (!newInputMode) { + if (isModeSwitcherRestricted()) { setInputMode(InputMode.EXP); return; } - if (newInputMode === InputMode.TEXT - && typeof initialFieldValue.current === 'string' - && initialFieldValue.current.trim() !== '' - && !(initialFieldValue.current.trim().startsWith("\"") - && initialFieldValue.current.trim().endsWith("\"") - ) - ) { - setInputMode(InputMode.EXP) - } else if (newInputMode === InputMode.TEMPLATE) { - if (sanitizedExpression && rawExpression) { - const sanitized = sanitizedExpression(initialFieldValue.current as string); - if (sanitized !== initialFieldValue.current || !initialFieldValue.current || initialFieldValue.current.trim() === '') { - setInputMode(InputMode.TEMPLATE); - } else { + switch (newInputMode) { + case (InputMode.BOOLEAN): + if (!isExpToBooleanSafe(field?.value as string)) { setInputMode(InputMode.EXP); + return; } - } - } else { - setInputMode(newInputMode); } + setInputMode(newInputMode) }, [field?.valueTypeConstraint, recordTypeField]); const handleFocus = async (controllerOnChange?: (value: string) => void) => { setFocused(true); // If in guided mode with recordTypeField, open ConfigureRecordPage directly - if (inputMode === InputMode.GUIDED && recordTypeField && onOpenRecordConfigPage) { + if (inputMode === InputMode.RECORD && recordTypeField && onOpenRecordConfigPage) { const currentValue = watch(key) || ''; // Create onChange callback that updates the form value const onChangeCallback = (value: string) => { @@ -520,63 +536,37 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { return await extractArgsFromFunction(value, getPropertyFromFormField(field), cursorPosition); }; + const isExpToBooleanSafe = (expValue: string) => { + return ["true", "false"].includes(expValue.trim().toLowerCase()) + } + const handleModeChange = (value: InputMode) => { const raw = watch(key); const currentValue = typeof raw === "string" ? raw.trim() : ""; - - // Warn when switching from EXP to TEXT if value doesn't have quotes - if ( - inputMode === InputMode.EXP - && value === InputMode.TEXT - && (!currentValue.trim().startsWith("\"") || !currentValue.trim().endsWith("\"")) - && currentValue.trim() !== '' - ) { - setTargetInputMode(value); - setShowModeSwitchWarning(true); + if (inputMode !== InputMode.EXP) { + setInputMode(value); return; } - - // Warn when switching from EXP to TEMPLATE if sanitization would hide parts of the expression - if ( - inputMode === InputMode.EXP - && value === InputMode.TEMPLATE - && sanitizedExpression - && currentValue - && currentValue.trim() !== '' - ) { - setTargetInputMode(value); - if (currentValue === sanitizedExpression(currentValue)) { - setShowModeSwitchWarning(true); - } else { - setInputMode(value); - } - return; - } - - // Auto-add quotes when switching from TEXT to EXP if not present - if (inputMode === InputMode.TEXT && value === InputMode.EXP) { - if (currentValue && typeof currentValue === 'string' && - !currentValue.startsWith('"') && !currentValue.endsWith('"')) { - setValue(key, `"${currentValue}"`); - } + const primaryInputMode = getInputModeFromTypes(field.valueTypeConstraint); + switch (primaryInputMode) { + case (InputMode.BOOLEAN): + if (!isExpToBooleanSafe(currentValue)) { + targetInputModeRef.current = value; + setShowModeSwitchWarning(true) + return; + } + break; } - setInputMode(value); }; const handleModeSwitchWarningContinue = () => { - if (targetInputMode !== null) { - setInputMode(targetInputMode); - setTargetInputMode(null); - if (targetInputMode === InputMode.TEMPLATE && inputMode === InputMode.EXP && rawExpression) { - setValue(key, rawExpression("")); - } - } + setInputMode(targetInputModeRef.current); setShowModeSwitchWarning(false); }; const handleModeSwitchWarningCancel = () => { - setTargetInputMode(null); + targetInputModeRef.current = null; setShowModeSwitchWarning(false); }; @@ -669,33 +659,29 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { render={({ field: { name, value, onChange }, fieldState: { error } }) => (
{ - if (updatedValue === value) { - return; - } // clear field diagnostics setFormDiagnostics([]); // Use ref to get current mode (not stale closure value) const currentMode = inputModeRef.current; - const rawValue = currentMode === InputMode.TEMPLATE && rawExpression ? rawExpression(updatedValue) : updatedValue; - onChange(rawValue); + onChange(updatedValue); if (getExpressionEditorDiagnostics && (currentMode === InputMode.EXP || currentMode === InputMode.TEMPLATE)) { getExpressionEditorDiagnostics( - (required ?? !field.optional) || rawValue !== '', - rawValue, + (required ?? !field.optional) || updatedValue !== '', + updatedValue, key, getPropertyFromFormField(field) ); @@ -704,18 +690,18 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { // Check if the current character is a trigger character const triggerCharacter = updatedCursorPosition > 0 - ? triggerCharacters.find((char) => rawValue[updatedCursorPosition - 1] === char) + ? triggerCharacters.find((char) => updatedValue[updatedCursorPosition - 1] === char) : undefined; if (triggerCharacter) { await retrieveCompletions( - rawValue, + updatedValue, getPropertyFromFormField(field), updatedCursorPosition, triggerCharacter ); } else { await retrieveCompletions( - rawValue, + updatedValue, getPropertyFromFormField(field), updatedCursorPosition ); @@ -754,9 +740,6 @@ export const ExpressionEditor = (props: ExpressionEditorProps) => { field={field} value={watch(key)} onChange={async (updatedValue: string, updatedCursorPosition: number) => { - if (updatedValue === value) { - return; - } // clear field diagnostics setFormDiagnostics([]); diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionField.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionField.tsx index cbccd701db9..e4280350d86 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionField.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/ExpressionField.tsx @@ -27,13 +27,20 @@ import { } from '@wso2/ui-toolkit'; import { S } from './ExpressionEditor'; import TextModeEditor from './MultiModeExpressionEditor/TextExpressionEditor/TextModeEditor'; -import { InputMode } from './MultiModeExpressionEditor/ChipExpressionEditor/types'; +import { InputMode, TokenType } from './MultiModeExpressionEditor/ChipExpressionEditor/types'; import { LineRange } from '@wso2/ballerina-core/lib/interfaces/common'; -import { HelperpaneOnChangeOptions } from '../Form/types'; +import { FormField, HelperpaneOnChangeOptions } from '../Form/types'; import { ChipExpressionEditorComponent } from './MultiModeExpressionEditor/ChipExpressionEditor/components/ChipExpressionEditor'; +import RecordConfigPreviewEditor from './MultiModeExpressionEditor/RecordConfigPreviewEditor/RecordConfigPreviewEditor'; +import { RawTemplateEditorConfig, StringTemplateEditorConfig, PrimaryModeChipExpressionEditorConfig } from './MultiModeExpressionEditor/Configurations'; +import NumberExpressionEditor from './MultiModeExpressionEditor/NumberExpressionEditor/NumberEditor'; +import BooleanEditor from './MultiModeExpressionEditor/BooleanEditor/BooleanEditor'; +import { SQLExpressionEditor } from './MultiModeExpressionEditor/SqlExpressionEditor/SqlExpressionEditor'; export interface ExpressionField { + field: FormField; inputMode: InputMode; + primaryMode: InputMode; name: string; value: string; fileName?: string; @@ -96,6 +103,8 @@ const EditorRibbon = ({ onClick }: { onClick: () => void }) => { export const ExpressionField: React.FC = ({ inputMode, + field, + primaryMode, name, value, completions, @@ -127,9 +136,18 @@ export const ExpressionField: React.FC = ({ onOpenExpandedMode, isInExpandedMode }) => { - if (inputMode === InputMode.TEXT || inputMode === InputMode.GUIDED) { + if (inputMode === InputMode.BOOLEAN) { return ( - + ); + } + if (inputMode === InputMode.RECORD) { + return ( + = ({ onOpenExpandedMode={onOpenExpandedMode} isInExpandedMode={isInExpandedMode} /> + ); + } + if (inputMode === InputMode.TEXT) { + return ( + ); } + if (inputMode === InputMode.TEMPLATE) { + return ( + + + ); + } + if (inputMode === InputMode.NUMBER) { + return ( + + + ); + } + if (inputMode === InputMode.SQL) { + return ( + + ); + } return ( = ({ onOpenExpandedMode={onOpenExpandedMode} onRemove={onRemove} isInExpandedMode={isInExpandedMode} + configuration={new PrimaryModeChipExpressionEditorConfig(primaryMode)} /> ); }; diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/BooleanEditor/BooleanEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/BooleanEditor/BooleanEditor.tsx new file mode 100644 index 00000000000..a7ca838881f --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/BooleanEditor/BooleanEditor.tsx @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 React, { ChangeEvent } from "react"; +import { Dropdown } from "@wso2/ui-toolkit"; +import { FormField } from "../../../Form/types"; +import { OptionProps } from "@wso2/ballerina-core"; + +interface BooleanEditorProps { + value: string; + field: FormField; + onChange: (value: string, cursorPosition: number) => void; +} + +const dropdownItems: OptionProps[] = [ + { + id: "default-option", + content: "None Selected", + value: "" + }, + { + id: "1", + content: "True", + value: "true" + }, + { + id: "2", + content: "False", + value: "false" + } +] + +export const BooleanEditor: React.FC = ({ value, onChange, field }) => { + const handleChange = (e: ChangeEvent) => { + onChange(e.target.value, e.target.value.length) + } + + return ( + + ); +}; + +export default BooleanEditor; diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/ChipExpressionDefaultConfig.ts b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/ChipExpressionDefaultConfig.ts new file mode 100644 index 00000000000..327024a32ec --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/ChipExpressionDefaultConfig.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 FXButton from "./components/FxButton"; +import { ParsedToken } from "./utils"; + +export abstract class ChipExpressionEditorDefaultConfiguration { + getHelperValue(value: string, token?: ParsedToken) { + return value; + } + getSerializationPrefix() { + return ""; + } + getSerializationSuffix() { + return ""; + } + serializeValue(value: string) { + return value + } + deserializeValue(value: string) { + return value; + } + showHelperPane() { + return true; + } + getPlugins() { + return []; + } + getAdornment() { + return (FXButton) + } +} diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts index c49580ee302..c836497113f 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/CodeUtils.ts @@ -20,7 +20,7 @@ import { StateEffect, StateField, RangeSet, Transaction, SelectionRange, Annotat import { WidgetType, Decoration, ViewPlugin, EditorView, ViewUpdate } from "@codemirror/view"; import { filterCompletionsByPrefixAndType, getParsedExpressionTokens, detectTokenPatterns, ParsedToken, mapRawToSanitized } from "./utils"; import { defaultKeymap, historyKeymap } from "@codemirror/commands"; -import { CompletionItem } from "@wso2/ui-toolkit"; +import { CompletionItem, FnSignatureDocumentation } from "@wso2/ui-toolkit"; import { ThemeColors } from "@wso2/ui-toolkit"; import { CompletionContext, CompletionResult } from "@codemirror/autocomplete"; import { TokenType, TokenMetadata, CompoundTokenSequence } from "./types"; @@ -32,13 +32,12 @@ import { getTokenTypeColor, getChipDisplayContent } from "./chipStyles"; +import React from "react"; export type TokenStream = number[]; export type TokensChangePayload = { tokens: TokenStream; - rawValue?: string; // Raw expression (e.g., `${var}`) - sanitizedValue?: string; // Sanitized expression (e.g., ${var}) }; export type CursorInfo = { @@ -93,7 +92,9 @@ export function createChip(text: string, type: TokenType, start: number, end: nu Object.assign(span.style, { ...BASE_CHIP_STYLES, background: colors.background, - border: `1px solid ${colors.border}` + border: `1px solid ${colors.border}`, + marginRight: "2px", + marginLeft: "2px", }); // Create icon element for standard chip @@ -223,23 +224,12 @@ export const tokenField = StateField.define({ for (let effect of tr.effects) { if (effect.is(tokensChangeEffect)) { const payload = effect.value; - const sanitizedDoc = tr.newDoc.toString(); - - // Parse tokens using the raw value if provided, otherwise use sanitized - const valueForParsing = payload.rawValue || sanitizedDoc; - tokens = getParsedExpressionTokens(payload.tokens, valueForParsing); - - // If we have both raw and sanitized values, map positions - if (payload.rawValue && payload.sanitizedValue) { - tokens = tokens.map(token => ({ - ...token, - start: mapRawToSanitized(token.start, payload.rawValue!, payload.sanitizedValue!), - end: mapRawToSanitized(token.end, payload.rawValue!, payload.sanitizedValue!) - })); - } + const currentValue = tr.newDoc.toString(); + + tokens = getParsedExpressionTokens(payload.tokens, currentValue); // Detect compounds once when tokens change - compounds = detectTokenPatterns(tokens, sanitizedDoc); + compounds = detectTokenPatterns(tokens, currentValue); return { tokens, compounds }; } @@ -465,10 +455,6 @@ export const buildOnSelectionChange = (onTrigger: (cursor: CursorInfo) => void) if (update.docChanged) return; if (!update.view.hasFocus) return; - if (update.transactions.some(tr => tr.annotation(ProgrammerticSelectionChange))) { - return; - } - const cursorPosition = update.state.selection.main; const coords = update.view.coordsAtPos(cursorPosition.to); @@ -571,22 +557,24 @@ export const buildOnChangeListner = (onTrigeer: (newValue: string, cursor: Curso return onChangeListner; } -export const buildCompletionSource = (getCompletions: () => CompletionItem[]) => { - return (context: CompletionContext): CompletionResult | null => { +export const buildCompletionSource = (getCompletions: () => Promise) => { + return async (context: CompletionContext): Promise => { + const textBeforeCursor = context.state.doc.toString().slice(0, context.pos); + const lastNonSpaceChar = textBeforeCursor.trimEnd().slice(-1); + const word = context.matchBefore(/\w*/); - if (!word || (word.from === word.to && !context.explicit)) { + if (lastNonSpaceChar !== '.' && ( + !word || (word.from === word.to && !context.explicit) + )) { return null; } - const textBeforeCursor = context.state.doc.toString().slice(0, context.pos); - const lastNonSpaceChar = textBeforeCursor.trimEnd().slice(-1); - // Don't show completions for trigger characters - if (lastNonSpaceChar === '+' || lastNonSpaceChar === ':') { + if (lastNonSpaceChar === '+') { return null; } - const completions = getCompletions(); + const completions = await getCompletions(); const prefix = word.text; const filteredCompletions = filterCompletionsByPrefixAndType(completions, prefix); @@ -618,3 +606,274 @@ export const buildHelperPaneKeymap = (getIsHelperPaneOpen: () => boolean, onClos } ]; }; + + +export const extractTextContent = (content: any): string => { + if (typeof content === 'string') { + return content; + } + if (React.isValidElement(content)) { + const props = (content as any).props; + if (props) { + if (typeof props.children === 'string') { + return props.children; + } + if (Array.isArray(props.children)) { + return props.children + .map((child: any) => extractTextContent(child)) + .filter(Boolean) + .join(' '); + } + if (props.children && typeof props.children === 'object') { + return extractTextContent(props.children); + } + } + } + if (Array.isArray(content)) { + return content + .map((item: any) => extractTextContent(item)) + .filter(Boolean) + .join(' '); + } + return ''; +}; + +export const parseMarkdownToDOM = (text: string, container: HTMLElement, codeBackground: string) => { + const parseInline = (str: string, parent: HTMLElement) => { + let remaining = str; + + while (remaining.length > 0) { + const boldMatch = remaining.match(/^\*\*(.+?)\*\*/); + const codeMatch = remaining.match(/^`([^`]+?)`/); + + if (boldMatch) { + const bold = document.createElement('strong'); + bold.style.fontWeight = '600'; + parseInline(boldMatch[1], bold); + parent.appendChild(bold); + remaining = remaining.slice(boldMatch[0].length); + } else if (codeMatch) { + const code = document.createElement('code'); + code.textContent = codeMatch[1]; + code.style.cssText = ` + background: ${codeBackground}; + color: ${ThemeColors.PRIMARY}; + padding: 2px 6px; + border-radius: 3px; + font-family: var(--vscode-editor-font-family); + font-size: 11px; + border: 1px solid ${ThemeColors.OUTLINE}; + `; + parent.appendChild(code); + remaining = remaining.slice(codeMatch[0].length); + } else { + parent.appendChild(document.createTextNode(remaining[0])); + remaining = remaining.slice(1); + } + } + }; + + const lines = text.split('\n'); + lines.forEach((line, index) => { + if (index > 0) { + container.appendChild(document.createElement('br')); + } + parseInline(line, container); + }); +}; + +export const createTooltipHeader = (label: string): HTMLDivElement => { + const header = document.createElement("div"); + header.style.cssText = ` + padding: 8px 12px; + background: ${ThemeColors.SURFACE_CONTAINER}; + border-bottom: 1px solid ${ThemeColors.OUTLINE}; + font-weight: 500; + color: ${ThemeColors.PRIMARY}; + font-family: var(--vscode-editor-font-family); + `; + header.textContent = label; + return header; +}; + +export const createSectionLabel = (text: string): HTMLDivElement => { + const label = document.createElement("div"); + label.style.cssText = ` + color: ${ThemeColors.ON_SURFACE_VARIANT}; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 6px; + `; + label.textContent = text; + return label; +}; + +export const createParametersSection = (args: string[], currentArgIndex: number): HTMLDivElement => { + const section = document.createElement("div"); + section.style.cssText = ` + padding: 8px 12px; + background: ${ThemeColors.SURFACE}; + border-bottom: 1px solid ${ThemeColors.OUTLINE}; + `; + + section.appendChild(createSectionLabel("Parameters")); + + args.forEach((arg, index) => { + const isCurrent = index === currentArgIndex; + const argDiv = document.createElement("div"); + argDiv.style.cssText = ` + padding: 4px 8px; + margin: 2px 0; + border-radius: 3px; + font-family: var(--vscode-editor-font-family); + color: ${isCurrent ? ThemeColors.ON_SURFACE : ThemeColors.ON_SURFACE_VARIANT}; + background: ${isCurrent ? ThemeColors.SURFACE_CONTAINER : 'transparent'}; + font-weight: ${isCurrent ? '600' : '400'}; + border-left: ${isCurrent ? `3px solid ${ThemeColors.PRIMARY}` : '3px solid transparent'}; + `; + argDiv.textContent = arg; + section.appendChild(argDiv); + }); + + return section; +}; + +export const createDocumentationSection = (documentation: FnSignatureDocumentation): HTMLDivElement => { + const section = document.createElement("div"); + section.style.cssText = ` + padding: 8px 12px; + background: ${ThemeColors.SURFACE}; + `; + + section.appendChild(createSectionLabel("Documentation")); + + const docContent = document.createElement("div"); + docContent.style.cssText = ` + color: ${ThemeColors.ON_SURFACE}; + line-height: 1.5; + font-size: 12px; + `; + + if (documentation.fn) { + const fnDoc = document.createElement("div"); + fnDoc.style.cssText = `margin-bottom: 8px;`; + const text = extractTextContent(documentation.fn); + if (text) { + parseMarkdownToDOM(text, fnDoc, ThemeColors.SURFACE_CONTAINER); + } else { + fnDoc.textContent = 'Function documentation available'; + } + docContent.appendChild(fnDoc); + } + + if (documentation.args) { + const argsDoc = document.createElement("div"); + argsDoc.style.cssText = ` + padding: 8px; + background: ${ThemeColors.SURFACE_CONTAINER}; + border-radius: 3px; + border-left: 3px solid ${ThemeColors.OUTLINE_VARIANT}; + `; + + argsDoc.appendChild(createSectionLabel("Arguments")); + + const argsDocText = document.createElement("div"); + argsDocText.style.cssText = ` + color: ${ThemeColors.ON_SURFACE}; + font-size: 12px; + `; + + const text = extractTextContent(documentation.args); + if (text) { + parseMarkdownToDOM(text, argsDocText, ThemeColors.SURFACE); + } else { + argsDocText.textContent = 'Arguments documentation available'; + } + + argsDoc.appendChild(argsDocText); + docContent.appendChild(argsDoc); + } + + section.appendChild(docContent); + return section; +}; + +export const createTooltipContainer = (): HTMLElement => { + const dom = document.createElement("div"); + dom.style.cssText = ` + background: ${ThemeColors.SURFACE_BRIGHT}; + border: 1px solid ${ThemeColors.OUTLINE}; + border-radius: 4px; + padding: 0; + max-width: 500px; + max-height: 200px; + font-family: var(--vscode-font-family); + font-size: 13px; + box-shadow: 0 2px 8px ${ThemeColors.SURFACE_CONTAINER}; + overflow-y: auto; + overflow-x: hidden; + `; + return dom; +}; + +export const createTooltipPositioningHandlers = (view: EditorView) => { + let adjustmentObserver: MutationObserver | null = null; + + const adjustPosition = () => { + const tooltipElements = view.dom.querySelectorAll('.cm-tooltip'); + if (tooltipElements.length === 0) return; + + const tooltip = tooltipElements[tooltipElements.length - 1] as HTMLElement; + const editorRect = view.dom.getBoundingClientRect(); + const tooltipRect = tooltip.getBoundingClientRect(); + + const rightOverflow = (tooltipRect.left + tooltipRect.width) - (editorRect.left + editorRect.width); + + if (rightOverflow > 0) { + const currentLeft = parseFloat(tooltip.style.left) || 0; + const newLeft = currentLeft - rightOverflow - 10; + tooltip.style.left = `${Math.max(0, newLeft)}px`; + } + }; + + const mount = () => { + requestAnimationFrame(() => { + adjustPosition(); + + const tooltipElements = view.dom.querySelectorAll('.cm-tooltip'); + if (tooltipElements.length > 0) { + const tooltip = tooltipElements[tooltipElements.length - 1] as HTMLElement; + adjustmentObserver = new MutationObserver(adjustPosition); + adjustmentObserver.observe(tooltip, { + attributes: true, + attributeFilter: ['style'] + }); + } + }); + }; + + const destroy = () => { + if (adjustmentObserver) { + adjustmentObserver.disconnect(); + } + }; + + return { mount, destroy }; +}; + +export const isSelectionOnToken = (from: number, to: number, view: EditorView): ParsedToken => { + if (!view) return undefined; + const { tokens, compounds } = view.state.field(tokenField); + + const matchingCompound = compounds.find( + compound => compound.start === from && compound.end === to + ); + if (matchingCompound) return undefined; + + const matchingToken = tokens.find( + token => token.start === from && token.end === to + ); + return matchingToken; +}; \ No newline at end of file diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/components/ChipExpressionEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/components/ChipExpressionEditor.tsx index 58791969f40..bb9580a6e23 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/components/ChipExpressionEditor.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/components/ChipExpressionEditor.tsx @@ -17,8 +17,8 @@ */ import { EditorState } from "@codemirror/state"; -import { EditorView, keymap, tooltips } from "@codemirror/view"; -import React, { useEffect, useRef, useState } from "react"; +import { EditorView, hoverTooltip, keymap, tooltips } from "@codemirror/view"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { useFormContext } from "../../../../../context"; import { buildNeedTokenRefetchListner, @@ -35,21 +35,27 @@ import { CursorInfo, buildOnFocusOutListner, buildOnSelectionChange, - ProgrammerticSelectionChange, - SyncDocValueWithPropValue + SyncDocValueWithPropValue, + isSelectionOnToken, + createTooltipHeader, + createParametersSection, + createDocumentationSection, + createTooltipContainer, + createTooltipPositioningHandlers } from "../CodeUtils"; -import { mapSanitizedToRaw } from "../utils"; +import { TOKEN_START_CHAR_OFFSET_INDEX } from "../utils"; import { history } from "@codemirror/commands"; import { autocompletion } from "@codemirror/autocomplete"; import { FloatingButtonContainer, FloatingToggleButton, ChipEditorContainer } from "../styles"; import { HelperpaneOnChangeOptions } from "../../../../Form/types"; -import { CompletionItem, FnSignatureDocumentation, HelperPaneHeight } from "@wso2/ui-toolkit"; +import { CompletionItem, FnSignatureDocumentation, HELPER_PANE_WIDTH, HelperPaneHeight } from "@wso2/ui-toolkit"; import { CloseHelperIcon, ExpandIcon, MinimizeIcon, OpenHelperIcon } from "./FloatingButtonIcons"; import { LineRange } from "@wso2/ballerina-core"; -import FXButton from "./FxButton"; import { HelperPaneToggleButton } from "./HelperPaneToggleButton"; import { HelperPane } from "./HelperPane"; import { listContinuationKeymap } from "../../../ExpandedEditor/utils/templateUtils"; +import { ChipExpressionEditorDefaultConfiguration } from "../ChipExpressionDefaultConfig"; +import { ChipExpressionEditorConfig } from "../../Configurations"; type HelperPaneState = { isOpen: boolean; @@ -91,29 +97,66 @@ export type ChipExpressionEditorComponentProps = { onEditorViewReady?: (view: EditorView) => void; toolbarRef?: React.RefObject; enableListContinuation?: boolean; + configuration?: ChipExpressionEditorDefaultConfiguration; } export const ChipExpressionEditorComponent = (props: ChipExpressionEditorComponentProps) => { + const { configuration = new ChipExpressionEditorConfig() } = props; const [helperPaneState, setHelperPaneState] = useState({ isOpen: false, top: 0, left: 0 }); - const editorRef = useRef(null); const helperPaneRef = useRef(null); const fieldContainerRef = useRef(null); const viewRef = useRef(null); const [isTokenUpdateScheduled, setIsTokenUpdateScheduled] = useState(true); - const completionsRef = useRef(props.completions); + const completionsRef = useRef(props.completions); const helperPaneToggleButtonRef = useRef(null); + const completionsFetchScheduledRef = useRef(false); const savedSelectionRef = useRef<{ from: number; to: number } | null>(null); const { expressionEditor } = useFormContext(); const expressionEditorRpcManager = expressionEditor?.rpcManager; + async function docTooltip(view: EditorView, pos: number) { + const value = view.state.doc.toString() + const fnSignature = await props.extractArgsFromFunction?.(value, pos); + if (!fnSignature) return null; + + return { + pos: pos, + end: pos, + above: true, + create() { + const dom = createTooltipContainer(); + dom.appendChild(createTooltipHeader(fnSignature.label)); + + if (fnSignature.args && fnSignature.args.length > 0) { + dom.appendChild(createParametersSection(fnSignature.args, fnSignature.currentArgIndex)); + } + if (fnSignature.documentation) { + dom.appendChild(createDocumentationSection(fnSignature.documentation)); + } + const { mount, destroy } = createTooltipPositioningHandlers(view); + + return { + dom, + mount, + destroy + }; + } + }; + } + + const tooltipExtension = hoverTooltip((view, pos) => { + return docTooltip(view, pos); + }); + const needTokenRefetchListner = buildNeedTokenRefetchListner(() => { setIsTokenUpdateScheduled(true); }); const handleChangeListner = buildOnChangeListner((newValue, cursor) => { - props.onChange(newValue, cursor.position.to); + completionsFetchScheduledRef.current = true; + props.onChange(configuration.deserializeValue(newValue), cursor.position.to); const textBeforeCursor = newValue.slice(0, cursor.position.to); const lastNonSpaceChar = textBeforeCursor.trimEnd().slice(-1); const isTrigger = lastNonSpaceChar === '+' || lastNonSpaceChar === ':'; @@ -141,20 +184,37 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone setIsTokenUpdateScheduled(true); }); - const completionSource = buildCompletionSource(() => completionsRef.current); + const waitForStateChange = (): Promise => { + return new Promise((resolve) => { + const checkState = () => { + if (!completionsFetchScheduledRef.current) { + resolve(completionsRef.current); + } else { + requestAnimationFrame(checkState); + } + }; + checkState(); + }); + }; + + const completionSource = useMemo(() => { + return buildCompletionSource(waitForStateChange); + }, [props.completions]); const helperPaneKeymap = buildHelperPaneKeymap(() => helperPaneState.isOpen, () => { setHelperPaneState(prev => ({ ...prev, isOpen: false })); }); const onHelperItemSelect = async (value: string, options: HelperpaneOnChangeOptions) => { - const newValue = value if (!viewRef.current) return; const view = viewRef.current; // Use saved selection if available, otherwise fall back to current selection const currentSelection = savedSelectionRef.current || view.state.selection.main; const { from, to } = options?.replaceFullText ? { from: 0, to: view.state.doc.length } : currentSelection; + + const selectionIsOnToken = isSelectionOnToken(currentSelection.from, currentSelection.to, view); + const newValue = selectionIsOnToken ? value : configuration.getHelperValue(value); let finalValue = newValue; let cursorPosition = from + newValue.length; @@ -171,7 +231,7 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone let functionDef = newValue; let prefix = ''; let suffix = ''; - + // Check if it's within a string template const stringTemplateMatch = newValue.match(/^(.*\$\{)([^}]+)(\}.*)$/); if (stringTemplateMatch) { @@ -179,12 +239,12 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone functionDef = stringTemplateMatch[2]; suffix = stringTemplateMatch[3]; } - + let cursorPositionForExtraction = from + prefix.length + functionDef.length - 1; if (functionDef.endsWith(')}')) { cursorPositionForExtraction -= 1; } - + const fnSignature = await props.extractArgsFromFunction(functionDef, cursorPositionForExtraction); if (fnSignature && fnSignature.args && fnSignature.args.length > 0) { @@ -229,11 +289,10 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone let top = buttonRect.bottom - editorRect.top; let left = buttonRect.left - editorRect.left; - // Add overflow correction for window boundaries - const HELPER_PANE_WIDTH = 300; - const viewportWidth = window.innerWidth; - const absoluteLeft = buttonRect.left; - const overflow = absoluteLeft + HELPER_PANE_WIDTH - viewportWidth; + // Add overflow correction for editor boundaries + const editorWidth = editorRect.width; + const relativeRight = left + HELPER_PANE_WIDTH; + const overflow = relativeRight - editorWidth; if (overflow > 0) { left -= overflow; @@ -263,6 +322,7 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone const startState = EditorState.create({ doc: props.value ?? "", extensions: [ + ...(configuration.getPlugins()), history(), keymap.of([ ...helperPaneKeymap, @@ -284,24 +344,21 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone handleChangeListner, handleFocusListner, handleFocusOutListner, + tooltipExtension, handleSelectionChange, ...(props.isInExpandedMode ? [EditorView.theme({ "&": { height: "100%" }, - ".cm-scroller": { overflow: "auto" } + ".cm-scroller": { overflow: "auto", maxHeight: "100%" } })] : props.sx && 'height' in props.sx ? [EditorView.theme({ - "&": { - height: typeof (props.sx as any).height === 'number' ? - `${(props.sx as any).height}px` : - (props.sx as any).height - }, - ".cm-scroller": { overflow: "auto" } + "&": { height: "100%" }, + ".cm-scroller": { overflow: "auto", maxHeight: "100%" } })] : [EditorView.theme({ "&": { maxHeight: "150px" }, - ".cm-scroller": { overflow: "auto" } + ".cm-scroller": { overflow: "auto", maxHeight: "150px" } })]) ] }); @@ -323,8 +380,14 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone useEffect(() => { if (props.value == null || !viewRef.current) return; + const serializedValue = configuration.serializeValue(props.value); + const deserializeValue = configuration.deserializeValue(props.value); + if (deserializeValue.trim() !== props.value.trim()) { + props.onChange(deserializeValue, deserializeValue.length); + return + } const updateEditorState = async () => { - const sanitizedValue = props.sanitizedExpression ? props.sanitizedExpression(props.value) : props.value; + const sanitizedValue = props.sanitizedExpression ? props.sanitizedExpression(serializedValue) : serializedValue; const currentDoc = viewRef.current!.state.doc.toString(); const isExternalUpdate = sanitizedValue !== currentDoc; @@ -332,15 +395,18 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone const startLine = props.targetLineRange?.startLine; const tokenStream = await expressionEditorRpcManager?.getExpressionTokens( - props.value, + deserializeValue, props.fileName, startLine !== undefined ? startLine : undefined ); + let prefixCorrectedTokenStream = tokenStream; + if (tokenStream && tokenStream.length >= 5) { + prefixCorrectedTokenStream = [...tokenStream]; + prefixCorrectedTokenStream[TOKEN_START_CHAR_OFFSET_INDEX] -= configuration.getSerializationPrefix().length; + } setIsTokenUpdateScheduled(false); - const effects = tokenStream ? [tokensChangeEffect.of({ - tokens: tokenStream, - rawValue: props.value, - sanitizedValue: sanitizedValue + const effects = prefixCorrectedTokenStream ? [tokensChangeEffect.of({ + tokens: prefixCorrectedTokenStream })] : []; const changes = isExternalUpdate ? { from: 0, to: viewRef.current!.state.doc.length, insert: sanitizedValue } @@ -362,6 +428,7 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone // just don't touch this. useEffect(() => { completionsRef.current = props.completions; + completionsFetchScheduledRef.current = false; }, [props.completions]); // Trigger token update when sanitization mode changes @@ -381,10 +448,6 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone if (!isClickInsideEditor && !isClickInsideHelperPane && !isClickOnToggleButton && !isClickInsideToolbar) { setHelperPaneState(prev => ({ ...prev, isOpen: false })); - viewRef.current?.dispatch({ - selection: { anchor: 0 }, - annotations: ProgrammerticSelectionChange.of(true) - }); viewRef.current?.dom.blur(); } }; @@ -422,16 +485,20 @@ export const ChipExpressionEditorComponent = (props: ChipExpressionEditorCompone - {!props.isInExpandedMode && } -
+ {!props.isInExpandedMode && configuration.getAdornment()({ onClick: () => {}})} +
- {helperPaneState.isOpen && + {helperPaneState.isOpen && configuration.showHelperPane() && ((pro ref={ref} top={props.top} left={props.left} - onMouseDown={e => { - e.preventDefault(); - e.stopPropagation(); - }} > {props.getHelperPane( props.value, diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/constants.ts b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/constants.ts index 52c643fde92..8ecaacd8905 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/constants.ts +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/constants.ts @@ -18,6 +18,7 @@ export const CHIP_EXPRESSION_EDITOR_HEIGHT = 26; export const EXPANDED_EDITOR_HEIGHT = 500; +export const HELPER_PANE_WIDTH = 300; // Data attributes export const DATA_CHIP_ATTRIBUTE = 'data-chip'; diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/types.ts b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/types.ts index 3fef3473a6a..b30e16df0c8 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/types.ts +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/types.ts @@ -19,13 +19,19 @@ export enum InputMode { TEXT = "Text", EXP = "Expression", - GUIDED = "Guided", - TEMPLATE = "Template" + RECORD = "Record", + TEMPLATE = "Template", + NUMBER = "Number", + BOOLEAN = "Boolean", + SQL = "SQL" } export const INPUT_MODE_MAP = { string: InputMode.TEXT, - "ai:Prompt": InputMode.TEMPLATE + "ai:Prompt": InputMode.TEMPLATE, + int: InputMode.NUMBER, + boolean: InputMode.BOOLEAN, + "sql:ParameterizedQuery": InputMode.SQL }; export enum TokenType { diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts index f3d55de191d..20d55cce582 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/ChipExpressionEditor/utils.ts @@ -19,11 +19,11 @@ import { CompletionItem } from "@wso2/ui-toolkit"; import { INPUT_MODE_MAP, InputMode, TokenType, CompoundTokenSequence, TokenMetadata, DocumentType, TokenPattern } from "./types"; -const TOKEN_LINE_OFFSET_INDEX = 0; -const TOKEN_START_CHAR_OFFSET_INDEX = 1; -const TOKEN_LENGTH_INDEX = 2; -const TOKEN_TYPE_INDEX = 3; -const TOKEN_MODIFIERS_INDEX = 4; +export const TOKEN_LINE_OFFSET_INDEX = 0; +export const TOKEN_START_CHAR_OFFSET_INDEX = 1; +export const TOKEN_LENGTH_INDEX = 2; +export const TOKEN_TYPE_INDEX = 3; +export const TOKEN_MODIFIERS_INDEX = 4; export const TOKEN_TYPE_INDEX_MAP: { [key: number]: TokenType } = { 0: TokenType.VARIABLE, @@ -150,7 +150,7 @@ export const filterCompletionsByPrefixAndType = (completions: CompletionItem[], } return completions.filter(completion => - (completion.kind === 'function' || completion.kind === 'variable' || completion.kind === 'field') && + (completion.kind === 'function' || completion.kind === 'variable' || completion.kind === 'field' || completion.kind === 'enum-member') && completion.label.toLowerCase().startsWith(prefix.toLowerCase()) ); }; diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/Configurations.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/Configurations.tsx new file mode 100644 index 00000000000..83f5f56c56b --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/Configurations.tsx @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { ChipExpressionEditorDefaultConfiguration } from "./ChipExpressionEditor/ChipExpressionDefaultConfig"; +import { TokenType } from "./ChipExpressionEditor/types"; +import { ParsedToken } from "./ChipExpressionEditor/utils"; +import { InputMode } from "./ChipExpressionEditor/types"; +import { ThemeColors } from "@wso2/ui-toolkit/lib/styles/Theme"; +import { tags } from "@lezer/highlight"; +import { HighlightStyle, syntaxHighlighting } from "@codemirror/language"; +import { sql } from "@codemirror/lang-sql"; + + +const customSqlHighlightStyle = HighlightStyle.define([ + { + tag: tags.keyword, + color: ThemeColors.PRIMARY + }, + + { + tag: tags.comment, + color: ThemeColors.ON_SURFACE_VARIANT, + fontStyle: "italic" + }, + + { + tag: tags.string, + color: ThemeColors.ERROR + }, + + { + tag: tags.number, + color: ThemeColors.SECONDARY + }, + { + tag: tags.operator, + color: ThemeColors.ON_SURFACE + }, + { + tag: tags.punctuation, + color: ThemeColors.ON_SURFACE + }, + { + tag: tags.variableName, + color: ThemeColors.ON_SURFACE + } +]); + +export class StringTemplateEditorConfig extends ChipExpressionEditorDefaultConfiguration { + getHelperValue(value: string, token?: ParsedToken): string { + if (token?.type === TokenType.FUNCTION) return value; + return `\$\{${value}\}`; + } + getSerializationPrefix() { + return "string `"; + } + getSerializationSuffix() { + return "`"; + } + getAdornment(): ({ onClick }: { onClick?: () => void; }) => JSX.Element { + return () => null; + } + serializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value.trim().slice(prefix.length, value.trim().length - suffix.length); + } + return value; + } + deserializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value; + } + return `${prefix}${value}${suffix}`; + } +} + +export class RawTemplateEditorConfig extends ChipExpressionEditorDefaultConfiguration { + getHelperValue(value: string, token?: ParsedToken): string { + if (token?.type === TokenType.FUNCTION) return value; + return `\$\{${value}\}`; + } + getSerializationPrefix() { + return "`"; + } + getSerializationSuffix() { + return "`"; + } + getAdornment(): ({ onClick }: { onClick?: () => void; }) => JSX.Element { + return () => null; + } + serializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value.trim().slice(prefix.length, value.trim().length - suffix.length); + } + return value; + } + deserializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value; + } + return `${prefix}${value}${suffix}`; + } +} + +export class SQLExpressionEditorConfig extends ChipExpressionEditorDefaultConfiguration { + showHelperPane() { + return true; + } + getHelperValue(value: string, token?: ParsedToken): string { + if (token?.type === TokenType.FUNCTION) return value; + return `\$\{${value}\}`; + } + getAdornment() { + return () => null; + } + getSerializationPrefix(): string { + return "sql `"; + } + getSerializationSuffix(): string { + return "`"; + } + serializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value.trim().slice(prefix.length, value.trim().length - suffix.length); + } + return value; + } + deserializeValue(value: string): string { + const suffix = this.getSerializationSuffix(); + const prefix = this.getSerializationPrefix(); + if (value.trim().startsWith(prefix) && value.trim().endsWith(suffix)) { + return value; + } + return `${prefix}${value}${suffix}`; + } + getPlugins() { + return [ + sql(), + syntaxHighlighting(customSqlHighlightStyle) + ]; + } +} + +export class ChipExpressionEditorConfig extends ChipExpressionEditorDefaultConfiguration { + getHelperValue(value: string, token?: ParsedToken): string { + if (token?.type === TokenType.FUNCTION) return value; + return `\$\{${value}\}`; + } +} + +export class PrimaryModeChipExpressionEditorConfig extends ChipExpressionEditorDefaultConfiguration { + private readonly primaryMode: InputMode; + + constructor(primaryMode: InputMode) { + super(); + this.primaryMode = primaryMode; + } + + getHelperValue(value: string, token?: ParsedToken): string { + const isTemplateEditor = ( + this.primaryMode === InputMode.TEXT || + this.primaryMode === InputMode.TEMPLATE || + this.primaryMode === InputMode.SQL + ); + + + if (isTemplateEditor && (!token || token.type !== TokenType.FUNCTION)) { + return `\$\{${value}\}`; + } + return value; + } +} diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/NumberExpressionEditor/NumberEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/NumberExpressionEditor/NumberEditor.tsx new file mode 100644 index 00000000000..c22c8637d93 --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/NumberExpressionEditor/NumberEditor.tsx @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 React from "react"; +import { getValueForTextModeEditor } from "../../utils"; +import { ChipExpressionEditorComponent, ChipExpressionEditorComponentProps } from "../ChipExpressionEditor/components/ChipExpressionEditor"; +import { ChipExpressionEditorDefaultConfiguration } from "../ChipExpressionEditor/ChipExpressionDefaultConfig"; +import { EditorState } from "@codemirror/state"; + +class NumberExpressionEditorConfig extends ChipExpressionEditorDefaultConfiguration { + showHelperPane() { + return false; + } + getAdornment() { + return () => null; + } + getPlugins() { + const numericOnly = EditorState.changeFilter.of(tr => { + let allow = true; + tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => { + const text = inserted.toString(); + + if (!/^[0-9.]*$/.test(text)) { + allow = false; + return; + } + + if ((text.match(/\./g) || []).length > 1) { + allow = false; + return; + } + }); + + return allow; + }); + + return [numericOnly]; + + } +} + +export const NumberExpressionEditor: React.FC = (props) => { + + return ( + + ); +}; + +export default NumberExpressionEditor diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RecordConfigPreviewEditor/RecordConfigPreviewEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RecordConfigPreviewEditor/RecordConfigPreviewEditor.tsx new file mode 100644 index 00000000000..a09e1b27173 --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/RecordConfigPreviewEditor/RecordConfigPreviewEditor.tsx @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { FormExpressionEditor } from "@wso2/ui-toolkit"; +import { ExpressionField } from "../../ExpressionField"; +import React from "react"; +import { getValueForTextModeEditor } from "../../utils"; +import styled from "@emotion/styled"; +import { FloatingToggleButton } from "../ChipExpressionEditor/components/FloatingToggleButton"; +import { ExpandIcon } from "../ChipExpressionEditor/components/FloatingButtonIcons"; + +const EditorContainer = styled.div` + width: 100%; + position: relative; + + #text-mode-editor-expand { + opacity: 0; + transition: opacity 0.2s ease-in-out; + } + + &:hover #text-mode-editor-expand { + opacity: 1; + } +`; + +type RecordConfigPreviewEditorProps = Pick; + +export const RecordConfigPreviewEditor: React.FC = ({ + name, + value, + autoFocus, + ariaLabel, + placeholder, + onChange, + onFocus, + onBlur, + onSave, + onCancel, + onRemove, + growRange, + exprRef, + anchorRef, + onOpenExpandedMode, + isInExpandedMode, +}) => { + + const handleOnChange = async (value: string, updatedCursorPosition: number) => { + const newValue = "\"" + value + "\""; + onChange(newValue, updatedCursorPosition); + } + + return ( + + } + ariaLabel={ariaLabel} + onChange={handleOnChange} + onFocus={onFocus} + onBlur={onBlur} + onSave={onSave} + onCancel={onCancel} + onRemove={onRemove} + enableExIcon={false} + growRange={growRange} + sx={{ paddingInline: '0' }} + placeholder={placeholder} + /> + {onOpenExpandedMode && !isInExpandedMode && ( +
+ + + +
+ )} +
+ ); +}; + +export default RecordConfigPreviewEditor diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/SqlExpressionEditor/SqlExpressionEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/SqlExpressionEditor/SqlExpressionEditor.tsx new file mode 100644 index 00000000000..9560c545120 --- /dev/null +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/SqlExpressionEditor/SqlExpressionEditor.tsx @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 React from "react"; +import { getValueForTextModeEditor } from "../../utils"; +import { ChipExpressionEditorComponent, ChipExpressionEditorComponentProps } from "../ChipExpressionEditor/components/ChipExpressionEditor"; +import { SQLExpressionEditorConfig } from "../Configurations"; + +export const SQLExpressionEditor: React.FC = (props) => { + + return ( + + ); +}; diff --git a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/TextExpressionEditor/TextModeEditor.tsx b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/TextExpressionEditor/TextModeEditor.tsx index 8fde4736c91..d91d91d9e15 100644 --- a/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/TextExpressionEditor/TextModeEditor.tsx +++ b/workspaces/ballerina/ballerina-side-panel/src/components/editors/MultiModeExpressionEditor/TextExpressionEditor/TextModeEditor.tsx @@ -16,13 +16,12 @@ * under the License. */ -import { FormExpressionEditor } from "@wso2/ui-toolkit"; -import { ExpressionField } from "../../ExpressionField"; import React from "react"; import { getValueForTextModeEditor } from "../../utils"; import styled from "@emotion/styled"; import { FloatingToggleButton } from "../ChipExpressionEditor/components/FloatingToggleButton"; import { ExpandIcon } from "../ChipExpressionEditor/components/FloatingButtonIcons"; +import { ChipExpressionEditorComponent, ChipExpressionEditorComponentProps } from "../ChipExpressionEditor/components/ChipExpressionEditor"; const EditorContainer = styled.div` width: 100%; @@ -38,57 +37,29 @@ const EditorContainer = styled.div` } `; -type TextModeEditorProps = Pick; - -export const TextModeEditor: React.FC = ({ - name, - value, - autoFocus, - ariaLabel, - placeholder, - onChange, - onFocus, - onBlur, - onSave, - onCancel, - onRemove, - growRange, - exprRef, - anchorRef, - onOpenExpandedMode, - isInExpandedMode, -}) => { - - const handleOnChange = async (value: string, updatedCursorPosition: number) => { - const newValue = "\"" + value + "\""; - onChange(newValue, updatedCursorPosition); - } +export const TextModeEditor: React.FC = (props) => { return ( - } - ariaLabel={ariaLabel} - onChange={handleOnChange} - onFocus={onFocus} - onBlur={onBlur} - onSave={onSave} - onCancel={onCancel} - onRemove={onRemove} - enableExIcon={false} - growRange={growRange} - sx={{ paddingInline: '0' }} - placeholder={placeholder} + - {onOpenExpandedMode && !isInExpandedMode && ( + {props.onOpenExpandedMode && !props.isInExpandedMode && (
- +
diff --git a/workspaces/ballerina/ballerina-visualizer/src/MainPanel.tsx b/workspaces/ballerina/ballerina-visualizer/src/MainPanel.tsx index 67b20143d0a..52de4b84a17 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/MainPanel.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/MainPanel.tsx @@ -81,6 +81,7 @@ import Popup from "./components/Popup"; import { ServiceFunctionForm } from "./views/BI/ServiceFunctionForm"; import ServiceConfigureView from "./views/BI/ServiceDesigner/ServiceConfigureView"; import { WorkspaceOverview } from "./views/BI/WorkspaceOverview"; +import { SamplesView } from "./views/BI/SamplesView"; const globalStyles = css` *, @@ -454,6 +455,10 @@ const MainPanel = () => { setNavActive(false); setViewComponent(); break; + case MACHINE_VIEW.BISamplesView: + setNavActive(false); + setViewComponent(); + break; case MACHINE_VIEW.SetupView: setNavActive(false); setViewComponent(); diff --git a/workspaces/ballerina/ballerina-visualizer/src/components/TopNavigationBar/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/components/TopNavigationBar/index.tsx index b3d873410f8..aa133b51668 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/components/TopNavigationBar/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/components/TopNavigationBar/index.tsx @@ -157,7 +157,8 @@ export function TopNavigationBar(props: TopNavigationBarProps) { "data mapper", "connection", "add project", - "bi add project skip" + "bi add project skip", + "welcome" ]; if (workspaceType?.type !== "BALLERINA_WORKSPACE") { diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/AddConfigurableVariables/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/AddConfigurableVariables/index.tsx index 97cbb168ac1..db2ae60a91f 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/AddConfigurableVariables/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/AddConfigurableVariables/index.tsx @@ -52,6 +52,7 @@ export function AddForm(props: ConfigFormProps) { const handleSave = async (node: FlowNode) => { setIsSaving(true); + node.properties.defaultValue.modified = true; await rpcClient.getBIDiagramRpcClient().updateConfigVariablesV2({ configFilePath: props.filename, configVariable: node, diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/AddConnectionWizard/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/AddConnectionWizard/index.tsx index edf843f3b11..4cb762e4850 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/AddConnectionWizard/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Connection/AddConnectionWizard/index.tsx @@ -276,7 +276,6 @@ export function AddConnectionWizard(props: AddConnectionWizardProps) { .then((response) => { console.log(">>> Updated source code", response); if (!isConnector) { - setSavingFormStatus(SavingFormStatus.SUCCESS); selectedNodeRef.current = undefined; if (options?.postUpdateCallBack) { options.postUpdateCallBack(); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/FlowDiagram/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/FlowDiagram/index.tsx index 78d522323b8..2eee1268d9a 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/FlowDiagram/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/FlowDiagram/index.tsx @@ -103,7 +103,7 @@ interface NavigationStackItem { export type FormSubmitOptions = { closeSidePanel?: boolean; - updateLineRange?: boolean; + isChangeFromHelperPane?: boolean; postUpdateCallBack?: () => void; }; @@ -166,9 +166,12 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { useEffect(() => { debouncedGetFlowModel(); - }, [breakpointState, syntaxTree]); + }, [breakpointState]); useEffect(() => { + rpcClient.onProjectContentUpdated(() => { + debouncedGetFlowModel(); + }) rpcClient.onParentPopupSubmitted((parent: ParentPopupData) => { if (parent.dataMapperMetadata) { // Skip if the parent is a data mapper popup @@ -490,17 +493,22 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { .then((model) => { console.log(">>> BIFlowDiagram getFlowModel", model); if (model?.flowModel) { + const currentSelectedNode = selectedNodeRef.current; + if ( + currentSelectedNode && + typeof currentSelectedNode?.properties?.variable?.value === "string" + ) { + const updatedSelectedNode = searchNodesByName(model.flowModel.nodes, currentSelectedNode?.properties?.variable?.value); + if (updatedSelectedNode) { + selectedNodeRef.current = updatedSelectedNode; + setSelectedNodeId(updatedSelectedNode.id); + } + } updateAgentModelTypes(model?.flowModel); setModel(model.flowModel); const parentMetadata = model.flowModel.nodes.find( (node) => node.codedata.node === "EVENT_START" )?.metadata.data as ParentMetadata | undefined; - - // Get visualizer location and pass position to onReady - rpcClient.getVisualizerLocation().then((location: VisualizerLocation) => { - console.log(">>> Visualizer location", location?.position); - onReady(model.flowModel.fileName, parentMetadata, location?.position); - }); if (shouldUpdateLineRangeRef.current) { const varName = typeof updatedNodeRef.current?.properties?.variable?.value === "string" ? updatedNodeRef.current.properties.variable.value @@ -511,6 +519,11 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { endLine: newNode.codedata.lineRange.endLine }) } + // Get visualizer location and pass position to onReady + rpcClient.getVisualizerLocation().then((location: VisualizerLocation) => { + console.log(">>> Visualizer location", location?.position); + onReady(model.flowModel.fileName, parentMetadata, location?.position); + }); } }) .finally(() => { @@ -644,6 +657,33 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { return undefined; }; + const flattenNodes = (nodes: FlowNode[]): FlowNode[] => { + const result: FlowNode[] = []; + const traverse = (nodeList: FlowNode[]) => { + for (const node of nodeList) { + result.push(node); + if (node.branches && node.branches.length > 0) { + for (const branch of node.branches) { + if (branch.children && branch.children.length > 0) { + traverse(branch.children); + } + } + } + } + }; + traverse(nodes); + return result; + }; + + const getNodeBefore = (targetNode: FlowNode, nodes: FlowNode[]): FlowNode | undefined => { + const flattened = flattenNodes(nodes); + const index = flattened.findIndex(node => node.id === targetNode.id); + if (index > 0) { + return flattened[index - 1]; + } + return undefined; + }; + const resetNodeSelectionStates = () => { setShowSidePanel(false); setSidePanelView(SidePanelView.NODE_LIST); @@ -1209,10 +1249,28 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { const noFormSubmitOptions = !options || ( options?.closeSidePanel === undefined - && options?.updateLineRange === undefined + && options?.isChangeFromHelperPane === undefined && options?.postUpdateCallBack === undefined ); + if ( + options?.isChangeFromHelperPane && + selectedNodeRef.current?.codedata && + !selectedNodeRef.current.codedata.isNew + ) { + const baseStartLine = selectedNodeRef.current.codedata.lineRange.startLine; + const safeOffset = Math.max(0, baseStartLine.offset - 1); + let targetLine = { ...baseStartLine, offset: safeOffset }; + + const nodeBefore = model ? getNodeBefore(selectedNodeRef.current, model.nodes) : undefined; + if (nodeBefore && nodeBefore.codedata.lineRange.endLine.line < targetLine.line) { + targetLine = nodeBefore.codedata.lineRange.endLine; + } + + updatedNode.codedata.lineRange.startLine = targetLine; + updatedNode.codedata.lineRange.endLine = targetLine; + } + if (dataMapperMode && dataMapperMode !== DataMapperDisplayMode.NONE) { rpcClient .getDataMapperRpcClient() @@ -1225,7 +1283,7 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { if (options?.postUpdateCallBack) { options.postUpdateCallBack(); } - shouldUpdateLineRangeRef.current = options?.updateLineRange; + shouldUpdateLineRangeRef.current = options?.isChangeFromHelperPane; updatedNodeRef.current = updatedNode; rpcClient.getVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, @@ -1262,6 +1320,7 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { filePath: model.fileName, flowNode: updatedNode, isFunctionNodeUpdate: dataMapperMode !== DataMapperDisplayMode.NONE, + isHelperPaneChange: options?.isChangeFromHelperPane, }) .then(async (response) => { if (response.artifacts.length > 0) { @@ -1280,7 +1339,43 @@ export function BIFlowDiagram(props: BIFlowDiagramProps) { if (options?.postUpdateCallBack) { options.postUpdateCallBack(); } - shouldUpdateLineRangeRef.current = options?.updateLineRange; + shouldUpdateLineRangeRef.current = options?.isChangeFromHelperPane; + if (options?.isChangeFromHelperPane) { + const updatedModel = await rpcClient.getBIDiagramRpcClient().getFlowModel(); + if (!updatedModel?.flowModel) { + console.error(">>> Flow model missing after helper-pane update"); + return; + } + + let newTargetLineRange = targetLineRange; + if (!selectedNodeRef.current?.codedata?.isNew) { + const updatedSelectedNode = searchNodesByName( + updatedModel.flowModel.nodes, + selectedNodeRef.current.properties?.variable?.value as string + ); + if (!updatedSelectedNode) { + console.error(">>> Selected node not found in updated flow model"); + return; + } + newTargetLineRange = updatedSelectedNode.codedata.lineRange; + } else { + const newNode = searchNodesByName( + updatedModel.flowModel.nodes, + updatedNode.properties?.variable?.value as string + ); + if (!newNode || !newTargetLineRange) { + console.error(">>> New node or targetLineRange missing after helper-pane update"); + return; + } + newTargetLineRange.startLine = newNode.codedata.lineRange.endLine; + newTargetLineRange.endLine = newNode.codedata.lineRange.endLine; + } + + if (newTargetLineRange) { + changeTargetRange(newTargetLineRange); + } + shouldUpdateLineRangeRef.current = false; + } updatedNodeRef.current = updatedNode; } else { console.error(">>> Error updating source code", response); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx index 1878c134cdb..badf69eba60 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx @@ -34,7 +34,9 @@ import { Imports, CodeData, LinePosition, - NodeProperties + NodeProperties, + ExpressionCompletionsRequest, + ExpressionCompletionsResponse } from "@wso2/ballerina-core"; import { FormField, @@ -89,6 +91,7 @@ interface FormProps { onCancel?: () => void; editForm?: boolean; isGraphqlEditor?: boolean; + isDataMapperEditor?: boolean; onSubmit: (data: FormValues, formImports?: FormImports, importsCodedata?: CodeData) => void; isSaving?: boolean; isActiveSubPanel?: boolean; @@ -127,6 +130,7 @@ export function FormGeneratorNew(props: FormProps) { onSubmit, isSaving, isGraphqlEditor, + isDataMapperEditor, openSubPanel, updatedExpressionField, resetUpdatedExpressionField, @@ -450,7 +454,7 @@ export function FormGeneratorNew(props: FormProps) { .sort((a, b) => a.sortText.localeCompare(b.sortText)); } else { const { lineOffset, charOffset } = calculateExpressionOffsets(value, offset); - let completions = await rpcClient.getBIDiagramRpcClient().getExpressionCompletions({ + const completionRequest: ExpressionCompletionsRequest = { filePath: fileName, context: { expression: value, @@ -464,7 +468,14 @@ export function FormGeneratorNew(props: FormProps) { triggerKind: triggerCharacter ? 2 : 1, triggerCharacter: triggerCharacter as TriggerCharacter } - }); + }; + + let completions: ExpressionCompletionsResponse; + if (!isDataMapperEditor) { + completions = await rpcClient.getBIDiagramRpcClient().getExpressionCompletions(completionRequest); + } else { + completions = await rpcClient.getBIDiagramRpcClient().getDataMapperCompletions(completionRequest); + } // Convert completions to the ExpressionEditor format let convertedCompletions: CompletionItem[] = []; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/ParameterBranch.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/ParameterBranch.tsx index 6ff47a25c4c..79f4985bdc7 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/ParameterBranch.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/ParameterBranch.tsx @@ -18,7 +18,7 @@ import React, { useState } from "react"; import { TypeField } from "@wso2/ballerina-core"; -import { Button } from "@wso2/ui-toolkit"; +import { Button, Codicon } from "@wso2/ui-toolkit"; import { useHelperPaneStyles } from "./styles"; @@ -64,31 +64,48 @@ export function ParameterBranch(props: ParameterBranchProps) { } }); - function toggleOptionalParams(e: any) { + function toggleOptionalParams(e?: React.MouseEvent) { + if (e) { + e.stopPropagation(); + } setShowOptionalParams(!showOptionalParams); } + const shouldShowOptionalParamsDirectly = (optionalParams.length > 0 && depth === 1) || + (requiredParams.length === 0 && optionalParams.length > 0 && depth < 3); + return (
{requiredParams} - {(optionalParams.length > 0 && depth === 1) ? ( + {shouldShowOptionalParamsDirectly ? ( optionalParams ) : ( <> {optionalParams.length > 0 && (
- {/*
Optional fields
*/} - +
+ +
Optional fields
+
)} - {showOptionalParams && optionalParams.length > 0 && optionalParams} +
+ {showOptionalParams && optionalParams.length > 0 && optionalParams} +
)}
diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/CustomType/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/CustomType/index.tsx index 0ef73447d39..5df6b0efa63 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/CustomType/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/CustomType/index.tsx @@ -22,7 +22,7 @@ import { Codicon, Tooltip, Typography } from "@wso2/ui-toolkit"; import { TypeProps } from "../../ParameterBranch"; import { useHelperPaneStyles } from "../../styles"; -import { isRequiredParam } from "../../utils"; +import { isRequiredParam, resetFieldValues } from "../../utils"; export default function CustomType(props: TypeProps) { const { param, onChange } = props; @@ -38,6 +38,12 @@ export default function CustomType(props: TypeProps) { if (!requiredParam) { const newSelectedState = !paramSelected; param.selected = newSelectedState; + + // When unchecking, reset the field values + if (!newSelectedState) { + resetFieldValues(param); + } + setParamSelected(newSelectedState); onChange(); } diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/InclusionType/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/InclusionType/index.tsx index 37ec0427e5e..f3862395d82 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/InclusionType/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/InclusionType/index.tsx @@ -23,7 +23,7 @@ import { Codicon, Tooltip, Typography } from "@wso2/ui-toolkit"; import { TypeProps } from "../../ParameterBranch"; import { useHelperPaneStyles } from "../../styles"; import { ParameterBranch } from "../../ParameterBranch"; -import { isAllDefaultableFields, isRequiredParam, updateFieldsSelection } from "../../utils"; +import { isAllDefaultableFields, isRequiredParam, updateFieldsSelection, resetFieldValues } from "../../utils"; export default function InclusionType(props: TypeProps) { const { param, depth, onChange } = props; @@ -43,6 +43,11 @@ export default function InclusionType(props: TypeProps) { param.selected = newSelectedState; param.inclusionType.selected = newSelectedState; + // When unchecking, reset the field values + if (!newSelectedState) { + resetFieldValues(param); + } + // If the inclusion type has fields, update their selection state if (param.inclusionType?.fields && param.inclusionType.fields.length > 0) { updateFieldsSelection(param.inclusionType.fields, newSelectedState); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/RecordType/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/RecordType/index.tsx index 750c7dcea01..31335b497e9 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/RecordType/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/RecordType/index.tsx @@ -23,7 +23,7 @@ import { Codicon, Tooltip, Typography } from "@wso2/ui-toolkit"; import { TypeProps } from "../../ParameterBranch"; import { useHelperPaneStyles } from "../../styles"; import { MemoizedParameterBranch } from "../../ParameterBranch"; -import { isRequiredParam, updateFieldsSelection } from "../../utils"; +import { isRequiredParam, updateFieldsSelection, resetFieldValues } from "../../utils"; export default function RecordType(props: TypeProps) { const { param, depth, onChange } = props; @@ -40,6 +40,11 @@ export default function RecordType(props: TypeProps) { const newSelectedState = !paramSelected; param.selected = newSelectedState; + // When unchecking, reset the field values + if (!newSelectedState) { + resetFieldValues(param); + } + // If the record has fields, update their selection state if (param.fields && param.fields.length > 0) { updateFieldsSelection(param.fields, newSelectedState); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/UnionType/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/UnionType/index.tsx index 14ff56118fc..503c9bf4019 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/UnionType/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/Types/UnionType/index.tsx @@ -24,7 +24,7 @@ import { Codicon, Dropdown, Tooltip, Typography } from "@wso2/ui-toolkit"; import { TypeProps } from "../../ParameterBranch"; import { useHelperPaneStyles } from "../../styles"; import { ParameterBranch } from "../../ParameterBranch"; -import { getSelectedUnionMember, isRequiredParam, updateFieldsSelection } from "../../utils"; +import { getSelectedUnionMember, isRequiredParam, updateFieldsSelection, resetFieldValues } from "../../utils"; export default function UnionType(props: TypeProps) { const { param, depth, onChange } = props; @@ -40,14 +40,70 @@ export default function UnionType(props: TypeProps) { const [paramSelected, setParamSelected] = useState(param.selected || requiredParam); const [selectedMemberType, setSelectedMemberType] = useState(getUnionParamName(initSelectedMember)); const [parameter, setParameter] = useState(initSelectedMember); + const isInitialized = useRef(false); - // Initialize: If the union is selected, ensure the selected member and its required fields are also selected + // Initialize union member selection when param becomes selected + const initializeUnionMember = () => { + if (!param.members || param.members.length === 0) { + return false; + } + + // Check if a member is already selected + const hasSelectedMember = param.members.some(member => member.selected === true); + if (hasSelectedMember) { + return true; // Already initialized + } + + // Get the member to select (use initSelectedMember if available, otherwise first member) + const memberToSelect = initSelectedMember || param.members[0]; + + if (memberToSelect) { + const memberTypeName = getUnionParamName(memberToSelect); + if (memberTypeName) { + const selectedMember = param.members.find((field) => getUnionParamName(field) === memberTypeName); + + if (selectedMember) { + updateFormFieldMemberSelection(selectedMember); + + if (selectedMember.fields && selectedMember.fields.length > 0) { + updateFieldsSelection(selectedMember.fields, true); + } + + setSelectedMemberType(memberTypeName); + setParameter(selectedMember); + + return true; + } + } + } + + return false; // Failed to initialize + }; + + // Initialize: Always ensure a member is selected if union param is selected useEffect(() => { - if (paramSelected && initSelectedMember) { - handleMemberType(paramSelected ? selectedMemberType : "", false); + // Only run initialization once + if (isInitialized.current) { + return; + } + isInitialized.current = true; + + // If union param is selected (or required), ensure a member is selected + if (paramSelected && param.members && param.members.length > 0) { + initializeUnionMember(); } }, []); + useEffect(() => { + // If param becomes selected but we haven't initialized the member yet + if (param.selected && !isInitialized.current && param.members && param.members.length > 0) { + const initialized = initializeUnionMember(); + if (initialized) { + isInitialized.current = true; + } + } + }, [param.selected]); + if (!(param.members && param.members.length > 0)) { return <>; } @@ -69,8 +125,28 @@ export default function UnionType(props: TypeProps) { }; const handleMemberType = (type: string, inCheckboxTrigger: boolean = true) => { - const selectedMember = param.members.find((field) => getUnionParamName(field) === type); + if (!type) { + return; + } + + const selectedMember = param.members?.find((field) => getUnionParamName(field) === type); + + if (!selectedMember) { + return; + } + + // Ensure the union param itself is selected when selecting a member + if (!param.selected) { + param.selected = true; + setParamSelected(true); + } + updateFormFieldMemberSelection(selectedMember); + + if (selectedMember.fields && selectedMember.fields.length > 0) { + updateFieldsSelection(selectedMember.fields, true); + } + setSelectedMemberType(type); setParameter(selectedMember); @@ -82,11 +158,7 @@ export default function UnionType(props: TypeProps) { } } - // If the parent is selected and the selected member has fields, ensure required fields are selected - if (param.selected && selectedMember && selectedMember.fields && selectedMember.fields.length > 0) { - updateFieldsSelection(selectedMember.fields, true); - } - + // Call onChange only after all selections are complete onChange(); }; @@ -96,6 +168,12 @@ export default function UnionType(props: TypeProps) { // When checkbox is checked, ensure the currently selected member is also marked as selected if (newSelectedState) { + // Ensure member is initialized before proceeding + if (!isInitialized.current) { + initializeUnionMember(); + isInitialized.current = true; + } + const selectedMember = param.members.find((field) => getUnionParamName(field) === selectedMemberType); if (selectedMember) { updateFormFieldMemberSelection(selectedMember); @@ -106,7 +184,8 @@ export default function UnionType(props: TypeProps) { } } } else { - // When unchecking, clear all member selections + // When unchecking, reset values and clear all member selections + resetFieldValues(param); param.members.forEach((field) => { field.selected = false; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/styles.ts b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/styles.ts index eabf726c434..d8e3dd2bd2d 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/styles.ts +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/styles.ts @@ -16,6 +16,7 @@ * under the License. */ import { css } from "@emotion/css"; +import { ThemeColors } from "@wso2/ui-toolkit"; const removePadding = { @@ -296,22 +297,44 @@ export const useHelperPaneStyles = () => ({ listOptionalWrapper: css({ display: 'flex', alignItems: 'center', - height: '32px', - marginBottom: '12px' + marginTop: '8px', + marginBottom: '8px' + }), + listOptionalHeader: css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + width: 'auto', + gap: '6px', + borderRadius: '5px', + cursor: 'pointer', + transition: 'all 0.2s ease', + border: '1px solid transparent', + '&:hover': { + backgroundColor: 'var(--vscode-list-hoverBackground)', + }, + '&:hover > div:last-of-type': { + opacity: 1, + color: ThemeColors.PRIMARY, + } + }), + listOptionalTitle: css({ + fontSize: '13px', + opacity: 0.7, + color: ThemeColors.ON_SURFACE_VARIANT, + transition: 'all 0.2s ease', + padding: '2px 4px', + borderRadius: '3px', + '&:hover': { + backgroundColor: 'var(--vscode-list-hoverBackground)', + } }), listOptionalBtn: css({ textTransform: 'none', minWidth: '32px', marginLeft: '8px' }), - listOptionalHeader: css({ - fontSize: '13px', - color: "gray", - fontWeight: 500, - letterSpacing: '0', - lineHeight: '14px', - paddingLeft: '0px', - }), }); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/utils/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/utils/index.tsx index 2027af17715..1eb1d26bd63 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/utils/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Components/RecordConstructView/utils/index.tsx @@ -64,17 +64,76 @@ export function checkFormFieldValue(field: FormField): boolean { return field.value !== undefined && field.value !== null; } +export function resetFieldValues(field: FormField): void { + if (!field) return; + + // Reset the field value + if (field.value !== undefined) { + field.value = undefined; + } + + // Reset nested fields + if (field.fields && field.fields.length > 0) { + field.fields.forEach(nestedField => { + resetFieldValues(nestedField); + }); + } + + // Reset union members + if (field.members && field.members.length > 0) { + field.members.forEach(member => { + resetFieldValues(member); + }); + } + + // Reset inclusion type fields + if (field.inclusionType?.fields && field.inclusionType.fields.length > 0) { + field.inclusionType.fields.forEach(inclusionField => { + resetFieldValues(inclusionField); + }); + } +} + export function updateFieldsSelection(fields: FormField[], selected: boolean): void { if (!fields || !fields.length) return; fields.forEach(field => { // When selecting: only select required fields - // When deselecting: deselect all fields (both required and optional) if (!selected || isRequiredParam(field)) { field.selected = selected; + + // If selecting a union type field, ensure a member is selected synchronously + if (selected && (field.typeName === "union" || field.typeName === "enum") && field.members && field.members.length > 0) { + // Check if a member is already selected + const hasSelectedMember = field.members.some(member => member.selected === true); + + if (!hasSelectedMember) { + // Select the first member (or use getSelectedUnionMember logic) + const memberToSelect = getSelectedUnionMember(field) || field.members[0]; + if (memberToSelect) { + const memberName = getUnionFormFieldName(memberToSelect); + // Mark the selected member + field.members.forEach(member => { + member.selected = getUnionFormFieldName(member) === memberName; + + // If this is the selected member and it has nested fields, select required fields + if (member.selected && member.fields && member.fields.length > 0) { + updateFieldsSelection(member.fields, true); + } + }); + } + } else { + // If a member is already selected, ensure its required fields are selected + const selectedMember = field.members.find(member => member.selected === true); + if (selectedMember && selectedMember.fields && selectedMember.fields.length > 0) { + updateFieldsSelection(selectedMember.fields, true); + } + } + } } // Recursively process nested fields + // Note: For union types, we handle members above, but union members can have fields too if (field.fields && field.fields.length > 0) { updateFieldsSelection(field.fields, selected); } diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Configurables.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Configurables.tsx index ee55b5f1e8c..e508b85de63 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Configurables.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Configurables.tsx @@ -149,6 +149,7 @@ export const Configurables = (props: ConfigurablesPageProps) => { closeModal(POPUP_IDS.CONFIGURABLES); //TODO: Need to disable the form before saving and move form close to finally block setIsSaving(true); + node.properties.defaultValue.modified = true; await rpcClient.getBIDiagramRpcClient().updateConfigVariablesV2({ configFilePath: Utils.joinPath(URI.file(projectPathUri), 'config.bal').fsPath, configVariable: node, diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/DocumentConfig.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/DocumentConfig.tsx index fbef883dad6..54a40f33396 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/DocumentConfig.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/DocumentConfig.tsx @@ -44,9 +44,8 @@ type DocumentConfigProps = { const AI_DOCUMENT_TYPES = Object.values(AIDocumentType); // Helper function to wrap content in document structure -const wrapInDocumentType = (documentType: AIDocumentType, content: string, addInterpolation: boolean = true): string => { - const docStructure = `<${documentType}>{content: ${content}}`; - return addInterpolation ? `\${${docStructure}}` : docStructure; +const wrapInDocumentType = (documentType: AIDocumentType, content: string): string => { + return`<${documentType}>{content: ${content}}`; }; export const DocumentConfig = ({ onChange, onClose, targetLineRange, filteredCompletions, currentValue, handleRetrieveCompletions, isInModal, inputMode }: DocumentConfigProps) => { @@ -164,13 +163,13 @@ export const DocumentConfig = ({ onChange, onClose, targetLineRange, filteredCom if (isAIDocumentType) { // For AI document types, wrap in string interpolation only in template mode if (isTemplateMode) { - onChange(`\${${fullPath}}`, false); + onChange(`${fullPath}`, false); } else { onChange(fullPath, false); } } else if (needsTypeCasting) { // Wrap the variable in the document structure with or without interpolation based on mode - const wrappedValue = wrapInDocumentType(documentType, fullPath, isTemplateMode); + const wrappedValue = wrapInDocumentType(documentType, fullPath); onChange(wrappedValue, false); } else { // For other types (records, etc.), insert directly @@ -212,7 +211,7 @@ export const DocumentConfig = ({ onChange, onClose, targetLineRange, filteredCom return; } const isTemplateMode = inputMode === InputMode.TEMPLATE; - const wrappedValue = wrapInDocumentType(documentType, `"${url.trim()}"`, isTemplateMode); + const wrappedValue = wrapInDocumentType(documentType, `"${url.trim()}"`); onChange(wrappedValue, false, false); closeModal(POPUP_IDS.DOCUMENT_URL); }; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/RecordConfigModal.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/RecordConfigModal.tsx index 677d2572d47..647f5b17484 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/RecordConfigModal.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/RecordConfigModal.tsx @@ -26,6 +26,7 @@ import { ChipExpressionEditorComponent, Context as FormContext, HelperpaneOnChan import { useForm } from "react-hook-form"; import { debounce } from "lodash"; import ReactMarkdown from "react-markdown"; +import { updateFieldsSelection } from "../Components/RecordConstructView/utils"; type ConfigureRecordPageProps = { fileName: string; @@ -142,6 +143,7 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { const { rpcClient } = useRpcContext(); const [recordModel, setRecordModel] = useState([]); + const recordModelRef = useRef([]); const [selectedMemberName, setSelectedMemberName] = useState(""); const firstRender = useRef(true); const sourceCode = useRef(currentValue); @@ -260,6 +262,7 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { } setRecordModel([recordConfig]); + recordModelRef.current = [recordConfig]; setSelectedMemberName(newRecordModel.name); } @@ -270,6 +273,23 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { await fetchRecordModelFromSource(currentValue); }; + + // Helper function to auto-select the first record in the model. + // Also selects required fields recursively within that record. + const autoSelectFirstRecord = (model: TypeField[]) => { + if (!model || model.length === 0) return; + + const recordConfig = model[0]; + + // Select the first record itself + recordConfig.selected = true; + + // If the record has fields, recursively select required fields + if (recordConfig.fields && recordConfig.fields.length > 0) { + updateFieldsSelection(recordConfig.fields as any, true); + } + }; + const getNewRecordModel = async () => { setIsLoading(true); const defaultSelection = recordTypeField.recordTypeMembers[0]; @@ -312,7 +332,15 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { ...typeFieldResponse.recordConfig } - setRecordModel([recordConfig]); + const newModel = [recordConfig]; + setRecordModel(newModel); + recordModelRef.current = newModel; + + // Auto-select the first field for new models + autoSelectFirstRecord(newModel); + + // Generate source with the auto-selected field + await handleModelChange(newModel); } setIsLoading(false); } @@ -354,7 +382,15 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { ...typeFieldResponse.recordConfig } - setRecordModel([recordConfig]); + const newModel = [recordConfig]; + setRecordModel(newModel); + recordModelRef.current = newModel; + + // Auto-select the first field when union member changes + autoSelectFirstRecord(newModel); + + // Generate source with the auto-selected field + await handleModelChange(newModel); } } @@ -523,6 +559,33 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { // Update local expression value when user edits in the ExpressionEditor setLocalExpressionValue(updatedValue); + // If the expression is empty, deselect all checkboxes + if (updatedValue.trim() === '') { + // Use ref to get the latest recordModel value + const currentRecordModel = recordModelRef.current; + // Deselect all fields in the record model + if (currentRecordModel.length > 0 && currentRecordModel[0]) { + const recordConfig = currentRecordModel[0]; + // Deselect the record itself + recordConfig.selected = false; + // Deselect all fields recursively + if (recordConfig.fields && recordConfig.fields.length > 0) { + updateFieldsSelection(recordConfig.fields as any, false); + } + // Update source code to empty to prevent sync issues + sourceCode.current = ''; + // Update latest expression ref to prevent sync + latestExpressionToSyncRef.current = ''; + // Trigger re-render by updating recordModel state with a new array reference + const updatedModel = [...currentRecordModel]; + setRecordModel(updatedModel); + recordModelRef.current = updatedModel; + } + // Clear diagnostics when expression is empty + setFormDiagnostics([]); + return; + } + // Fetch diagnostics (debounced) - this will update formDiagnostics state // The sync will be triggered by the useEffect that watches localExpressionValue fetchDiagnostics(updatedValue); @@ -585,6 +648,8 @@ export function ConfigureRecordPage(props: ConfigureRecordPageProps) { label: member.type, value: member.type }))} + sx={{ width: '100%' }} + containerSx={{ width: '100%' }} onValueChange={(value) => handleMemberChange(value)} /> diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Variables.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Variables.tsx index e115980586d..93e62e48398 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Variables.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/Views/Variables.tsx @@ -162,7 +162,7 @@ export const Variables = (props: VariablesPageProps) => { updatedNode, dataMapperMode === DataMapperDisplayMode.VIEW ? DataMapperDisplayMode.POPUP : DataMapperDisplayMode.NONE, { - closeSidePanel: false, updateLineRange: true, postUpdateCallBack: () => { + closeSidePanel: false, isChangeFromHelperPane: true, postUpdateCallBack: () => { onClose() closeModal(POPUP_IDS.VARIABLE); onChange(newNodeNameRef.current, false, true); diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/utils/utils.ts b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/utils/utils.ts index e65fd742a3b..0cbe367348d 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/utils/utils.ts +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/HelperPaneNew/utils/utils.ts @@ -19,6 +19,6 @@ import { InputMode } from "@wso2/ballerina-side-panel"; // Wraps a value in template interpolation syntax ${} if in template mode -export const wrapInTemplateInterpolation = (value: string, inputMode?: InputMode): string => { - return inputMode === InputMode.TEMPLATE ? `\${${value}}` : value; +export const wrapInTemplateInterpolation = (value: string, _inputMode?: InputMode): string => { + return value; }; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/SamplesView/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/SamplesView/index.tsx new file mode 100644 index 00000000000..7874530ab95 --- /dev/null +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/SamplesView/index.tsx @@ -0,0 +1,388 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 React, { useState, useMemo, useEffect } from "react"; +import { EVENT_TYPE, MACHINE_VIEW, SampleDownloadRequest } from "@wso2/ballerina-core"; +import { useRpcContext } from "@wso2/ballerina-rpc-client"; +import styled from "@emotion/styled"; +import { Button, Codicon, Icon, ThemeColors, Typography } from "@wso2/ui-toolkit"; +import { IconButton } from "../ImportIntegration/styles"; + + +const FormContainer = styled.div` + display: flex; + flex-direction: column; + margin: 80px 120px; +`; + +const TitleContainer = styled.div` + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 5px; +`; + +const SamplesSubtitle = styled.p` + font-size: 14px; + line-height: 1.4; + font-weight: 400; + color: var(--vscode-descriptionForeground); + margin: 0 0 24px 0; +`; + +const SearchAndFilterContainer = styled.div` + display: flex; + gap: 16px; + margin-bottom: 24px; + align-items: center; + flex-wrap: wrap; +`; + +const SearchBar = styled.div` + flex: 1; + min-width: 200px; + position: relative; + display: flex; + align-items: center; +`; + +const SearchInput = styled.input` + width: 100%; + padding: 8px 12px 8px 36px; + background: var(--vscode-input-background); + border: 1px solid var(--vscode-input-border); + border-radius: 2px; + color: var(--vscode-input-foreground); + font-size: 13px; + font-family: var(--vscode-font-family); + + &:focus { + outline: none; + border-color: var(--vscode-focusBorder); + } + + &::placeholder { + color: var(--vscode-input-placeholderForeground); + } +`; + +const SearchIcon = styled.div` + position: absolute; + left: 10px; + color: var(--vscode-input-placeholderForeground); + pointer-events: none; +`; + +const CategoryFilter = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; + +const CategoryLabel = styled.label` + font-size: 13px; + color: var(--vscode-foreground); + white-space: nowrap; +`; + +const CategorySelect = styled.select` + padding: 8px 12px; + background: var(--vscode-input-background); + border: 1px solid var(--vscode-input-border); + border-radius: 2px; + color: var(--vscode-input-foreground); + font-size: 13px; + font-family: var(--vscode-font-family); + cursor: pointer; + + &:focus { + outline: none; + border-color: var(--vscode-focusBorder); + } +`; + +const SamplesGrid = styled.div` + max-width: 1400px; + margin: 0 auto; + padding: 32px 20px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + overflow-y: auto; + max-height: calc(100vh - 300px); + min-height: 400px; + + @media (max-width: 1200px) { + grid-template-columns: repeat(3, 1fr); + } + + @media (max-width: 900px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: 600px) { + grid-template-columns: 1fr; + } +`; + +const SampleCard = styled.div` + background: var(--vscode-editor-background); + border: 1px solid var(--vscode-panel-border); + border-radius: 3px; + padding: 20px; + display: flex; + flex-direction: column; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + cursor: pointer; + min-height: 200px; + + &:hover { + border-color: ${ThemeColors.PRIMARY}; + box-shadow: 0 0 0 2px ${ThemeColors.PRIMARY_CONTAINER}; + } +`; + +interface SampleIconContainerProps { + iconColor?: string; +} + +const SampleIconContainer = styled.div` + width: 48px; + height: 48px; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 16px; + background-color: ${(props: SampleIconContainerProps) => props.iconColor || ThemeColors.SURFACE_CONTAINER}; + flex-shrink: 0; + > div { + width: unset; + height: unset; + } +`; + +const SampleCardTitle = styled.h3` + font-size: 16px; + font-weight: 600; + margin: 0 0 8px 0; + color: var(--vscode-foreground); + line-height: 1.3; +`; + +const SampleCardDescription = styled.p` + font-size: 13px; + line-height: 1.4; + margin: 0 0 16px 0; + color: var(--vscode-descriptionForeground); + flex: 1; +`; + +const SampleDownloadButton = styled(Button)` + height: 32px; + font-size: 13px; + font-weight: 400; + border-radius: 2px; + align-self: flex-start; + margin-top: auto; +`; + +interface Sample { + id: string; + category: string; + title: string; + description: string; + icon: string; + zipUrl: string; + isEnabled: boolean; +} + +// Map icon names from JSON to codicon names +const ICON_MAP: Record = { + automation: "bi-task", + ai: "bi-ai-agent", + file: "file", + api: "bi-globe", + integration: "Event", + default: "bi-globe" +}; + +// Map categories to icon colors +const CATEGORY_COLOR_MAP: Record = { + "Automation": "#4A90E2", + "File Integration": "#FF8C42", + "Integration": "#52C41A", + "AI Agent": "#9C27B0", + "Integration as API": "#00BCD4", + "Default": "#4A90E2" +}; + +export function SamplesView() { + const { rpcClient } = useRpcContext(); + const [searchQuery, setSearchQuery] = useState(""); + const [selectedCategory, setSelectedCategory] = useState("All"); + const [samples, setSamples] = useState([]); + const [isLoadingSamples, setIsLoadingSamples] = useState(true); + const [samplesError, setSamplesError] = useState(null); + + // Fetch samples from GitHub + useEffect(() => { + const fetchSamples = async () => { + try { + setIsLoadingSamples(true); + setSamplesError(null); + const response = await fetch( + "https://raw.githubusercontent.com/wso2/integration-samples/refs/heads/main/ballerina-integrator/samples/meta.json" + ); + if (!response.ok) { + throw new Error(`Failed to fetch samples at the moment. Please try again later.`); + } + const data: Sample[] = await response.json(); + // Filter only enabled samples + const enabledSamples = data.filter((sample) => sample.isEnabled); + setSamples(enabledSamples); + } catch (error) { + rpcClient.getCommonRpcClient().openExternalUrl({ + url: "https://bi.docs.wso2.com/integration-guides/integration-as-api/message-transformation/", + }); + console.error("Error fetching samples:", error); + setSamplesError(error instanceof Error ? error.message : "Failed to load samples"); + } finally { + setIsLoadingSamples(false); + } + }; + + fetchSamples(); + }, [rpcClient]); + + const categories = useMemo(() => { + const uniqueCategories = Array.from(new Set(samples.map((s) => s.category))); + return ["All", ...uniqueCategories]; + }, [samples]); + + const filteredSamples = useMemo(() => { + return samples.filter((sample) => { + const matchesSearch = + sample.title.toLowerCase().includes(searchQuery.toLowerCase()) || + sample.description.toLowerCase().includes(searchQuery.toLowerCase()); + const matchesCategory = selectedCategory === "All" || sample.category === selectedCategory; + return matchesSearch && matchesCategory; + }); + }, [searchQuery, selectedCategory, samples]); + + const handleDownload = async (sampleId: string) => { + try { + const request: SampleDownloadRequest = { + zipFileName: sampleId + }; + await rpcClient.getCommonRpcClient().downloadSelectedSampleFromGithub(request); + } catch (error) { + console.error("Error downloading sample:", error); + rpcClient.getCommonRpcClient().showErrorMessage({ + message: `Error while downloading the sample: ${error instanceof Error ? error.message : String(error)}` + }); + } + }; + + const handleBack = () => { + rpcClient.getVisualizerRpcClient().openView({ + type: EVENT_TYPE.OPEN_VIEW, + location: { + view: MACHINE_VIEW.BIWelcome, + }, + }); + }; + + return ( + + + + + + Samples + + Choose a sample from the list below to get started. + + + + + + + setSearchQuery(e.target.value)} + /> + + + Category: + setSelectedCategory(e.target.value)} + > + {categories.map((category) => ( + + ))} + + + + + {isLoadingSamples ? ( +
+ Loading samples... +
+ ) : samplesError ? ( +
+ {samplesError} +
+ ) : filteredSamples.length === 0 ? ( +
+ No samples found matching your search criteria. +
+ ) : ( + + {filteredSamples.map((sample) => { + const iconName = ICON_MAP[sample.icon] || ICON_MAP.default; + const iconColor = CATEGORY_COLOR_MAP[sample.category] || CATEGORY_COLOR_MAP.Default; + return ( + handleDownload(sample.id)}> + + + + {sample.title} + {sample.description} + { + e.stopPropagation(); + handleDownload(sample.id); + }} + > + Download + + + ); + })} + + )} +
+ ); +} diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/BI/WelcomeView/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/BI/WelcomeView/index.tsx index 0f910f22e9c..c4449f331aa 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/BI/WelcomeView/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/BI/WelcomeView/index.tsx @@ -107,8 +107,8 @@ const ActionCard = styled.div` &:hover { ${(props: ActionCardProps) => - !props.disabled && - ` + !props.disabled && + ` border-color: ${ThemeColors.PRIMARY}; box-shadow: 0 0 0 2px ${ThemeColors.PRIMARY_CONTAINER}; `} @@ -255,8 +255,11 @@ export function WelcomeView(props: WelcomeViewProps) { }; const openSamples = () => { - rpcClient.getCommonRpcClient().openExternalUrl({ - url: "https://bi.docs.wso2.com/integration-guides/integration-as-api/message-transformation/", + rpcClient.getVisualizerRpcClient().openView({ + type: EVENT_TYPE.OPEN_VIEW, + location: { + view: MACHINE_VIEW.BISamplesView, + }, }); }; diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx index 9456770b65d..3fd223d4053 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/DataMapperView.tsx @@ -43,7 +43,9 @@ import { MACHINE_VIEW, VisualizerLocation, DeleteClauseRequest, - IORoot + IORoot, + IntermediateClauseType, + TriggerKind } from "@wso2/ballerina-core"; import { CompletionItem, ProgressIndicator } from "@wso2/ui-toolkit"; import { useRpcContext } from "@wso2/ballerina-rpc-client"; @@ -284,6 +286,7 @@ export function DataMapperView(props: DataMapperProps) { fileName={filePath} preserveFieldOrder={true} helperPaneSide="left" + isDataMapperEditor={true} {...formProps} /> ) @@ -359,6 +362,25 @@ export function DataMapperView(props: DataMapperProps) { } } + const getClausePosition = async (targetField: string, index: number) => { + try { + const { position } = await rpcClient.getDataMapperRpcClient().getClausePosition({ + filePath, + codedata: viewState.codedata, + targetField: targetField, + index: index + }); + if (position) { + return position; + } else { + throw new Error("Clause position not found"); + } + } catch (error) { + console.error(error); + return { line: 0, offset: 0 }; + } + } + const addSubMapping = async ( subMappingName: string, type: string, @@ -491,13 +513,12 @@ export function DataMapperView(props: DataMapperProps) { }; const goToSource = async (outputId: string, viewId: string) => { - const { property } = await rpcClient.getDataMapperRpcClient().getProperty({ + const { property } = await rpcClient.getDataMapperRpcClient().getFieldProperty({ filePath, codedata: viewState.codedata, - propertyKey: "expression", // TODO: Remove this once the API is updated targetField: viewId, fieldId: outputId, - }) + }); if (property.codedata) { const position: NodePosition = { startLine: property.codedata.lineRange?.startLine?.line, @@ -526,11 +547,45 @@ export function DataMapperView(props: DataMapperProps) { parentField.isDeepNested = false; } + const genUniqueName = async (name: string, viewId: string): Promise => { + const { property } = await rpcClient.getDataMapperRpcClient().getProperty({ + filePath, + codedata: viewState.codedata, + targetField: viewId + }) + if (!property?.codedata?.lineRange?.startLine) { + console.error("Failed to get start line for generating unique name"); + return name; + } + + const completions = await rpcClient.getBIDiagramRpcClient().getDataMapperCompletions({ + filePath, + context: { + expression: "", + startLine: property.codedata.lineRange.startLine, + lineOffset: 0, + offset: 0, + codedata: viewState.codedata, + property: property + }, + completionContext: { + triggerKind: TriggerKind.INVOKED + } + }); + + let i = 2; + let uniqueName = name; + while (completions.some(c => c.insertText === uniqueName)) { + uniqueName = name + (i++); + } + + return uniqueName; + }; const onDMClose = () => { onClose ? onClose() : rpcClient.getVisualizerRpcClient()?.goBack(); - } + }; const onDMRefresh = async () => { try { @@ -544,13 +599,6 @@ export function DataMapperView(props: DataMapperProps) { await refreshDMModel(); }; - const onDMReset = async () => { - await deleteMapping( - { output: name, expression: undefined }, - name - ); - }; - const onEdit = () => { const context: VisualizerLocation = { view: MACHINE_VIEW.BIDataMapperForm, @@ -559,7 +607,7 @@ export function DataMapperView(props: DataMapperProps) { }; rpcClient.getVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: context }); - } + }; useEffect(() => { @@ -592,13 +640,11 @@ export function DataMapperView(props: DataMapperProps) { const { property } = await rpcClient.getDataMapperRpcClient().getProperty({ filePath, codedata: viewState.codedata, - propertyKey: "expression", // TODO: Remove this once the API is updated - targetField: viewId, - fieldId: outputId, + targetField: viewId }) const { lineOffset, charOffset } = calculateExpressionOffsets(value, cursorPosition); - const startLine = updateLineRange(codedata.lineRange, expressionOffsetRef.current).startLine; - let completions = await rpcClient.getBIDiagramRpcClient().getExpressionCompletions({ + const startLine = updateLineRange(property.codedata.lineRange, expressionOffsetRef.current).startLine; + let completions = await rpcClient.getBIDiagramRpcClient().getDataMapperCompletions({ filePath, context: { expression: value, @@ -606,10 +652,10 @@ export function DataMapperView(props: DataMapperProps) { lineOffset: lineOffset, offset: charOffset, codedata: viewState.codedata, - property: { ...property, valueType: "DATA_MAPPING_EXPRESSION" } + property: property }, completionContext: { - triggerKind: triggerCharacter ? 2 : 1, + triggerKind: triggerCharacter ? TriggerKind.TRIGGER_CHARACTER : TriggerKind.INVOKED, triggerCharacter: triggerCharacter as TriggerCharacter } }); @@ -679,7 +725,6 @@ export function DataMapperView(props: DataMapperProps) { reusable={reusable} onClose={onDMClose} onRefresh={onDMRefresh} - onReset={onDMReset} onEdit={reusable ? onEdit : undefined} applyModifications={updateExpression} addArrayElement={addArrayElement} @@ -688,6 +733,7 @@ export function DataMapperView(props: DataMapperProps) { convertToQuery={convertToQuery} addClauses={addClauses} deleteClause={deleteClause} + getClausePosition={getClausePosition} addSubMapping={addSubMapping} deleteMapping={deleteMapping} deleteSubMapping={deleteSubMapping} @@ -695,6 +741,7 @@ export function DataMapperView(props: DataMapperProps) { mapWithTransformFn={mapWithTransformFn} goToFunction={goToFunction} enrichChildFields={enrichChildFields} + genUniqueName={genUniqueName} undoRedoGroup={undoRedoGroup} expressionBar={{ completions: filteredCompletions, @@ -714,7 +761,13 @@ export function DataMapperView(props: DataMapperProps) { }; const getModelSignature = (model: DMModel | ExpandedDMModel): ModelSignature => ({ - inputs: [...model.inputs.map(i => i.name), ...(model.query?.inputs || [])], + inputs: [...model.inputs.map(i => i.name), + ...(model.query?.inputs || []), + ...(model.query?.intermediateClauses + ?.filter((clause) => (clause.type === IntermediateClauseType.LET || clause.type === IntermediateClauseType.GROUP_BY)) + .map(clause => `${clause.properties.type} ${clause.properties.name} ${clause.properties.expression}`) + || []) + ], output: model.output.name, subMappings: model.subMappings?.map(s => (s as IORoot | IOType).name) || [], refs: 'refs' in model ? JSON.stringify(model.refs) : '' diff --git a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/index.tsx b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/index.tsx index e2bd80dcfdf..216c0cb23a7 100644 --- a/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/index.tsx +++ b/workspaces/ballerina/ballerina-visualizer/src/views/DataMapper/index.tsx @@ -23,6 +23,7 @@ import { ErrorBoundary } from "@wso2/ui-toolkit"; import { TopNavigationBar } from "../../components/TopNavigationBar"; import { DataMapperView } from "./DataMapperView"; +import { BALLERINA_INTEGRATOR_ISSUES_URL } from "../../utils/bi"; export interface DataMapperProps { filePath: string; @@ -38,7 +39,7 @@ export function DataMapper(props: DataMapperProps) { return ( <> - + diff --git a/workspaces/ballerina/component-diagram/src/components/nodes/ConnectionNode/ConnectionNodeWidget.tsx b/workspaces/ballerina/component-diagram/src/components/nodes/ConnectionNode/ConnectionNodeWidget.tsx index 9dad8e2f8ed..115b4ecc113 100644 --- a/workspaces/ballerina/component-diagram/src/components/nodes/ConnectionNode/ConnectionNodeWidget.tsx +++ b/workspaces/ballerina/component-diagram/src/components/nodes/ConnectionNode/ConnectionNodeWidget.tsx @@ -164,6 +164,14 @@ export function ConnectionNodeWidget(props: ConnectionNodeWidgetProps) { setMenuAnchorEl(null); }; + const handleMenuMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMenuMouseUp = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + const getNodeTitle = () => { return model.node.symbol; }; @@ -199,7 +207,12 @@ export function ConnectionNodeWidget(props: ConnectionNodeWidgetProps) { {getNodeTitle()} {getNodeDescription()} - + diff --git a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/AIServiceWidget.tsx b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/AIServiceWidget.tsx index 0ef835f0750..3a9fe32b58b 100644 --- a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/AIServiceWidget.tsx +++ b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/AIServiceWidget.tsx @@ -81,6 +81,14 @@ export function AIServiceWidget({ model, engine }: BaseNodeWidgetProps) { setMenuAnchorEl(null); }; + const handleMenuMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMenuMouseUp = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + const menuItems: Item[] = [ { id: "edit", label: "Edit", onClick: () => handleOnClick() }, { id: "delete", label: "Delete", onClick: () => onDeleteComponent(model.node) }, @@ -101,7 +109,12 @@ export function AIServiceWidget({ model, engine }: BaseNodeWidgetProps) { {getNodeTitle(model)} {getNodeDescription(model)} - + 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 5e24186426a..128d13e62ed 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 @@ -197,6 +197,14 @@ export function GeneralServiceWidget({ model, engine }: BaseNodeWidgetProps) { setMenuAnchorEl(null); }; + const handleMenuMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMenuMouseUp = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + const menuItems: Item[] = [ { id: "edit", label: "Edit", onClick: () => handleOnClick() }, { id: "delete", label: "Delete", onClick: () => onDeleteComponent(model.node) }, @@ -251,7 +259,12 @@ export function GeneralServiceWidget({ model, engine }: BaseNodeWidgetProps) { {getNodeTitle(model)} {getNodeDescription(model)} - + diff --git a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx index 9b9cfa21ee9..d55833bdba0 100644 --- a/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx +++ b/workspaces/ballerina/component-diagram/src/components/nodes/EntryNode/components/GraphQLServiceWidget.tsx @@ -191,6 +191,14 @@ export function GraphQLServiceWidget({ model, engine }: BaseNodeWidgetProps) { setMenuAnchorEl(null); }; + const handleMenuMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMenuMouseUp = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + const menuItems: Item[] = [ { id: "edit", label: "Edit", onClick: () => handleOnClick() }, { id: "delete", label: "Delete", onClick: () => onDeleteComponent(model.node) }, @@ -245,7 +253,12 @@ export function GraphQLServiceWidget({ model, engine }: BaseNodeWidgetProps) { {getNodeTitle(model)} {getNodeDescription(model)} - + diff --git a/workspaces/ballerina/component-diagram/src/components/nodes/ListenerNode/ListenerNodeWidget.tsx b/workspaces/ballerina/component-diagram/src/components/nodes/ListenerNode/ListenerNodeWidget.tsx index 35bd8a204e1..0441df85f7e 100644 --- a/workspaces/ballerina/component-diagram/src/components/nodes/ListenerNode/ListenerNodeWidget.tsx +++ b/workspaces/ballerina/component-diagram/src/components/nodes/ListenerNode/ListenerNodeWidget.tsx @@ -174,6 +174,14 @@ export function ListenerNodeWidget(props: ListenerNodeWidgetProps) { setMenuAnchorEl(null); }; + const handleMenuMouseDown = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + + const handleMenuMouseUp = (event: React.MouseEvent) => { + event.stopPropagation(); + }; + const menuItems: Item[] = [ { id: "edit", label: "Edit", onClick: () => handleOnClick() }, @@ -196,7 +204,12 @@ export function ListenerNodeWidget(props: ListenerNodeWidgetProps) { - +
diff --git a/workspaces/ballerina/component-diagram/src/utils/diagram.ts b/workspaces/ballerina/component-diagram/src/utils/diagram.ts index 0bde6be9e87..51ee6666b2d 100644 --- a/workspaces/ballerina/component-diagram/src/utils/diagram.ts +++ b/workspaces/ballerina/component-diagram/src/utils/diagram.ts @@ -24,7 +24,7 @@ import { NodeModel } from "./types"; import { EntryNodeFactory, EntryNodeModel } from "../components/nodes/EntryNode"; import { ConnectionNodeFactory } from "../components/nodes/ConnectionNode/ConnectionNodeFactory"; import { ListenerNodeFactory } from "../components/nodes/ListenerNode/ListenerNodeFactory"; -import { LISTENER_NODE_WIDTH, NodeTypes, NODE_GAP_X, ENTRY_NODE_WIDTH } from "../resources/constants"; +import { LISTENER_NODE_WIDTH, NodeTypes, NODE_GAP_X, ENTRY_NODE_WIDTH, NODE_GAP_Y, LISTENER_NODE_HEIGHT } from "../resources/constants"; import { ListenerNodeModel } from "../components/nodes/ListenerNode"; import { ConnectionNodeModel } from "../components/nodes/ConnectionNode"; import { CDConnection, CDResourceFunction, CDFunction, CDService } from "@wso2/ballerina-core"; @@ -64,16 +64,26 @@ export function autoDistribute(engine: DiagramEngine) { const entryX = listenerX + LISTENER_NODE_WIDTH + NODE_GAP_X; const connectionX = entryX + ENTRY_NODE_WIDTH + NODE_GAP_X; - // Position listeners while maintaining relative Y positions of their services + // Separate listeners into connected and unconnected + const connectedListeners: ListenerNodeModel[] = []; + const unconnectedListeners: ListenerNodeModel[] = []; + listenerNodes.forEach((node) => { const listenerNode = node as ListenerNodeModel; const attachedServices = listenerNode.node.attachedServices; - // Find the average Y position of attached services + // Find the attached service nodes const serviceNodes = entryNodes.filter((n) => attachedServices.includes(n.getID())); - const avgY = serviceNodes.reduce((sum, n) => sum + n.getY(), 0) / serviceNodes.length; - listenerNode.setPosition(listenerX, avgY); + if (serviceNodes.length > 0) { + // Has attached services - position at average Y of services + const avgY = serviceNodes.reduce((sum, n) => sum + n.getY(), 0) / serviceNodes.length; + listenerNode.setPosition(listenerX, avgY); + connectedListeners.push(listenerNode); + } else { + // No attached services - will position later + unconnectedListeners.push(listenerNode); + } }); // Update X positions for entry nodes while keeping their Y positions @@ -88,6 +98,26 @@ export function autoDistribute(engine: DiagramEngine) { connectionNode.setPosition(connectionX, node.getY()); }); + // Position unconnected listeners below all other nodes + if (unconnectedListeners.length > 0) { + // Find the maximum Y position among all nodes + const allNodes = [...connectedListeners, ...entryNodes, ...connectionNodes]; + let maxY = 100; // Default starting position if no other nodes + + if (allNodes.length > 0) { + maxY = Math.max(...allNodes.map(node => { + const nodeHeight = node.height || LISTENER_NODE_HEIGHT; + return node.getY() + nodeHeight; + })); + } + + // Position unconnected listeners below, with spacing + unconnectedListeners.forEach((listenerNode, index) => { + const yPosition = maxY + NODE_GAP_Y/2 + (index * (LISTENER_NODE_HEIGHT + NODE_GAP_Y/2)); + listenerNode.setPosition(listenerX, yPosition); + }); + } + engine.repaintCanvas(); } diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx index d0a73bd940e..74a8ad3cba2 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/DataMapperEditor.tsx @@ -128,7 +128,6 @@ export function DataMapperEditor(props: DataMapperEditorProps) { applyModifications, onClose, onRefresh, - onReset, onEdit, addArrayElement, handleView, @@ -139,10 +138,12 @@ export function DataMapperEditor(props: DataMapperEditorProps) { generateForm, addClauses, deleteClause, + getClausePosition, mapWithCustomFn, mapWithTransformFn, goToFunction, enrichChildFields, + genUniqueName, undoRedoGroup } = props; const { @@ -190,6 +191,19 @@ export function DataMapperEditor(props: DataMapperEditorProps) { dispatch({ type: ActionType.RESET_VIEW, payload: { view: newData } }); }, [resetSearchStore]); + const handleOnReset = useCallback(async () => { + const targetField = views[views.length - 1].targetField; + const outputIds = targetField.split('.'); + + let output: string; + while ((output = outputIds.pop()) === '0'); + + await deleteMapping( + { output, expression: undefined }, + targetField + ); + }, [views, deleteMapping]); + useEffect(() => { const lastView = views[views.length - 1]; handleView(lastView.targetField, !!lastView?.subMappingInfo); @@ -235,10 +249,12 @@ export function DataMapperEditor(props: DataMapperEditorProps) { convertToQuery, deleteMapping, deleteSubMapping, + addClauses, mapWithCustomFn, mapWithTransformFn, goToFunction, - enrichChildFields + enrichChildFields, + genUniqueName ); const ioNodeInitVisitor = new IONodeInitVisitor(context); @@ -334,7 +350,7 @@ export function DataMapperEditor(props: DataMapperEditorProps) { onClose={handleOnClose} onBack={handleOnBack} onRefresh={onRefresh} - onReset={onReset} + onReset={handleOnReset} onEdit={onEdit} autoMapWithAI={autoMapWithAI} undoRedoGroup={undoRedoGroup} @@ -361,7 +377,9 @@ export function DataMapperEditor(props: DataMapperEditorProps) { targetField={views[views.length - 1].targetField} addClauses={addClauses} deleteClause={deleteClause} + getClausePosition={getClausePosition} generateForm={generateForm} + genUniqueName={genUniqueName} /> )} diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx index bbbaf3954a8..a1b6904c423 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/DataMapperHeader.tsx @@ -52,7 +52,7 @@ export function DataMapperHeader(props: DataMapperHeaderProps) { return ( - + @@ -67,12 +67,16 @@ export function DataMapperHeader(props: DataMapperHeaderProps) { - {undoRedoGroup && undoRedoGroup()} + @@ -132,6 +136,7 @@ const RightContainer = styled.div<{ isClickable: boolean }>` const ActionGroupContaner = styled.div` display: flex; + gap: 2px; `; const BreadCrumb = styled.div` diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx index 0bc8c67ccc8..ac280863179 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/Header/ExpressionBar.tsx @@ -110,21 +110,26 @@ export default function ExpressionBarWrapper({ views }: ExpressionBarProps) { if (inputPort) { // Keep the text field focused when an input port is selected if (textFieldRef.current) { + if (focusedPort || focusedFilter) { - textFieldRef.current.focus(true); + // Update the expression text when an input port is selected + const cursorPosition = textFieldRef.current.inputElement.selectionStart; + + const inputAccessExpr = buildInputAccessExpr(inputPort.attributes.fieldFQN); + const updatedText = + textFieldValue.substring(0, cursorPosition) + + inputAccessExpr + + textFieldValue.substring(cursorPosition); + await handleChange(updatedText); + + textFieldRef.current.setCursor(updatedText, cursorPosition + inputAccessExpr.length); + } else { textFieldRef.current.blur(); } - - // Update the expression text when an input port is selected - const cursorPosition = textFieldRef.current.shadowRoot.querySelector('input').selectionStart; - const inputAccessExpr = buildInputAccessExpr(inputPort.attributes.fieldFQN); - const updatedText = - textFieldValue.substring(0, cursorPosition) + - inputAccessExpr + - textFieldValue.substring(cursorPosition); - await handleChange(updatedText); + resetInputPort(); + } } })(); @@ -161,7 +166,7 @@ export default function ExpressionBarWrapper({ views }: ExpressionBarProps) { return disabled; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [textFieldRef.current, focusedPort, focusedFilter, views]); + }, [focusedPort, focusedFilter, views]); const handleChange = async (text: string, cursorPosition?: number) => { if (textFieldValue === text) { diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx index 75cb3a1ba3a..1fd5357823a 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseEditor.tsx @@ -17,33 +17,37 @@ */ import React from "react"; -import { EditorContainer } from "./styles"; -import { Divider, Dropdown, OptionProps, Typography } from "@wso2/ui-toolkit"; -import { DMFormProps, DMFormField, DMFormFieldValues, IntermediateClauseType, IntermediateClause, IntermediateClauseProps } from "@wso2/ballerina-core"; +import { EditorContainer, ProgressRingWrapper } from "./styles"; +import { Divider, Dropdown, OptionProps, ProgressRing, Typography } from "@wso2/ui-toolkit"; +import { DMFormProps, DMFormField, DMFormFieldValues, IntermediateClauseType, IntermediateClause, IntermediateClauseProps, LinePosition } from "@wso2/ballerina-core"; import { useDMQueryClausesPanelStore } from "../../../../store/store"; +import { useQuery } from "@tanstack/react-query"; export interface ClauseEditorProps { + index: number; + targetField: string; clause?: IntermediateClause; onSubmitText?: string; isSaving: boolean; onSubmit: (clause: IntermediateClause) => void; onCancel: () => void; + getClausePosition: (targetField: string, index: number) => Promise; generateForm: (formProps: DMFormProps) => JSX.Element; } export function ClauseEditor(props: ClauseEditorProps) { - const { clause, onSubmitText, isSaving, onSubmit, onCancel, generateForm } = props; + const { index, targetField, clause, onSubmitText, isSaving, onSubmit, onCancel, getClausePosition, generateForm } = props; const { clauseToAdd, setClauseToAdd } = useDMQueryClausesPanelStore.getState(); const { type: _clauseType, properties: clauseProps } = clause ?? clauseToAdd ?? {}; const [clauseType, setClauseType] = React.useState(_clauseType ?? IntermediateClauseType.WHERE); const clauseTypeItems: OptionProps[] = [ - { content: "condition", value: IntermediateClauseType.WHERE }, - { content: "local variable", value: IntermediateClauseType.LET }, - { content: "sort by", value: IntermediateClauseType.ORDER_BY }, - { content: "limit", value: IntermediateClauseType.LIMIT }, - { content: "from", value: IntermediateClauseType.FROM }, - { content: "join", value: IntermediateClauseType.JOIN }, + { content: "Condition", value: IntermediateClauseType.WHERE }, + { content: "Local variable", value: IntermediateClauseType.LET }, + { content: "Sort by", value: IntermediateClauseType.ORDER_BY }, + { content: "Limit", value: IntermediateClauseType.LIMIT }, + { content: "From", value: IntermediateClauseType.FROM }, + { content: "Join", value: IntermediateClauseType.JOIN } ] const nameField: DMFormField = { @@ -72,11 +76,15 @@ export function ClauseEditor(props: ClauseEditorProps) { const expressionField: DMFormField = { key: "expression", - label: clauseType === IntermediateClauseType.JOIN ? "Join With Collection" : "Expression", + label: clauseType === IntermediateClauseType.JOIN ? "Join With Collection" : + clauseType === IntermediateClauseType.GROUP_BY ? "Grouping Key" : + "Expression", type: "EXPRESSION", optional: false, editable: true, - documentation: clauseType === IntermediateClauseType.JOIN ? "Collection to be joined" : "Enter the expression of the clause", + documentation: clauseType === IntermediateClauseType.JOIN ? "Collection to be joined" : + clauseType === IntermediateClauseType.GROUP_BY ? "Enter the grouping key expression" : + "Enter the expression of the clause", value: clauseProps?.expression ?? "", valueTypeConstraint: "Global", enabled: true, @@ -110,7 +118,7 @@ export function ClauseEditor(props: ClauseEditorProps) { const rhsExpressionField: DMFormField = { key: "rhsExpression", label: "RHS Expression", - type: "EXPRESSION", + type: "DM_JOIN_CLAUSE_RHS_EXPRESSION", optional: false, editable: true, documentation: "Enter the RHS expression of join-on condition", @@ -125,10 +133,6 @@ export function ClauseEditor(props: ClauseEditorProps) { type: clauseType as IntermediateClauseType, properties: data as IntermediateClauseProps }; - if (clauseType === IntermediateClauseType.JOIN) { - clause.properties.type = "var"; - clause.properties.isOuter = false; - } onSubmit(clause); } @@ -147,13 +151,24 @@ export function ClauseEditor(props: ClauseEditorProps) { return [expressionField, orderField]; case IntermediateClauseType.JOIN: return [expressionField, nameField, lhsExpressionField, rhsExpressionField]; + case IntermediateClauseType.GROUP_BY: + return [expressionField]; default: return [expressionField]; } } + const { + data: clausePosition, + isFetching: isFetchingTargetLineRange + } = useQuery({ + queryKey: ['getClausePosition', targetField, index], + queryFn: async () => await getClausePosition(targetField, index), + networkMode: 'always' + }); + const formProps: DMFormProps = { - targetLineRange:{ startLine: { line: 0, offset: 0 }, endLine: { line: 0, offset: 0 } }, + targetLineRange: { startLine: clausePosition, endLine: clausePosition }, fields: generateFields(), submitText: onSubmitText || "Add", cancelText: "Cancel", @@ -179,7 +194,12 @@ export function ClauseEditor(props: ClauseEditorProps) { value={clauseType} /> - {generateForm(formProps)} + {isFetchingTargetLineRange ? + + + : + generateForm(formProps) + } ); diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseItem.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseItem.tsx index 58792dd89a5..ecd0eab0bf0 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseItem.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClauseItem.tsx @@ -34,11 +34,12 @@ import { } from "./styles"; import { Button, Codicon, ProgressRing } from "@wso2/ui-toolkit"; import { ClauseEditor } from "./ClauseEditor"; -import { DMFormProps, IntermediateClause, IntermediateClauseType } from "@wso2/ballerina-core"; +import { DMFormProps, IntermediateClause, IntermediateClauseType, LinePosition } from "@wso2/ballerina-core"; import { set } from "lodash"; export interface ClauseItemProps { index: number; + targetField: string; clause: IntermediateClause; isSaving: boolean; isAdding: boolean; @@ -49,11 +50,12 @@ export interface ClauseItemProps { onAdd: (clause: IntermediateClause, index?: number) => void; onEdit: (clause: IntermediateClause, index: number) => void; onDelete: (index: number) => void; + getClausePosition: (targetField: string, index: number) => Promise; generateForm: (formProps: DMFormProps) => JSX.Element; } export function ClauseItem(props: ClauseItemProps) { - const { index, clause, isSaving, isAdding, isEditing, isDeleting, setAdding, setEditing, onDelete, onEdit, onAdd, generateForm } = props; + const { index, targetField, clause, isSaving, isAdding, isEditing, isDeleting, setAdding, setEditing, onDelete, onEdit, onAdd, getClausePosition, generateForm } = props; const { type: clauseType, properties: clauseProps } = clause; @@ -104,20 +106,26 @@ export function ClauseItem(props: ClauseItemProps) { {isEditing && ( setEditing(undefined)} + getClausePosition={getClausePosition} generateForm={generateForm} /> )} {isAdding ? ( setAdding(undefined)} onSubmit={onHandleAdd} + getClausePosition={getClausePosition} generateForm={generateForm} /> ) : ( setAdding(index)} /> diff --git a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx index 46042de03a0..4826a1af99f 100644 --- a/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx +++ b/workspaces/ballerina/data-mapper/src/components/DataMapper/SidePanel/QueryClauses/ClausesPanel.tsx @@ -23,20 +23,22 @@ import { useDMQueryClausesPanelStore } from "../../../../store/store"; import { AddButton, ClauseItem } from "./ClauseItem"; import { ClauseEditor } from "./ClauseEditor"; import { ClauseItemListContainer } from "./styles"; -import { DMFormProps, IntermediateClause, Query } from "@wso2/ballerina-core"; +import { DMFormProps, IntermediateClause, IntermediateClauseType, LinePosition, Query } from "@wso2/ballerina-core"; export interface ClausesPanelProps { query: Query; targetField: string; addClauses: (clause: IntermediateClause, targetField: string, isNew: boolean, index:number) => Promise; deleteClause: (targetField: string, index: number) => Promise; + getClausePosition: (targetField: string, index: number) => Promise; generateForm: (formProps: DMFormProps) => JSX.Element; + genUniqueName: (name: string, viewId: string) => Promise; } export function ClausesPanel(props: ClausesPanelProps) { const { isQueryClausesPanelOpen, setIsQueryClausesPanelOpen } = useDMQueryClausesPanelStore(); const { clauseToAdd, setClauseToAdd } = useDMQueryClausesPanelStore.getState(); - const { query, targetField, addClauses, deleteClause, generateForm } = props; + const { query, targetField, addClauses, deleteClause, getClausePosition, generateForm , genUniqueName} = props; const [adding, setAdding] = React.useState(); const [editing, setEditing] = React.useState(); @@ -45,8 +47,20 @@ export function ClausesPanel(props: ClausesPanelProps) { const clauses = query?.intermediateClauses || []; + const fillDefaults = async (clause: IntermediateClause) => { + const clauseType = clause.type; + if (clauseType === IntermediateClauseType.JOIN) { + clause.properties.type = "var"; + clause.properties.isOuter = false; + } else if (clauseType === IntermediateClauseType.GROUP_BY) { + clause.properties.type = "var"; + clause.properties.name = await genUniqueName(clause.properties.expression.split('.').pop(), targetField); + } + }; + const setClauses = async (clause: IntermediateClause, isNew: boolean, index: number) => { setSaving(index); + await fillDefaults(clause); await addClauses(clause, targetField, isNew, index); setSaving(undefined); } @@ -104,9 +118,12 @@ export function ClausesPanel(props: ClausesPanelProps) { {adding === -1 ? ( setAdding(undefined)} onSubmit={onAdd} + getClausePosition={getClausePosition} generateForm={generateForm} /> ) : ( @@ -118,6 +135,7 @@ export function ClausesPanel(props: ClausesPanelProps) { ))} - ); diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx b/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx index 60f751c51d8..ab9b48985cb 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Label/MappingOptionsWidget.tsx @@ -17,7 +17,7 @@ */ // tslint:disable: jsx-no-multiline-js -import React from 'react'; +import React, { useMemo } from 'react'; import { ResultClauseType, TypeKind } from '@wso2/ballerina-core'; import { Codicon, Item, Menu, MenuItem, ProgressRing } from '@wso2/ui-toolkit'; @@ -25,9 +25,11 @@ import { css } from '@emotion/css'; import { MappingType } from '../Link'; import { ExpressionLabelModel } from './ExpressionLabelModel'; -import { createNewMapping, mapWithCustomFn, mapWithQuery, mapWithTransformFn } from '../utils/modification-utils'; +import { createNewMapping, mapSeqToX, mapWithCustomFn, mapWithQuery, mapWithTransformFn } from '../utils/modification-utils'; import classNames from 'classnames'; import { genArrayElementAccessSuffix } from '../utils/common-utils'; +import { InputOutputPortModel } from '../Port'; +import { getGenericTypeKind, isNumericType, isPrimitive } from '../utils/type-utils'; export const useStyles = () => ({ arrayMappingMenu: css({ @@ -95,112 +97,161 @@ export function MappingOptionsWidget(props: MappingOptionsWidgetProps) { const pendingMappingType = link.pendingMappingType; const [inProgress, setInProgress] = React.useState(false); - const wrapWithProgress = (onClick: () => Promise) => { - return async () => { - setInProgress(true); - await onClick(); + + const menuItems: Item[] = useMemo(() => { + const wrapWithProgress = (onClick: () => Promise) => { + return async () => { + setInProgress(true); + await onClick(); + } + }; + + const onClickMapDirectly = async () => { + await createNewMapping(link); } - }; - const onClickMapDirectly = async () => { - await createNewMapping(link); - } - - const onClickMapIndividualElements = async () => { - await mapWithQuery(link, ResultClauseType.SELECT, context); - }; - - const onClickMapArraysAccessSingleton = async () => { - await createNewMapping(link, (expr: string) => `${expr}${genArrayElementAccessSuffix(link)}`); - }; - - const onClickAggregateArray = async () => { - await mapWithQuery(link, ResultClauseType.COLLECT, context); - }; - - const onClickMapWithCustomFn = async () => { - await mapWithCustomFn(link, context); - }; - - const onClickMapWithTransformFn = async () => { - await mapWithTransformFn(link, context); - } - - const onClickMapWithAggregateFn = async (fn: string) => { - await createNewMapping(link, (expr: string) => `${fn}(${expr})`); - } - - const getItemElement = (id: string, label: string) => { - return ( -
- - {label} -
- ); - } - - const a2aMenuItems: Item[] = [ - { - id: "a2a-direct", - label: getItemElement("a2a-direct", "Map Input Array to Output Array"), - onClick: wrapWithProgress(onClickMapDirectly) - }, - { - id: "a2a-inner", - label: getItemElement("a2a-inner", "Map Array Elements Individually"), - onClick: wrapWithProgress(onClickMapIndividualElements) + const onClickMapIndividualElements = async () => { + await mapWithQuery(link, ResultClauseType.SELECT, context); + }; + + const onClickMapArraysAccessSingleton = async () => { + await createNewMapping(link, (expr: string) => `${expr}${genArrayElementAccessSuffix(link)}`); + }; + + const onClickAggregateArray = async () => { + await mapWithQuery(link, ResultClauseType.COLLECT, context); + }; + + const onClickMapWithCustomFn = async () => { + await mapWithCustomFn(link, context); + }; + + const onClickMapWithTransformFn = async () => { + await mapWithTransformFn(link, context); } - ]; - - const a2sMenuItems: Item[] = [ - { - id: "a2s-direct", - label: getItemElement("a2s-direct", "Extract Single Element from Array"), - onClick: wrapWithProgress(onClickMapArraysAccessSingleton) + + const onClickMapWithAggregateFn = async (fn: string) => { + await createNewMapping(link, (expr: string) => `${fn}(${expr})`); } - ]; - - const aggregateFns = ["sum", "avg", "min", "max", "count"]; - const a2sAggregateItems: Item[] = aggregateFns.map((fn) => ({ - id: `a2s-collect-${fn}`, - label: getItemElement(`a2s-collect-${fn}`, `Aggregate using ${fn}`), - onClick: wrapWithProgress(async () => await onClickMapWithAggregateFn(fn)) - })); - - const defaultMenuItems: Item[] = [ - { - id: "a2a-direct", - label: getItemElement("direct", "Map Anyway"), - onClick: wrapWithProgress(onClickMapDirectly) + const onClickMapSeqToPrimitive = async (fn: string) => { + await mapSeqToX(link, context, (expr: string) => `${fn}(${expr})`); } - ]; - - const menuItems = pendingMappingType === MappingType.ArrayToArray - ? a2aMenuItems - : pendingMappingType === MappingType.ArrayToSingleton - ? a2sMenuItems - : pendingMappingType === MappingType.ArrayToSingletonAggregate - ? a2sAggregateItems - : defaultMenuItems; - if (pendingMappingType !== MappingType.ArrayToSingletonAggregate) { - menuItems.push({ - id: "a2a-a2s-custom-func", - label: getItemElement("a2a-a2s-custom-func", "Map Using Custom Function"), - onClick: wrapWithProgress(onClickMapWithCustomFn) - }); - if (pendingMappingType !== MappingType.ContainsUnions) { + const getItemElement = (id: string, label: string) => { + return ( +
+ + {label} +
+ ); + } + + const a2aMenuItems: Item[] = [ + { + id: "a2a-direct", + label: getItemElement("a2a-direct", "Map Input Array to Output Array"), + onClick: wrapWithProgress(onClickMapDirectly) + }, + { + id: "a2a-inner", + label: getItemElement("a2a-inner", "Map Array Elements Individually"), + onClick: wrapWithProgress(onClickMapIndividualElements) + } + ]; + + const defaultMenuItems: Item[] = [ + { + id: "direct", + label: getItemElement("direct", "Map Anyway"), + onClick: wrapWithProgress(onClickMapDirectly) + } + ]; + + const genAggregateItems = (onClick: (fn: string) => Promise) => { + const aggregateFnsNumeric = ["sum", "avg", "min", "max"]; + const aggregateFnsString = ["string:'join"]; + const aggregateFnsCommon = ["first", "last"]; + + const sourcePort = link.getSourcePort() as InputOutputPortModel; + const sourceType = sourcePort.attributes.field.kind; + + const aggregateFns = [...(isNumericType(sourceType) ? aggregateFnsNumeric : + getGenericTypeKind(sourceType) === TypeKind.String ? aggregateFnsString : + []), + ...aggregateFnsCommon]; + const a2sAggregateItems: Item[] = aggregateFns.map((fn) => ({ + id: `a2s-collect-${fn}`, + label: getItemElement(`a2s-collect-${fn}`, `Aggregate using ${fn}`), + onClick: wrapWithProgress(async () => await onClick(fn)) + })); + return a2sAggregateItems; + }; + + const genArrayToSingletonItems = (): Item[] => { + const a2sMenuItems: Item[] = [ + { + id: "a2s-index", + label: getItemElement("a2s-index", "Extract Single Element from Array"), + onClick: wrapWithProgress(onClickMapArraysAccessSingleton) + } + + ]; + const sourcePort = link.getSourcePort() as InputOutputPortModel; + const targetPort = link.getTargetPort() as InputOutputPortModel; + const sourceMemberType = sourcePort.attributes.field.member?.kind; + const targetType = targetPort.attributes.field.kind; + + if (sourceMemberType === targetType && isPrimitive(sourceMemberType)) { + a2sMenuItems.push({ + id: "a2s-aggregate", + label: getItemElement("a2s-aggregate", "Aggregate and map"), + onClick: wrapWithProgress(onClickAggregateArray) + }); + } + + return a2sMenuItems; + }; + + const genMenuItems = (): Item[] => { + switch (pendingMappingType) { + case MappingType.ArrayToArray: + return a2aMenuItems; + case MappingType.ArrayToSingleton: + return genArrayToSingletonItems(); + case MappingType.ArrayToSingletonAggregate: + return genAggregateItems(onClickMapWithAggregateFn); + case MappingType.SeqToPrimitive: + return genAggregateItems(onClickMapSeqToPrimitive); + default: + return defaultMenuItems; + } + }; + + const menuItems = genMenuItems(); + + if (pendingMappingType !== MappingType.ArrayToSingletonAggregate && + pendingMappingType !== MappingType.SeqToPrimitive && + pendingMappingType !== MappingType.SeqToArray) { menuItems.push({ - id: "a2a-a2s-transform-func", - label: getItemElement("a2a-a2s-transform-func", "Map Using Transform Function"), - onClick: wrapWithProgress(onClickMapWithTransformFn) + id: "a2a-a2s-custom-func", + label: getItemElement("a2a-a2s-custom-func", "Map Using Custom Function"), + onClick: wrapWithProgress(onClickMapWithCustomFn) }); + if (pendingMappingType !== MappingType.ContainsUnions) { + menuItems.push({ + id: "a2a-a2s-transform-func", + label: getItemElement("a2a-a2s-transform-func", "Map Using Transform Function"), + onClick: wrapWithProgress(onClickMapWithTransformFn) + }); + } } - } + return menuItems; + }, [pendingMappingType, link, context]); + return (
diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts index 1a2be0c0dce..50f122425d0 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Link/DataMapperLink/DataMapperLink.ts @@ -31,6 +31,8 @@ export enum MappingType { ArrayJoin = "array-join", Incompatible = "incompatible", ContainsUnions = "contains-unions", + SeqToPrimitive = "seq-primitive", + SeqToArray = "seq-array", Default = undefined // This is for non-array mappings currently } diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/LinkConnector/LinkConnectorNodeWidget.tsx b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/LinkConnector/LinkConnectorNodeWidget.tsx index fee23c12d62..2cda565b9cc 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/LinkConnector/LinkConnectorNodeWidget.tsx +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/LinkConnector/LinkConnectorNodeWidget.tsx @@ -66,7 +66,7 @@ export function LinkConnectorNodeWidget(props: LinkConnectorNodeWidgetProps) { ); return (!node.hidden && ( -
+
{renderPortWidget(engine, node.inPort, `${node?.value}-input`)} {renderIconButton(node)} diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx index 28c799206a6..b01a312690b 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/QueryExprConnector/QueryExprConnectorNodeWidget.tsx @@ -83,7 +83,7 @@ export function QueryExprConnectorNodeWidget(props: QueryExprConnectorNodeWidget ); return (!node.hidden && ( -
+
{renderPortWidget(engine, node.inPort, `${node?.value}-input`)} {renderEditButton(onClickEdit, node?.value)} diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/Tree/Tree.tsx b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/Tree/Tree.tsx index 2c944cba631..62847e9ea08 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/Tree/Tree.tsx +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Node/commons/Tree/Tree.tsx @@ -68,7 +68,10 @@ export const TreeHeader = styled.div<{ isSelected?: boolean; isDisabled?: boolea : 'var(--vscode-list-hoverBackground)', }, color: 'var(--vscode-inputOption-activeForeground)', - borderBottom: '1.8px solid var(--vscode-dropdown-border)' + borderBottom: '1.8px solid var(--vscode-dropdown-border)', + ...(isSelected && { + outline: "1px solid var(--vscode-list-focusAndSelectionOutline, var(--vscode-contrastActiveBorder, var(--vscode-editorLink-activeForeground, var(--vscode-list-focusOutline))))" + }) })); export const TreeBody = styled.div` diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts index 348b189749f..d412f1b6e8b 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/Port/model/InputOutputPortModel.ts @@ -20,8 +20,9 @@ import { IOType, Mapping } from "@wso2/ballerina-core"; import { DataMapperLinkModel, MappingType } from "../../Link"; import { IntermediatePortModel } from "../IntermediatePort"; -import { createNewMapping, mapWithJoin } from "../../utils/modification-utils"; +import { createNewMapping, mapSeqToX, mapWithJoin } from "../../utils/modification-utils"; import { getMappingType, isPendingMappingRequired } from "../../utils/common-utils"; +import { DataMapperNodeModel } from "../../Node/commons/DataMapperNode"; export interface InputOutputPortModelGenerics { PORT: InputOutputPortModel; @@ -80,6 +81,11 @@ export class InputOutputPortModel extends PortModel `[${expr}]`); + return; + } await createNewMapping(lm); }) diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts index b91569cbfad..309f4e9576f 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/hooks/useDiagramModel.ts @@ -26,7 +26,7 @@ import { useDMSearchStore } from "../../../store/store"; import { InputNode } from "../Node"; import { getErrorKind } from "../utils/common-utils"; import { OverlayLayerModel } from "../OverlayLayer/OverlayLayerModel"; -import { IOType } from "@wso2/ballerina-core"; +import { IntermediateClauseType, IOType } from "@wso2/ballerina-core"; import { useEffect } from "react"; export const useDiagramModel = ( @@ -48,6 +48,9 @@ export const useDiagramModel = ( const mappings = model?.mappings.map(mapping => mapping.output + ':' + mapping.expression).toString(); const subMappings = model?.subMappings?.map(mapping => (mapping as IOType).id).toString(); const queryIOs = model?.query ? model.query.inputs.toString() + ':' + model.query.output : ''; + const queryClauses = model?.query?.intermediateClauses + ?.filter(clause => clause.type === IntermediateClauseType.LET || clause.type === IntermediateClauseType.GROUP_BY) + .map(clause => clause.properties.name + ':' + clause.properties.expression).toString(); const collapsedFields = useDMCollapsedFieldsStore(state => state.fields); // Subscribe to collapsedFields const expandedFields = useDMExpandedFieldsStore(state => state.fields); // Subscribe to expandedFields const { inputSearch, outputSearch } = useDMSearchStore(); @@ -101,7 +104,8 @@ export const useDiagramModel = ( outputSearch, mappings, subMappings, - queryIOs + queryIOs, + queryClauses ], queryFn: genModel, networkMode: 'always', diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts index 1a54644bae1..5384e0e195a 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/common-utils.ts @@ -65,7 +65,7 @@ export function hasChildMappingsForInput(mappings: Mapping[], inputId: string): } export function isPendingMappingRequired(mappingType: MappingType): boolean { - return mappingType !== MappingType.Default; + return mappingType !== MappingType.Default && mappingType !== MappingType.SeqToArray; } export function getMappingType(sourcePort: PortModel, targetPort: PortModel): MappingType { @@ -95,6 +95,15 @@ export function getMappingType(sourcePort: PortModel, targetPort: PortModel): Ma if (sourceField.kind === TypeKind.Union || targetField.kind === TypeKind.Union) { return MappingType.ContainsUnions; } + + if (sourceField.isSeq) { + if (isPrimitive(targetField.kind)){ + return MappingType.SeqToPrimitive; + } + if (targetField.kind === TypeKind.Array) { + return MappingType.SeqToArray; + } + } const sourceDim = getDMTypeDim(sourceField); const targetDim = getDMTypeDim(targetField); diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts index b234ba8abc5..d211e18f87a 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/modification-utils.ts @@ -176,6 +176,57 @@ export async function mapWithQuery(link: DataMapperLinkModel, clauseType: Result expandArrayFn(context, [input], output, viewId); } + +export async function mapSeqToArray(link: DataMapperLinkModel, context: IDataMapperContext){ + const sourcePort = link.getSourcePort(); + const targetPort = link.getTargetPort(); + if (!sourcePort || !targetPort) { + return; + } + + const sourcePortModel = sourcePort as InputOutputPortModel; + +} + +export async function mapSeqToX(link: DataMapperLinkModel, context: IDataMapperContext, modifier: (expr: string) => string){ + const sourcePort = link.getSourcePort(); + const targetPort = link.getTargetPort(); + if (!sourcePort || !targetPort) { + return; + } + + const sourcePortModel = sourcePort as InputOutputPortModel; + + if (!sourcePortModel.attributes.field.isFocused){ + + const lastView = context.views[context.views.length - 1]; + const viewId = lastView.targetField; + + const clause = { + type: IntermediateClauseType.LET, + properties: { + name: await context.genUniqueName(sourcePortModel.attributes.field.name, viewId), + type: "var", + expression: sourcePortModel.attributes.fieldFQN, + } + } + + const groupByClauseIndex = context.model.query?.intermediateClauses + ?.findIndex(c => c.type === IntermediateClauseType.GROUP_BY); + + const letClauseIndex = (groupByClauseIndex !== -1 && groupByClauseIndex !== undefined) ? groupByClauseIndex - 1 : -1; + + await context.addClauses(clause, viewId, true, letClauseIndex); + + sourcePortModel.attributes.fieldFQN = clause.properties.name; + sourcePortModel.attributes.optionalOmittedFieldFQN = clause.properties.name; + + } + + await createNewMapping(link, modifier); + +} + export function mapWithJoin(link: DataMapperLinkModel) { const sourcePort = link.getSourcePort(); @@ -201,7 +252,6 @@ export function mapWithJoin(link: DataMapperLinkModel) { setIsQueryClausesPanelOpen(true); } - export function buildInputAccessExpr(fieldFqn: string): string { // Regular expression to match either quoted strings or non-quoted strings with dots const regex = /"([^"]+)"|'([^"]+)'|([^".]+)/g; diff --git a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts index 93706781864..a1d3fc16a84 100644 --- a/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts +++ b/workspaces/ballerina/data-mapper/src/components/Diagram/utils/type-utils.ts @@ -28,6 +28,10 @@ export function getTypeName(fieldType: IOType): string { } let typeName = fieldType?.typeName || fieldType.kind; + + if (fieldType.isSeq) { + return `...${typeName}`; + } return typeName; } @@ -90,3 +94,10 @@ export function getGenericTypeKind(typeKind: TypeKind): TypeKind { return typeKind; } }; + +export function isNumericType(typeKind: TypeKind): boolean { + const genericTypeKind = getGenericTypeKind(typeKind); + return genericTypeKind === TypeKind.Int || + genericTypeKind === TypeKind.Float || + genericTypeKind === TypeKind.Decimal; +} diff --git a/workspaces/ballerina/data-mapper/src/index.tsx b/workspaces/ballerina/data-mapper/src/index.tsx index 85f1e575359..9cae88a622e 100644 --- a/workspaces/ballerina/data-mapper/src/index.tsx +++ b/workspaces/ballerina/data-mapper/src/index.tsx @@ -24,11 +24,12 @@ import type {} from "@projectstorm/react-diagrams-core"; import type {} from "@projectstorm/react-diagrams"; import { css, Global } from '@emotion/react'; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { DMFormProps, ModelState, IntermediateClause, Mapping, CodeData, FnMetadata, LineRange, ResultClauseType, IOType } from "@wso2/ballerina-core"; +import { DMFormProps, ModelState, IntermediateClause, Mapping, CodeData, FnMetadata, LineRange, ResultClauseType, IOType, Property, LinePosition } from "@wso2/ballerina-core"; import { CompletionItem, ErrorBoundary } from "@wso2/ui-toolkit"; import { DataMapperEditor } from "./components/DataMapper/DataMapperEditor"; import { ExpressionProvider } from "./context/ExpressionContext"; +import { ISSUES_URL } from "./components/Diagram/utils/constants"; const queryClient = new QueryClient({ defaultOptions: { @@ -68,6 +69,7 @@ export interface DataMapperEditorProps { convertToQuery: (mapping: Mapping, clauseType: ResultClauseType, viewId: string, name: string) => Promise; addClauses: (clause: IntermediateClause, targetField: string, isNew: boolean, index:number) => Promise; deleteClause: (targetField: string, index: number) => Promise; + getClausePosition: (targetField: string, index: number) => Promise; addSubMapping: (subMappingName: string, type: string, index: number, targetField: string, importsCodedata?: CodeData) => Promise; deleteMapping: (mapping: Mapping, viewId: string) => Promise; deleteSubMapping: (index: number, viewId: string) => Promise; @@ -76,11 +78,11 @@ export interface DataMapperEditorProps { goToFunction: (functionRange: LineRange) => Promise; enrichChildFields: (parentField: IOType) => Promise; onRefresh: () => Promise; - onReset: () => Promise; onClose: () => void; onEdit?: () => void; handleView: (viewId: string, isSubMapping?: boolean) => void; generateForm: (formProps: DMFormProps) => JSX.Element; + genUniqueName: (name: string, viewId: string) => Promise; undoRedoGroup: () => JSX.Element; } @@ -90,7 +92,7 @@ export interface DataMapperProps extends DataMapperEditorProps { export function DataMapper({ expressionBar, ...props }: DataMapperProps) { return ( - + diff --git a/workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts b/workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts index 0ad7a314d45..504604e8229 100644 --- a/workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts +++ b/workspaces/ballerina/data-mapper/src/utils/DataMapperContext/DataMapperContext.ts @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -import { FnMetadata, ExpandedDMModel, IOType, LineRange, Mapping, ResultClauseType } from "@wso2/ballerina-core"; +import { FnMetadata, ExpandedDMModel, IOType, LineRange, Mapping, ResultClauseType, IntermediateClause } from "@wso2/ballerina-core"; import { View } from "../../components/DataMapper/Views/DataMapperView"; export interface IDataMapperContext { @@ -28,10 +28,12 @@ export interface IDataMapperContext { convertToQuery: (mapping: Mapping, clauseType: ResultClauseType, viewId: string, name: string) => Promise; deleteMapping: (mapping: Mapping, viewId: string) => Promise; deleteSubMapping: (index: number, viewId: string) => Promise; + addClauses: (clause: IntermediateClause, targetField: string, isNew: boolean, index:number) => Promise; mapWithCustomFn: (mapping: Mapping, metadata: FnMetadata, viewId: string) => Promise; mapWithTransformFn: (mapping: Mapping, metadata: FnMetadata, viewId: string) => Promise; goToFunction: (functionRange: LineRange) => Promise; enrichChildFields: (parentField: IOType) => Promise; + genUniqueName: (name: string, viewId: string) => Promise; } export class DataMapperContext implements IDataMapperContext { @@ -46,9 +48,11 @@ export class DataMapperContext implements IDataMapperContext { public convertToQuery: (mapping: Mapping, clauseType: ResultClauseType, viewId: string, name: string) => Promise, public deleteMapping: (mapping: Mapping, viewId: string) => Promise, public deleteSubMapping: (index: number, viewId: string) => Promise, + public addClauses: (clause: IntermediateClause, targetField: string, isNew: boolean, index:number) => Promise, public mapWithCustomFn: (mapping: Mapping, metadata: FnMetadata, viewId: string) => Promise, public mapWithTransformFn: (mapping: Mapping, metadata: FnMetadata, viewId: string) => Promise, public goToFunction: (functionRange: LineRange) => Promise, - public enrichChildFields: (parentField: IOType) => Promise + public enrichChildFields: (parentField: IOType) => Promise, + public genUniqueName: (name: string, viewId: string) => Promise ){} } diff --git a/workspaces/bi/bi-extension/CHANGELOG.md b/workspaces/bi/bi-extension/CHANGELOG.md index b6bc048bc2b..415db8bb09b 100644 --- a/workspaces/bi/bi-extension/CHANGELOG.md +++ b/workspaces/bi/bi-extension/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to the **WSO2 Integrator: BI** extension will be documented The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/). +## [1.5.3](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.5.2...ballerina-integrator-1.5.3) - 2025-12-01 + +### Changed + +- **Data Mapper** — Improved completion support for the expression bar and clause editor. Re-enabled array aggregating options. + +### Fixed + +- **Data Mapper** — Fixed expression bar focusing, inline undo button, and crashes during mapping clearance. +- **AI Data Mapper** — Fixed error handling, output formatting, and compilation errors. ## [1.5.2](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.5.1...ballerina-integrator-1.5.2) - 2025-11-18 diff --git a/workspaces/bi/bi-extension/package.json b/workspaces/bi/bi-extension/package.json index f5382f4424d..5772496da7b 100644 --- a/workspaces/bi/bi-extension/package.json +++ b/workspaces/bi/bi-extension/package.json @@ -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.5.1", + "version": "1.5.3", "publisher": "wso2", "icon": "resources/images/wso2-ballerina-integrator-logo.png", "repository": { @@ -67,7 +67,8 @@ "ballerina-integrator": [ { "id": "BI.project-explorer", - "name": "" + "name": "", + "when": "!config.integrator.defaultIntegrator" } ] }, @@ -162,7 +163,7 @@ "lint": "eslint src --ext ts", "test": "node ./out/test/runTest.js", "build": "pnpm run compile && pnpm run lint && pnpm run postbuild", - "package": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi", + "package": "node ../../common-libs/scripts/package-vsix.js", "copyFonts": "copyfiles -f ./node_modules/@wso2/font-wso2-vscode/dist/* ./resources/font-wso2-vscode/dist/", "rebuild": "pnpm run clean && pnpm run compile && pnpm run postbuild", "postbuild": "pnpm run copyFonts && pnpm run package && pnpm run copyVSIX", @@ -176,7 +177,7 @@ "@wso2/ballerina-core": "workspace:*", "@wso2/font-wso2-vscode": "workspace:*", "xstate": "^4.38.3", - "toml": "^3.0.0" + "@iarna/toml": "^2.2.5" }, "devDependencies": { "@vscode/vsce": "^3.7.0", diff --git a/workspaces/bi/bi-extension/src/constants/index.ts b/workspaces/bi/bi-extension/src/constants/index.ts index 182bfeda524..e3a9354dcea 100644 --- a/workspaces/bi/bi-extension/src/constants/index.ts +++ b/workspaces/bi/bi-extension/src/constants/index.ts @@ -16,4 +16,10 @@ * under the License. */ +import { BI_COMMANDS } from "@wso2/ballerina-core"; + // ADD ALL THE NON-SHARED BI ONLY ATTRIBUTES HERE. +export const WI_EXTENSION_ID = 'wso2.wso2-integrator'; +export const WI_PROJECT_EXPLORER_VIEW_ID = 'wso2-integrator.explorer'; +export const WI_PROJECT_EXPLORER_VIEW_REFRESH_COMMAND = 'wso2-integrator.explorer.refresh'; +export const BI_PROJECT_EXPLORER_VIEW_ID = BI_COMMANDS.PROJECT_EXPLORER; diff --git a/workspaces/bi/bi-extension/src/project-explorer/activate.ts b/workspaces/bi/bi-extension/src/project-explorer/activate.ts index ab5ddb46784..afc8482012d 100644 --- a/workspaces/bi/bi-extension/src/project-explorer/activate.ts +++ b/workspaces/bi/bi-extension/src/project-explorer/activate.ts @@ -15,11 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -import { SHARED_COMMANDS, BI_COMMANDS } from '@wso2/ballerina-core'; +import { SHARED_COMMANDS, BI_COMMANDS, MACHINE_VIEW, NodePosition } from '@wso2/ballerina-core'; import { ProjectExplorerEntry, ProjectExplorerEntryProvider } from './project-explorer-provider'; import { ExtensionContext, TreeView, commands, window, workspace } from 'vscode'; import { extension } from '../biExtentionContext'; +import { BI_PROJECT_EXPLORER_VIEW_ID, WI_PROJECT_EXPLORER_VIEW_ID, WI_PROJECT_EXPLORER_VIEW_REFRESH_COMMAND } from '../constants'; interface ExplorerActivationConfig { context: ExtensionContext; @@ -27,20 +28,27 @@ interface ExplorerActivationConfig { isBallerinaPackage?: boolean; isBallerinaWorkspace?: boolean; isEmptyWorkspace?: boolean; + isInWI: boolean; } export function activateProjectExplorer(config: ExplorerActivationConfig) { - const { context, isBI, isBallerinaPackage, isBallerinaWorkspace, isEmptyWorkspace } = config; + const { context, isBI, isBallerinaPackage, isBallerinaWorkspace, isEmptyWorkspace, isInWI } = config; if (extension.langClient && extension.biSupported) { setLoadingStatus(); } + const treeviewId = isInWI ? WI_PROJECT_EXPLORER_VIEW_ID : BI_PROJECT_EXPLORER_VIEW_ID; const projectExplorerDataProvider = new ProjectExplorerEntryProvider(); - const projectTree = createProjectTree(projectExplorerDataProvider); + const projectTree = createProjectTree(projectExplorerDataProvider, treeviewId); + + projectExplorerDataProvider.setTreeView(projectTree); + + // Always register core commands so they're available to the Ballerina extension + registerCoreCommands(projectExplorerDataProvider, isInWI); if (isBallerinaPackage || isBallerinaWorkspace) { - registerBallerinaCommands(projectExplorerDataProvider, isBI, isBallerinaWorkspace, isEmptyWorkspace); + registerBallerinaCommands(projectExplorerDataProvider, isBI, isInWI, isBallerinaWorkspace, isEmptyWorkspace); } handleVisibilityChangeEvents( @@ -57,17 +65,41 @@ function setLoadingStatus() { commands.executeCommand('setContext', 'BI.status', 'loading'); } -function createProjectTree(dataProvider: ProjectExplorerEntryProvider) { - return window.createTreeView(BI_COMMANDS.PROJECT_EXPLORER, { treeDataProvider: dataProvider }); +function createProjectTree(dataProvider: ProjectExplorerEntryProvider, treeviewId: string) { + return window.createTreeView(treeviewId, { treeDataProvider: dataProvider }); +} + +function registerCoreCommands(dataProvider: ProjectExplorerEntryProvider, isInWI: boolean) { + // Register the notify command that's called by the Ballerina extension + commands.registerCommand( + BI_COMMANDS.NOTIFY_PROJECT_EXPLORER, + (event: { + projectPath: string, + documentUri: string, + position: NodePosition, + view: MACHINE_VIEW + }) => { + dataProvider.revealInTreeView(event.documentUri, event.projectPath, event.position, event.view); + } + ); + + // Register the refresh command + commands.registerCommand(BI_COMMANDS.REFRESH_COMMAND, () => { + if (isInWI) { + commands.executeCommand(WI_PROJECT_EXPLORER_VIEW_REFRESH_COMMAND); + return; + } + dataProvider.refresh() + }); } function registerBallerinaCommands( dataProvider: ProjectExplorerEntryProvider, isBI: boolean, + isInWI: boolean, isBallerinaWorkspace?: boolean, isEmptyWorkspace?: boolean ) { - commands.registerCommand(BI_COMMANDS.REFRESH_COMMAND, () => dataProvider.refresh()); commands.executeCommand('setContext', 'BI.isWorkspaceSupported', extension.isWorkspaceSupported ?? false); if (isBallerinaWorkspace) { @@ -77,7 +109,7 @@ function registerBallerinaCommands( } } if (isBI) { - registerBICommands(); + registerBICommands(isInWI); } } @@ -131,8 +163,9 @@ function handleNonBallerinaVisibility() { commands.executeCommand(SHARED_COMMANDS.OPEN_BI_WELCOME); } -function registerBICommands() { - commands.executeCommand(BI_COMMANDS.FOCUS_PROJECT_EXPLORER); +function registerBICommands(isInWI) { + const treeViewId = isInWI ? WI_PROJECT_EXPLORER_VIEW_ID : BI_PROJECT_EXPLORER_VIEW_ID; + commands.executeCommand(`${treeViewId}.focus`); commands.executeCommand(SHARED_COMMANDS.SHOW_VISUALIZER); commands.executeCommand('setContext', 'BI.project', true); } diff --git a/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts b/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts index ebc0c203c5d..388514c5ee7 100644 --- a/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts +++ b/workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts @@ -19,7 +19,17 @@ import * as vscode from 'vscode'; import { window, Uri, commands } from 'vscode'; import path = require('path'); -import { DIRECTORY_MAP, ProjectStructureArtifactResponse, ProjectStructureResponse, SHARED_COMMANDS, BI_COMMANDS, PackageConfigSchema, BallerinaProject, VisualizerLocation, ProjectStructure } from "@wso2/ballerina-core"; +import { + DIRECTORY_MAP, + ProjectStructureArtifactResponse, + ProjectStructureResponse, + SHARED_COMMANDS, + BI_COMMANDS, + VisualizerLocation, + ProjectStructure, + MACHINE_VIEW, + NodePosition +} from "@wso2/ballerina-core"; import { extension } from "../biExtentionContext"; interface Property { @@ -34,17 +44,20 @@ interface Property { export class ProjectExplorerEntry extends vscode.TreeItem { children: ProjectExplorerEntry[] | undefined; info: string | undefined; + position: NodePosition | undefined; constructor( public readonly label: string, public collapsibleState: vscode.TreeItemCollapsibleState, info: string | undefined = undefined, icon: string = 'folder', - isCodicon: boolean = false + isCodicon: boolean = false, + position: NodePosition | undefined = undefined ) { super(label, collapsibleState); this.tooltip = `${this.label}`; this.info = info; + this.position = position; if (icon && isCodicon) { this.iconPath = new vscode.ThemeIcon(icon); } else if (icon) { @@ -62,25 +75,156 @@ export class ProjectExplorerEntryProvider implements vscode.TreeDataProvider(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + private _treeView: vscode.TreeView | undefined; + private _isRefreshing: boolean = false; + private _pendingRefresh: boolean = false; + + setTreeView(treeView: vscode.TreeView): void { + this._treeView = treeView; + } refresh(): void { + // If already refreshing, mark that we need another refresh after current one completes + if (this._isRefreshing) { + this._pendingRefresh = true; + return; + } + + this._isRefreshing = true; + this._pendingRefresh = false; + window.withProgress({ location: { viewId: BI_COMMANDS.PROJECT_EXPLORER }, title: 'Loading project structure' }, async () => { try { - const data = await getProjectStructureData(); + this._data = []; + + const data = await getProjectStructureData(); this._data = data; // Fire the event after data is fully populated this._onDidChangeTreeData.fire(); } catch (err) { - console.error(err); + console.error('[ProjectExplorer] Error during refresh:', err); this._data = []; this._onDidChangeTreeData.fire(); + } finally { + this._isRefreshing = false; + + // If another refresh was requested while we were refreshing, do it now + if (this._pendingRefresh) { + console.log('[ProjectExplorer] Executing pending refresh'); + this._pendingRefresh = false; + this.refresh(); + } } }); } + revealInTreeView( + documentUri: string | undefined, + projectPath: string | undefined, + position: NodePosition | undefined, + view: MACHINE_VIEW | undefined + ): void { + if (!this._treeView) { + return; + } + + let itemToReveal: ProjectExplorerEntry | undefined; + + // Case 1: If documentUri is present, find the tree item with matching path and position + if (documentUri) { + itemToReveal = this.findItemByPathAndPosition(documentUri, position); + } + // Case 2: If documentUri is undefined but projectPath is present and view is not 'WorkspaceOverview' + else if (projectPath && view !== MACHINE_VIEW.WorkspaceOverview) { + itemToReveal = this.findItemByPathAndPosition(projectPath, position); + } + + // Reveal the item if found + if (itemToReveal && this._treeView.visible) { + this._treeView.reveal(itemToReveal, { + select: true, + focus: true, + expand: true + }); + } + } + + /** + * Recursively search for a tree item by its path and position + */ + private findItemByPathAndPosition(targetPath: string, targetPosition: NodePosition | undefined): ProjectExplorerEntry | undefined { + for (const rootItem of this._data) { + // Check if the root item matches + if (this.matchesPathAndPosition(rootItem, targetPath, targetPosition)) { + return rootItem; + } + // Recursively search children + const found = this.searchChildrenByPathAndPosition(rootItem, targetPath, targetPosition); + if (found) { + return found; + } + } + return undefined; + } + + /** + * Recursively search through children for a matching path and position + */ + private searchChildrenByPathAndPosition(parent: ProjectExplorerEntry, targetPath: string, targetPosition: NodePosition | undefined): ProjectExplorerEntry | undefined { + if (!parent.children) { + return undefined; + } + + for (const child of parent.children) { + if (this.matchesPathAndPosition(child, targetPath, targetPosition)) { + return child; + } + + const found = this.searchChildrenByPathAndPosition(child, targetPath, targetPosition); + if (found) { + return found; + } + } + + return undefined; + } + + /** + * Check if an item matches the given path and position + */ + private matchesPathAndPosition(item: ProjectExplorerEntry, targetPath: string, targetPosition: NodePosition | undefined): boolean { + // Path must match + if (item.info !== targetPath) { + return false; + } + + // If no target position is provided, match by path only + if (!targetPosition) { + return true; + } + + // If target position is provided but item has no position, don't match + if (!item.position) { + return true; // Fall back to path-only matching for items without position + } + + // Compare positions + return this.positionsMatch(item.position, targetPosition); + } + + /** + * Check if two positions match + */ + private positionsMatch(pos1: NodePosition, pos2: NodePosition): boolean { + return pos1.startLine === pos2.startLine && + pos1.startColumn === pos2.startColumn && + pos1.endLine === pos2.endLine && + pos1.endColumn === pos2.endColumn; + } + constructor() { this._data = []; } @@ -166,8 +310,18 @@ async function getProjectStructureData(): Promise { // Generate the tree data for the projects const projects = projectStructure.projects; - const isSingleProject = projects.length === 1; + // Filter projects to avoid duplicates - only include unique project paths + const uniqueProjects = new Map(); for (const project of projects) { + if (!uniqueProjects.has(project.projectPath)) { + uniqueProjects.set(project.projectPath, project); + } + } + + const filteredProjects = Array.from(uniqueProjects.values()); + + const isSingleProject = filteredProjects.length === 1; + for (const project of filteredProjects) { const projectTree = generateTreeData(project, isSingleProject); if (projectTree) { data.push(projectTree); @@ -371,7 +525,9 @@ function getComponents(items: ProjectStructureArtifactResponse[], itemType: DIRE comp.name, vscode.TreeItemCollapsibleState.None, comp.path, - comp.icon + comp.icon, + false, + comp.position ); fileEntry.resourceUri = Uri.parse(`bi-category:${projectPath}`); fileEntry.command = { @@ -394,4 +550,3 @@ function getComponents(items: ProjectStructureArtifactResponse[], itemType: DIRE } return entries; } - diff --git a/workspaces/bi/bi-extension/src/stateMachine.ts b/workspaces/bi/bi-extension/src/stateMachine.ts index d82d8eb9f22..43b5dcbf251 100644 --- a/workspaces/bi/bi-extension/src/stateMachine.ts +++ b/workspaces/bi/bi-extension/src/stateMachine.ts @@ -20,12 +20,15 @@ import { assign, createMachine, interpret } from 'xstate'; import { activateProjectExplorer } from './project-explorer/activate'; import { extension } from './biExtentionContext'; import { fetchProjectInfo, ProjectInfo } from './utils'; +import { WI_EXTENSION_ID } from './constants'; +import * as vscode from 'vscode'; interface MachineContext { isBI: boolean; isBallerinaPackage?: boolean; isBallerinaWorkspace?: boolean; isEmptyWorkspace?: boolean; + isInWI: boolean; } const stateMachine = createMachine({ @@ -34,7 +37,8 @@ const stateMachine = createMachine({ initial: 'initialize', predictableActionArguments: true, context: { - isBI: false + isBI: false, + isInWI: vscode.extensions.getExtension(WI_EXTENSION_ID) ? true : false }, states: { initialize: { @@ -71,7 +75,8 @@ const stateMachine = createMachine({ isBI: context.isBI, isBallerinaPackage: context.isBallerinaPackage, isBallerinaWorkspace: context.isBallerinaWorkspace, - isEmptyWorkspace: context.isEmptyWorkspace + isEmptyWorkspace: context.isEmptyWorkspace, + isInWI: context.isInWI }); } }, diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/ai-chat-service.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/ai-chat-service.spec.ts similarity index 96% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/ai-chat-service.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/ai-chat-service.spec.ts index cca330a9fbb..a841ca1aa95 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/ai-chat-service.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/ai-chat-service.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('AI Chat Agent Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphql-service.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphql-service.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphql-service.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphql-service.spec.ts index e97fca071a2..b371493640b 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphql-service.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphql-service.spec.ts @@ -16,11 +16,11 @@ * under the License. */ import { Frame, test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; import { GraphQLServiceUtils} from './graphqlUtils'; -import { TypeEditorUtils } from '../type/TypeEditorUtils'; +import { TypeEditorUtils } from '../type-editor/TypeEditorUtils'; const TEST_DATA = { editedBasePath: (attempt: number) => `/editedSample${attempt}`, diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphqlUtils.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphqlUtils.ts similarity index 99% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphqlUtils.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphqlUtils.ts index 621558bd79a..f74ba8829aa 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/graphqlUtils.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/graphqlUtils.ts @@ -17,7 +17,7 @@ */ import { Frame,Page } from '@playwright/test'; import { Form } from '@wso2/playwright-vscode-tester'; -import { TypeEditorUtils } from '../type/TypeEditorUtils'; +import { TypeEditorUtils } from '../type-editor/TypeEditorUtils'; export class GraphQLServiceUtils { /** diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/http-service.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/http-service.spec.ts similarity index 96% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/http-service.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/http-service.spec.ts index b9f1825f770..31c838180eb 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/http-service.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/http-service.spec.ts @@ -16,9 +16,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('HTTP Service Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/tcp-service.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/tcp-service.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/tcp-service.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/tcp-service.spec.ts index 8166ba59350..fa06a8d3e7e 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-services/tcp-service.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/api-integration/tcp-service.spec.ts @@ -16,9 +16,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('TCP Service Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/automation/automation.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/automation/automation.spec.ts index 7975bb9f2f0..397cf02aecd 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/automation/automation.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/automation/automation.spec.ts @@ -16,7 +16,7 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { switchToIFrame } from '@wso2/playwright-vscode-tester'; export default function createTests() { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/configuration/configuration.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/configuration/configuration.spec.ts index 01ca0ad4ae4..f2b4c3b0881 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/configuration/configuration.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/configuration/configuration.spec.ts @@ -16,9 +16,9 @@ * under the License. */ import { expect, test } from '@playwright/test'; -import { addArtifact, enableICP, initTest, page } from '../utils'; +import { addArtifact, enableICP, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ConfigEditor } from '../ConfigEditor'; +import { ConfigEditor } from '../utils/pages'; import { config } from 'process'; export default function createTests() { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts new file mode 100644 index 00000000000..f6923e801a3 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/DataMapperUtils.ts @@ -0,0 +1,599 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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, Frame, Locator } from "@playwright/test"; +import * as fs from 'fs'; +import { newProjectPath, page } from '../utils/helpers'; +import path from "path"; + +const dmDataDir = path.join(__dirname, 'dm-data'); +const projectDir = path.join(newProjectPath, 'sample'); + +export class DataMapper { + + constructor(private webView: Frame) { + } + + public async waitFor() { + await this.webView.locator('#data-mapper-canvas-container').waitFor(); + } + + public getWebView() { + return this.webView; + } + + public async scrollClickOutput(locator: Locator) { + await this.scrollOutputUntilClickable(locator); + await locator.click(); + } + + public async scrollOutputUntilClickable(locator: Locator) { + const outputNode = this.webView.locator(`div[data-testid$="Output-node"]`); + await outputNode.hover(); + + for (let i = 0; !(await this.isClickable(locator)) && i < 5; i++) { + await page.page.mouse.wheel(0, 400); + } + } + + public async isClickable(element: Locator): Promise { + + // Check if the element is not covered by other elements + const isNotObstructed = await element.evaluate((el) => { + const rect = el.getBoundingClientRect(); + const elementAtPoint = document.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2); + return elementAtPoint === el || el.contains(elementAtPoint) || (elementAtPoint?.contains(el) ?? false); + }); + + return isNotObstructed; + } + + public async waitForProgressEnd() { + await this.webView.waitForSelector('vscode-progress-ring', { state: 'detached' }); + } + + public async expandField(fieldFQN: string) { + const expandButton = this.webView.locator(`div[id="expand-or-collapse-${fieldFQN}"]`); + + // Expand only if collapsed + if (await expandButton.locator('.codicon-chevron-right').isVisible()) { + await expandButton.click(); + await expandButton.locator('.codicon-chevron-down').waitFor(); + } + } + + public async refresh() { + await this.webView.getByTitle('Refresh').click(); + await this.waitForProgressEnd(); + } + + public async mapFields(sourceFieldFQN: string, targetFieldFQN: string, menuOptionId?: string) { + + const sourceField = this.webView.locator(`div[id="recordfield-${sourceFieldFQN}"]`); + const targetField = this.webView.locator(`div[id="recordfield-${targetFieldFQN}"] .port`); + + await targetField.waitFor(); + await sourceField.waitFor(); + + await sourceField.click({ force: true }); + + await expect(sourceField).toHaveCSS('outline-style', 'solid'); + + await targetField.click({ force: true }); + + if (menuOptionId) { + const menuItem = this.webView.locator(`#menu-item-${menuOptionId}`); + await menuItem.click(); + await menuItem.waitFor({ state: 'hidden' }); + } + try { + await this.webView.waitForSelector('vscode-progress-ring', { state: 'attached', timeout: 3000 }); + } catch (error) { } + try { + await this.webView.waitForSelector('vscode-progress-ring', { state: 'detached' }); + } catch (error) { } + + } + + public async selectConfigMenuItem(fieldFQN: string, menuOptionText: string) { + + const configMenu = this.webView.locator(`[id="recordfield-${fieldFQN}"] #component-list-menu-btn`); + await configMenu.waitFor(); + await configMenu.click(); + + const menuOption = this.webView.getByTestId(`context-menu-${menuOptionText}`); + await menuOption.waitFor(); + await menuOption.click(); + + await menuOption.waitFor({ state: 'detached' }); + await this.waitForProgressEnd(); + } + + public async goPrevViewBreadcrumb() { + const breadcrumbs = this.webView.locator(`a[data-testid^="dm-header-breadcrumb-"]`); + const previousCrumb = this.webView.locator(`a[data-testid="dm-header-breadcrumb-${await breadcrumbs.count() - 1}"]`); + await previousCrumb.waitFor(); + await previousCrumb.click(); + await previousCrumb.waitFor({ state: 'detached' }); + } + + public async goPrevViewBackButton() { + const breadcrumbs = this.webView.locator(`a[data-testid^="dm-header-breadcrumb-"]`); + const previousCrumb = this.webView.locator(`a[data-testid="dm-header-breadcrumb-${await breadcrumbs.count() - 1}"]`); + await this.webView.getByTestId('back-button').click(); + await previousCrumb.waitFor({ state: 'detached' }); + } + + public async saveSnapshot(snapshotFile: string) { + const root = this.webView.locator(`div#data-mapper-canvas-container`); + await root.waitFor(); + fs.writeFileSync(snapshotFile, await root.innerHTML()); + } + + public async expectErrorLink(locator: Locator) { + await locator.waitFor({ state: 'attached' }); + const hasDiagnostic = await locator.evaluate((el) => el.getAttribute('data-diagnostics')); + expect(hasDiagnostic).toBeTruthy(); + } + +} + +export namespace FileUtils { + + export function updateProjectFileSync(sourceFile: string, targetFile: string) { + const sourcePath = path.join(dmDataDir, sourceFile); + const targetPath = path.join(newProjectPath, 'sample', targetFile); + fs.writeFileSync(targetPath, fs.readFileSync(sourcePath, 'utf8')); + } + + export function updateDataFileSync(sourceFile: string, targetFile: string) { + const sourcePath = path.join(newProjectPath, 'sample', sourceFile); + const targetPath = path.join(dmDataDir, targetFile); + fs.writeFileSync(targetPath, fs.readFileSync(sourcePath, 'utf8')); + } + + export async function verifyFileContent(comparingFile: string, projectFile: string) { + + // // Uncomment this blcok for update data files + // console.log({comparingFile, projectFile}); + // await page.page.pause(); + // updateDataFileSync(projectFile, comparingFile); + // return true; + // // End of the block + + return compareFilesSync( + path.join(dmDataDir, comparingFile), + path.join(projectDir, projectFile) + ); + } + + export function compareFilesSync(file1: string, file2: string) { + const file1Content = fs.readFileSync(file1, 'utf8').replaceAll('\r\n', '\n'); + const file2Content = fs.readFileSync(file2, 'utf8').replaceAll('\r\n', '\n'); + + return file1Content === file2Content; + } +} + +export namespace TestScenarios { + + export async function testBasicMappings(dmWebView: Frame, projectFile: string, compDir: string, needRefresh?: boolean) { + console.log('Test Basic Mappings'); + + const dm = new DataMapper(dmWebView); + await dm.waitFor(); + + await dm.expandField('input'); + if (needRefresh) { + await dm.refresh(); + } + + console.log(' - Map child fields'); + // direct mapping + // objectOutput.output.oPrimDirect = input.iPrimDirect; + await dm.mapFields('input.iPrimDirect', 'objectOutput.output.oPrimDirect'); + const loc0 = dmWebView.getByTestId('link-from-input.iPrimDirect.OUT-to-objectOutput.output.oPrimDirect.IN'); + await loc0.waitFor({ state: 'attached' }); + + // direct mapping with error + // objectOutput.output.oPrimDirectErr = input.iPrimDirectErr; + await dm.mapFields('input.iPrimDirectErr', 'objectOutput.output.oPrimDirectErr'); + const loc1 = dmWebView.getByTestId('link-from-input.iPrimDirectErr.OUT-to-objectOutput.output.oPrimDirectErr.IN') + await dm.expectErrorLink(loc1); + + // many-one mapping + // objectOutput.output.oManyOne = input.iManyOne1 + input.iManyOne2 + input.iManyOne3; + await dm.mapFields('input.iManyOne1', 'objectOutput.output.oManyOne'); + await dm.mapFields('input.iManyOne2', 'objectOutput.output.oManyOne'); + await dm.mapFields('input.iManyOne3', 'objectOutput.output.oManyOne'); + + await dmWebView.getByTestId('link-from-input.iManyOne1.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-input.iManyOne2.OUT-to-datamapper-intermediate-port').first().waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-input.iManyOne3.OUT-to-datamapper-intermediate-port').first().waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-objectOutput.output.oManyOne.IN').waitFor({ state: 'attached' }); + const loc2 = dmWebView.getByTestId('link-connector-node-objectOutput.output.oManyOne.IN') + await loc2.waitFor(); + + // many-one mapping with error + // objectOutput.output.oManyOneErr = input.iManyOneErr1 + input.iPrimDirectErr + input.iManyOneErr2 + await dm.mapFields('input.iManyOneErr1', 'objectOutput.output.oManyOneErr'); + await dm.mapFields('input.iPrimDirectErr', 'objectOutput.output.oManyOneErr'); + await dm.mapFields('input.iManyOneErr2', 'objectOutput.output.oManyOneErr'); + + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.iManyOneErr1.OUT-to-datamapper-intermediate-port')); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.iPrimDirectErr.OUT-to-datamapper-intermediate-port')); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.iManyOneErr2.OUT-to-datamapper-intermediate-port')); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-objectOutput.output.oManyOneErr.IN')); + const loc3 = dmWebView.getByTestId('link-connector-node-objectOutput.output.oManyOneErr.IN'); + await loc3.getByTestId('expression-label-diagnostic').waitFor(); + + // object direct mapping + // objectOutput.output.oObjDirect= input.iObjDirect; + await dm.mapFields('input.iObjDirect', 'objectOutput.output.oObjDirect', 'direct'); + await dmWebView.getByTestId('link-from-input.iObjDirect.OUT-to-objectOutput.output.oObjDirect.IN').waitFor({ state: 'attached' }); + + // object direct mapping with error + // objectOutput.output.oObjDirectErr = input.iObjDirect + await dm.mapFields('input.iObjDirect', 'objectOutput.output.oObjDirectErr', 'direct'); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.iObjDirect.OUT-to-objectOutput.output.oObjDirectErr.IN')); + + // object properties mapping + // objectOutput.output.oObjProp.p1 = input.iObjDirect.d1; + await dm.mapFields('input.iObjDirect.d1', 'objectOutput.output.oObjProp.p1'); + const loc4 = dmWebView.getByTestId('link-from-input.iObjDirect.d1.OUT-to-objectOutput.output.oObjProp.p1.IN'); + await loc4.waitFor({ state: 'attached' }); + + // objectOutput.output.oObjProp.p2 = input.iObjProp.d2; + await dm.mapFields('input.iObjProp.op2', 'objectOutput.output.oObjProp.p2'); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.iObjProp.op2.OUT-to-objectOutput.output.oObjProp.p2.IN')); + + expect(await FileUtils.verifyFileContent(`basic/${compDir}/map1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete child field mappings'); + + await loc0.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.iPrimDirect.OUT-to-objectOutput.output.oPrimDirect.IN') + .locator('.codicon-trash').click({ force: true }); + await loc0.waitFor({ state: 'detached' }); + + await loc1.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.iPrimDirectErr.OUT-to-objectOutput.output.oPrimDirectErr.IN') + .locator('.codicon-trash').click({ force: true }); + await loc1.waitFor({ state: 'detached' }); + + await loc2.locator('.codicon-trash').click({ force: true }); + await loc2.waitFor({ state: 'detached' }); + + await loc3.locator('.codicon-trash').click({ force: true }); + await loc3.waitFor({ state: 'detached' }); + + await loc4.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.iObjDirect.d1.OUT-to-objectOutput.output.oObjProp.p1.IN') + .locator('.codicon-trash').click({ force: true }); + await loc4.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`basic/${compDir}/del1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Clear All Mappings'); + + await dmWebView.getByTitle('Clear all mappings').click(); + await dm.waitForProgressEnd(); + const links = dmWebView.locator('[data-testid^="link-from-"]'); + await expect(links).toHaveCount(0); + + expect(await FileUtils.verifyFileContent(`basic/${compDir}/del2.bal.txt`, projectFile)).toBeTruthy(); + + + console.log(' - Map root fields'); + + // root mapping + await dm.mapFields('input', 'objectOutput.output', 'direct'); + const locRoot = dmWebView.getByTestId('link-from-input.OUT-to-objectOutput.output.IN'); + await dm.expectErrorLink(locRoot); + + expect(await FileUtils.verifyFileContent(`basic/${compDir}/map2.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete root field mapping'); + // delete root mapping + await locRoot.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.OUT-to-objectOutput.output.IN').locator('.codicon-trash').click({ force: true }); + await locRoot.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`basic/${compDir}/del2.bal.txt`, projectFile)).toBeTruthy(); + } + + export async function testArrayInnerMappings(dmWebView: Frame, projectFile: string, compDir: string, needRefresh?: boolean) { + + console.log('Test Array Inner Mappings'); + + const dm = new DataMapper(dmWebView); + await dm.waitFor(); + + await dm.expandField('input'); + + if (needRefresh) { + await dm.refresh(); + await dmWebView.locator(`div[id="recordfield-input.iArr1D"]`).waitFor(); + } + + console.log(' - Input/Output preview'); + + await dm.expandField('input.iArr1D'); + + await dmWebView.locator('div[id="recordfield-input.iArr1D.iArr1D"]').waitFor(); + + await dm.expandField('objectOutput.output.oArr1D'); + await dmWebView.locator('div[id="recordfield-objectOutput.output.oArr1D.oArr1D"]').waitFor(); + + console.log(' - Map using query expression'); + await dm.mapFields('input.iArr1D', 'objectOutput.output.oArr1D', 'a2a-inner'); + + console.log(' - Map within focused view'); + await dm.mapFields('iArr1DItem.p2', 'queryOutput.oArr1D.p2'); + const loc1 = dmWebView.getByTestId('link-from-iArr1DItem.p2.OUT-to-queryOutput.oArr1D.p2.IN'); + await dm.expectErrorLink(loc1); + + await dm.mapFields('iArr1DItem.p2', 'queryOutput.oArr1D.p1'); + await dm.mapFields('iArr1DItem.p3', 'queryOutput.oArr1D.p1'); + + await dmWebView.getByTestId('link-from-iArr1DItem.p2.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-iArr1DItem.p3.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-queryOutput.oArr1D.p1.IN').waitFor({ state: 'attached' }); + + const loc2 = dmWebView.getByTestId('link-connector-node-queryOutput.oArr1D.p1.IN'); + await loc2.waitFor(); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/map1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Go back to root (using breadcrumb)'); + await dm.goPrevViewBreadcrumb(); + const loc0 = dmWebView.getByTestId('link-connector-node-objectOutput.output.oArr1D.IN'); + await loc0.waitFor(); + + console.log(' - Goto focused view again'); + await dmWebView.getByTestId('expand-array-fn-output.oArr1D').click(); + await dmWebView.getByTestId('link-from-input.iArr1D.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-queryOutput.oArr1D.#.IN').waitFor({ state: 'attached' }); + + console.log(' - Delete within focused view'); + await loc1.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-iArr1DItem.p2.OUT-to-queryOutput.oArr1D.p2.IN') + .locator('.codicon-trash').click({ force: true }); + await loc1.waitFor({ state: 'detached' }); + + await loc2.locator('.codicon-trash').click({ force: true }); + await loc2.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/del1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Map roots within focused view'); + await dm.mapFields('iArr1DItem', 'queryOutput.oArr1D', 'direct'); + const loc3 = dmWebView.getByTestId('link-from-iArr1DItem.OUT-to-queryOutput.oArr1D.IN'); + await loc3.waitFor(); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/map2.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete root mapping within focused view'); + await loc3.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-iArr1DItem.OUT-to-queryOutput.oArr1D.IN') + .locator('.codicon-trash').click({ force: true }); + await loc3.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/del2.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Go back to root view (using back button)'); + await dm.goPrevViewBackButton(); + + console.log(' - Initialize and add element using config menu'); + await dm.selectConfigMenuItem('objectOutput.output.oArr1D', 'Initialize Array'); + await dm.waitForProgressEnd(); + const locArrInit = dmWebView.getByTestId('array-widget-field-objectOutput.output.oArr1D.IN'); + await locArrInit.waitFor(); + expect(locArrInit).toHaveText('[]'); + + await dm.selectConfigMenuItem('objectOutput.output.oArr1D', 'Add Element'); + + await dmWebView.locator('div[id="recordfield-objectOutput.output.oArr1D.0"]').waitFor(); + + console.log(' - Add element using button'); + const addElementBtn = dmWebView.getByTestId('array-widget-objectOutput.output.oArr1D.IN-add-element'); + await addElementBtn.click(); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-objectOutput.output.oArr1D.1"]').waitFor(); + + await addElementBtn.click(); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-objectOutput.output.oArr1D.2"]').waitFor(); + + console.log(' - Map to array elements'); + await dm.mapFields('input.p1', 'objectOutput.output.oArr1D.0.p1'); + const loc4 = dmWebView.getByTestId('link-from-input.p1.OUT-to-objectOutput.output.oArr1D.0.p1.IN'); + await dm.expectErrorLink(loc4); + + await dm.mapFields('input.p2', 'objectOutput.output.oArr1D.1.p1'); + await dmWebView.getByTestId('link-from-input.p2.OUT-to-objectOutput.output.oArr1D.1.p1.IN').waitFor({ state: 'attached' }); + + await dm.mapFields('input.p1', 'objectOutput.output.oArr1D.2', 'direct'); + const loc5 = dmWebView.getByTestId('link-from-input.p1.OUT-to-objectOutput.output.oArr1D.2.IN'); + await dm.expectErrorLink(loc5); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/map3.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete array element mapping, entire element and entire array'); + await loc4.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.p1.OUT-to-objectOutput.output.oArr1D.0.p1.IN') + .locator('.codicon-trash').click({ force: true }); + await loc4.waitFor({ state: 'detached' }); + + await loc5.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.p1.OUT-to-objectOutput.output.oArr1D.2.IN') + .locator('.codicon-trash').click({ force: true }); + await loc5.waitFor({ state: 'detached' }); + + await dm.selectConfigMenuItem('objectOutput.output.oArr1D.1', 'Delete Element'); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-objectOutput.output.oArr1D.1"]').waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/del3.bal.txt`, projectFile)).toBeTruthy(); + + await dm.selectConfigMenuItem('objectOutput.output.oArr1D', 'Delete Array'); + + expect(await FileUtils.verifyFileContent(`array-inner/${compDir}/del4.bal.txt`, projectFile)).toBeTruthy(); + } + + export async function testArrayRootMappings(dmWebView: Frame, projectFile: string, compDir: string, needRefresh?: boolean) { + console.log('Test Array Root Mappings'); + + const dm = new DataMapper(dmWebView); + await dm.waitFor(); + + await dm.expandField('input'); + + if (needRefresh) { + await dm.refresh(); + } + + console.log(' - Input/Output preview'); + + await dmWebView.getByText('').waitFor(); + await dmWebView.getByText('*').waitFor(); + + console.log(' - Map roots using query expression'); + + await dm.mapFields('input', 'arrayOutput.output', 'a2a-inner'); + await dmWebView.getByTestId('link-from-input.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-queryOutput.output.#.IN').waitFor({ state: 'attached' }); + + + console.log(' - Map using query expression within focused view'); + await dm.mapFields('inputItem.iArr1D', 'queryOutput.output.oArr1D', 'a2a-inner'); + + console.log(' - Map within inner focused view'); + await dm.mapFields('iArr1DItem.p2', 'queryOutput.oArr1D.p2'); + const loc1 = dmWebView.getByTestId('link-from-iArr1DItem.p2.OUT-to-queryOutput.oArr1D.p2.IN'); + await dm.expectErrorLink(loc1); + + await dm.mapFields('iArr1DItem.p2', 'queryOutput.oArr1D.p1'); + await dm.mapFields('iArr1DItem.p3', 'queryOutput.oArr1D.p1'); + + await dmWebView.getByTestId('link-from-iArr1DItem.p2.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-iArr1DItem.p3.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-queryOutput.oArr1D.p1.IN').waitFor({ state: 'attached' }); + + const loc2 = dmWebView.getByTestId('link-connector-node-queryOutput.oArr1D.p1.IN'); + await loc2.waitFor(); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/map1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Go back to intermediate focused view (using back button)'); + await dm.goPrevViewBackButton(); + const loc0 = dmWebView.getByTestId('link-connector-node-queryOutput.output.oArr1D.IN'); + await loc0.waitFor(); + + console.log(' - Goto inner focused view again'); + await dmWebView.getByTestId('expand-array-fn-output.oArr1D').click(); + await dmWebView.getByTestId('link-from-inputItem.iArr1D.OUT-to-datamapper-intermediate-port').waitFor({ state: 'attached' }); + await dmWebView.getByTestId('link-from-datamapper-intermediate-port-to-queryOutput.oArr1D.#.IN').waitFor({ state: 'attached' }); + + console.log(' - Delete within inner focused view'); + await loc1.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-iArr1DItem.p2.OUT-to-queryOutput.oArr1D.p2.IN') + .locator('.codicon-trash').click({ force: true }); + await loc1.waitFor({ state: 'detached' }); + + await loc2.locator('.codicon-trash').click({ force: true }); + await loc2.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/del1.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Map roots within inner focused view'); + await dm.mapFields('iArr1DItem', 'queryOutput.oArr1D', 'direct'); + const loc3 = dmWebView.getByTestId('link-from-iArr1DItem.OUT-to-queryOutput.oArr1D.IN'); + await loc3.waitFor(); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/map2.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete root mapping within inner focused view'); + await loc3.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-iArr1DItem.OUT-to-queryOutput.oArr1D.IN') + .locator('.codicon-trash').click({ force: true }); + await loc3.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/del2.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Go back to intermediate focused view (using back button)'); + await dm.goPrevViewBackButton(); + + console.log(' - Delete intermediate query expression'); + await loc0.locator('.codicon-trash').click({ force: true }); + await loc0.waitFor({ state: 'detached' }); + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/del3.bal.txt`, projectFile)).toBeTruthy(); + + + console.log(' - Go back to root view (using breadcrumb)'); + await dm.goPrevViewBreadcrumb(); + + const loc4 = dmWebView.getByTestId('link-connector-node-arrayOutput.output.IN'); + await loc4.waitFor(); + + console.log(' - Delete root mapping'); + await loc4.locator('.codicon-trash').click({ force: true }); + await loc4.waitFor({ state: 'detached' }); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/del4.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Add element to root array using config menu'); + + await dm.selectConfigMenuItem('arrayOutput.output', 'Add Element'); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-arrayOutput.output.0"]').waitFor(); + + await dmWebView.getByTestId('array-widget-arrayOutput.output.IN-add-element').click(); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-arrayOutput.output.1"]').waitFor(); + + console.log(' - Map to root array elements'); + await dm.expandField('input'); + await dm.mapFields('input', 'arrayOutput.output.0.oArr1D', 'a2a-direct'); + const loc5 = dmWebView.getByTestId('link-from-input.OUT-to-arrayOutput.output.0.oArr1D.IN'); + await dm.expectErrorLink(loc5); + + await dm.mapFields('input', 'arrayOutput.output.1.oArr1D', 'a2a-direct'); + await dm.expectErrorLink(dmWebView.getByTestId('link-from-input.OUT-to-arrayOutput.output.1.oArr1D.IN')); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/map3.bal.txt`, projectFile)).toBeTruthy(); + + console.log(' - Delete root array element mapping, entire element and entire root array'); + await loc5.click({ force: true }); + await dmWebView.getByTestId('expression-label-for-input.OUT-to-arrayOutput.output.0.oArr1D.IN') + .locator('.codicon-trash').click({ force: true }); + await loc5.waitFor({ state: 'detached' }); + + await dm.selectConfigMenuItem('arrayOutput.output.1', 'Delete Element'); + await dm.waitForProgressEnd(); + await dmWebView.locator('div[id="recordfield-arrayOutput.output.1"]').waitFor({ state: 'detached' }); + + await dm.selectConfigMenuItem('arrayOutput.output', 'Delete Array'); + await dm.waitForProgressEnd(); + await dmWebView.getByText('*').waitFor(); + + expect(await FileUtils.verifyFileContent(`array-root/${compDir}/del5.bal.txt`, projectFile)).toBeTruthy(); + + } + +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del1.bal.txt new file mode 100644 index 00000000000..42cf355444e --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del1.bal.txt @@ -0,0 +1,14 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: from var iArr1DItem in input.iArr1D + select {} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del2.bal.txt new file mode 100644 index 00000000000..42cf355444e --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del2.bal.txt @@ -0,0 +1,14 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: from var iArr1DItem in input.iArr1D + select {} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del3.bal.txt new file mode 100644 index 00000000000..6d534a57d28 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del3.bal.txt @@ -0,0 +1,13 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: [{p2: ""}] + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del4.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del4.bal.txt new file mode 100644 index 00000000000..4851d21b3f3 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/del4.bal.txt @@ -0,0 +1,13 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/init.bal.txt new file mode 100644 index 00000000000..595da7ca19a --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/init.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = {}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map1.bal.txt new file mode 100644 index 00000000000..61d8200eb3f --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map1.bal.txt @@ -0,0 +1,14 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: from var iArr1DItem in input.iArr1D + select {p1: iArr1DItem.p2 + iArr1DItem.p3, p2: iArr1DItem.p2} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map2.bal.txt new file mode 100644 index 00000000000..7358c212649 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map2.bal.txt @@ -0,0 +1,14 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: from var iArr1DItem in input.iArr1D + select iArr1DItem + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt new file mode 100644 index 00000000000..7a3cf6b44f1 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/inline/map3.bal.txt @@ -0,0 +1,13 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = { + oArr1D: [{p1: input.p1, p2: ""}, {p1: input.p2, p2: ""}, input.p1] + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del1.bal.txt new file mode 100644 index 00000000000..c9b299e9628 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del1.bal.txt @@ -0,0 +1,4 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: from var iArr1DItem in input.iArr1D + select {} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del2.bal.txt new file mode 100644 index 00000000000..c9b299e9628 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del2.bal.txt @@ -0,0 +1,4 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: from var iArr1DItem in input.iArr1D + select {} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del3.bal.txt new file mode 100644 index 00000000000..841ab9e21b9 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del3.bal.txt @@ -0,0 +1,3 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: [{p2: ""}] +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del4.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del4.bal.txt new file mode 100644 index 00000000000..d3e136bdc5b --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/del4.bal.txt @@ -0,0 +1,3 @@ +function output(InRoot input) returns OutRoot => { + +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/init.bal.txt new file mode 100644 index 00000000000..d0da11940ff --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/init.bal.txt @@ -0,0 +1,3 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: [] +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map1.bal.txt new file mode 100644 index 00000000000..1a98c6044c3 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map1.bal.txt @@ -0,0 +1,4 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: from var iArr1DItem in input.iArr1D + select {p1: iArr1DItem.p2 + iArr1DItem.p3, p2: iArr1DItem.p2} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map2.bal.txt new file mode 100644 index 00000000000..3740c904baf --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map2.bal.txt @@ -0,0 +1,4 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: from var iArr1DItem in input.iArr1D + select iArr1DItem +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map3.bal.txt new file mode 100644 index 00000000000..5199059fa72 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/reusable/map3.bal.txt @@ -0,0 +1,3 @@ +function output(InRoot input) returns OutRoot => { + oArr1D: [{p1: input.p1, p2: ""}, {p1: input.p2, p2: ""}, input.p1] +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/types.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/types.bal.txt new file mode 100644 index 00000000000..24e5d734491 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-inner/types.bal.txt @@ -0,0 +1,21 @@ +type InRoot record {| + InArrType[] iArr1D; + string p1; + int p2; +|}; + +type InArrType record {| + string p1; + int p2; + int p3; +|}; + +type OutRoot record {| + OutArrType[] oArr1D; +|}; + +type OutArrType record {| + int p1; + string p2; +|}; + diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del1.bal.txt new file mode 100644 index 00000000000..39e3290c230 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del1.bal.txt @@ -0,0 +1,15 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del2.bal.txt new file mode 100644 index 00000000000..39e3290c230 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del2.bal.txt @@ -0,0 +1,15 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del3.bal.txt new file mode 100644 index 00000000000..1a3253bbdb0 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del3.bal.txt @@ -0,0 +1,14 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = from var inputItem in input + select { + + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del4.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del4.bal.txt new file mode 100644 index 00000000000..b99effb4779 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del4.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = []; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del5.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del5.bal.txt new file mode 100644 index 00000000000..b99effb4779 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/del5.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = []; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/init.bal.txt new file mode 100644 index 00000000000..b99effb4779 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/init.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = []; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map1.bal.txt new file mode 100644 index 00000000000..b64a25d5b07 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map1.bal.txt @@ -0,0 +1,15 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {p1: iArr1DItem.p2 + iArr1DItem.p3, p2: iArr1DItem.p2} + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map2.bal.txt new file mode 100644 index 00000000000..e5e19b228ac --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map2.bal.txt @@ -0,0 +1,15 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select iArr1DItem + }; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map3.bal.txt new file mode 100644 index 00000000000..4a4b9c3f886 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/inline/map3.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot[] input = []; + OutRoot[] output = [{oArr1D: input}, {oArr1D: input}]; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del1.bal.txt new file mode 100644 index 00000000000..aa85c4d9f3d --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del1.bal.txt @@ -0,0 +1,5 @@ +function output(InRoot[] input) returns OutRoot[] => from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {} + }; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del2.bal.txt new file mode 100644 index 00000000000..aa85c4d9f3d --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del2.bal.txt @@ -0,0 +1,5 @@ +function output(InRoot[] input) returns OutRoot[] => from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {} + }; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del3.bal.txt new file mode 100644 index 00000000000..228eb8fdef5 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del3.bal.txt @@ -0,0 +1,4 @@ +function output(InRoot[] input) returns OutRoot[] => from var inputItem in input + select { + + }; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del4.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del4.bal.txt new file mode 100644 index 00000000000..84f5fc20bda --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del4.bal.txt @@ -0,0 +1 @@ +function output(InRoot[] input) returns OutRoot[] => []; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del5.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del5.bal.txt new file mode 100644 index 00000000000..84f5fc20bda --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/del5.bal.txt @@ -0,0 +1 @@ +function output(InRoot[] input) returns OutRoot[] => []; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/init.bal.txt new file mode 100644 index 00000000000..84f5fc20bda --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/init.bal.txt @@ -0,0 +1 @@ +function output(InRoot[] input) returns OutRoot[] => []; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map1.bal.txt new file mode 100644 index 00000000000..dead90b25d9 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map1.bal.txt @@ -0,0 +1,5 @@ +function output(InRoot[] input) returns OutRoot[] => from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select {p1: iArr1DItem.p2 + iArr1DItem.p3, p2: iArr1DItem.p2} + }; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map2.bal.txt new file mode 100644 index 00000000000..8fd83d8de1c --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map2.bal.txt @@ -0,0 +1,5 @@ +function output(InRoot[] input) returns OutRoot[] => from var inputItem in input + select { + oArr1D: from var iArr1DItem in inputItem.iArr1D + select iArr1DItem + }; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map3.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map3.bal.txt new file mode 100644 index 00000000000..49276df27a2 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/reusable/map3.bal.txt @@ -0,0 +1 @@ +function output(InRoot[] input) returns OutRoot[] => [{oArr1D: input}, {oArr1D: input}]; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/types.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/types.bal.txt new file mode 100644 index 00000000000..24e5d734491 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/array-root/types.bal.txt @@ -0,0 +1,21 @@ +type InRoot record {| + InArrType[] iArr1D; + string p1; + int p2; +|}; + +type InArrType record {| + string p1; + int p2; + int p3; +|}; + +type OutRoot record {| + OutArrType[] oArr1D; +|}; + +type OutArrType record {| + int p1; + string p2; +|}; + diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del1.bal.txt new file mode 100644 index 00000000000..4c47abd0c34 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del1.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = {oObjDirect: input.iObjDirect, oObjDirectErr: input.iObjDirect, oObjProp: {p2: input.iObjProp.op2}}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del2.bal.txt new file mode 100644 index 00000000000..595da7ca19a --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/del2.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = {}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/init.bal.txt new file mode 100644 index 00000000000..595da7ca19a --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/init.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = {}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map1.bal.txt new file mode 100644 index 00000000000..0a0b4952ab6 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map1.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = {oPrimDirect: input.iPrimDirect, oPrimDirectErr: input.iPrimDirectErr, oManyOne: input.iManyOne1 + input.iManyOne2 + input.iManyOne3, oManyOneErr: input.iManyOneErr1 + input.iPrimDirectErr + input.iManyOneErr2, oObjDirect: input.iObjDirect, oObjDirectErr: input.iObjDirect, oObjProp: {p1: input.iObjDirect.d1, p2: input.iObjProp.op2}}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map2.bal.txt new file mode 100644 index 00000000000..ae2519c2893 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/inline/map2.bal.txt @@ -0,0 +1,11 @@ +import ballerina/log; + +public function main() returns error? { + do { + InRoot input = {}; + OutRoot output = input; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del1.bal.txt new file mode 100644 index 00000000000..26dbf561f12 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del1.bal.txt @@ -0,0 +1,5 @@ +function output(InRoot input) returns OutRoot => { + oObjDirect: input.iObjDirect, + oObjDirectErr: input.iObjDirect, + oObjProp: {p2: input.iObjProp.op2} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del2.bal.txt new file mode 100644 index 00000000000..ee72fbef326 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/del2.bal.txt @@ -0,0 +1 @@ +function output(InRoot input) returns OutRoot => {}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/init.bal.txt new file mode 100644 index 00000000000..689f2044213 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/init.bal.txt @@ -0,0 +1,9 @@ +function output(InRoot input) returns OutRoot => { + oManyOneErr: 0, + oPrimDirect: "", + oObjDirect: {d1: "", d2: 0}, + oManyOne: "", + oPrimDirectErr: 0, + oObjDirectErr: {d1: "", d2: ""}, + oObjProp: {p1: "", p2: 0} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map1.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map1.bal.txt new file mode 100644 index 00000000000..6cae71d775a --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map1.bal.txt @@ -0,0 +1,9 @@ +function output(InRoot input) returns OutRoot => { + oManyOneErr: input.iManyOneErr1 + input.iPrimDirectErr + input.iManyOneErr2, + oPrimDirect: input.iPrimDirect, + oObjDirect: input.iObjDirect, + oManyOne: input.iManyOne1 + input.iManyOne2 + input.iManyOne3, + oPrimDirectErr: input.iPrimDirectErr, + oObjDirectErr: input.iObjDirect, + oObjProp: {p1: input.iObjDirect.d1, p2: input.iObjProp.op2} +}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map2.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map2.bal.txt new file mode 100644 index 00000000000..3f89afa71ab --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/reusable/map2.bal.txt @@ -0,0 +1 @@ +function output(InRoot input) returns OutRoot => input; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/types.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/types.bal.txt new file mode 100644 index 00000000000..146660364b6 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/basic/types.bal.txt @@ -0,0 +1,46 @@ +type InRoot record {| + string iPrimDirect; + string iPrimDirectErr; + string iManyOne1; + string iManyOne2; + string iManyOne3; + int iManyOneErr1; + boolean iManyOneErr2; + InObjDirect iObjDirect; + InObjProp iObjProp; +|}; + +type InObjDirect record {| + string d1; + int d2; +|}; + +type InObjProp record {| + string op1; + string op2; +|}; + +type OutRoot record {| + string oPrimDirect; + int oPrimDirectErr; + string oManyOne; + int oManyOneErr; + OutObjDirect oObjDirect; + OutObjDirectErr oObjDirectErr; + OutObjProp oObjProp; +|}; + +type OutObjDirect record {| + string d1; + int d2; +|}; + +type OutObjDirectErr record {| + string d1; + string d2; +|}; + +type OutObjProp record {| + string p1; + int p2; +|}; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/final.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/final.bal.txt new file mode 100644 index 00000000000..ba011d6a16f --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/final.bal.txt @@ -0,0 +1,10 @@ +import ballerina/log; + +public function main() returns error? { + do { + OutRoot var1 = {}; + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/init.bal.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/init.bal.txt new file mode 100644 index 00000000000..e36260a4a5d --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/create/inline/init.bal.txt @@ -0,0 +1,9 @@ +import ballerina/log; + +public function main() returns error? { + do { + } on fail error e { + log:printError("Error occurred", 'error = e); + return e; + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/empty.txt b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/dm-data/empty.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/inline-data-mapper.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/inline-data-mapper.spec.ts new file mode 100644 index 00000000000..6ec620b4aee --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/inline-data-mapper.spec.ts @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { initTest, page } from '../utils/helpers'; +import { switchToIFrame } from '@wso2/playwright-vscode-tester'; +import { Diagram, ProjectExplorer } from '../utils/pages'; +import { TestScenarios, FileUtils } from './DataMapperUtils'; + +export default function createTests() { + test.describe('Inline Data Mapper Tests', { + tag: '@group1', + }, async () => { + initTest(); + test('Create', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Inline Data Mapper - Create: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('basic/types.bal.txt', 'types.bal'); + FileUtils.updateProjectFileSync('create/inline/init.bal.txt', 'automation.bal'); + + console.log(' - Add Declare Variable Node'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const projectExplorer = new ProjectExplorer(page.page); + await projectExplorer.refresh('sample'); + + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'main' }).click(); + + await webView.getByRole('heading', { name: 'Automation' }).waitFor(); + + // Add a node to the diagram + const diagram = new Diagram(page.page); + await diagram.init(); + await diagram.clickAddButtonByIndex(1); + + await webView.getByText('Declare Variable').click(); + + const varType = webView.getByRole('textbox', { name: 'Type' }); + await varType.click(); + await webView.getByText('OutRoot').click(); + await expect(varType).toHaveValue('OutRoot'); + + await webView.getByRole('button', { name: 'Open in Data Mapper' }).click(); + + console.log(' - Wait for Data Mapper to open'); + await webView.locator('#data-mapper-canvas-container').waitFor(); + + await FileUtils.verifyFileContent('create/inline/final.bal.txt', 'automation.bal'); + + console.log(' - Go back to overview (using back button)'); + await webView.getByTestId('back-button').click(); + await webView.getByRole('heading', { name: 'Automation' }).waitFor(); + await webView.getByTestId('back-button').click(); + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + + console.log('Inline Data Mapper - Create: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Basic', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Inline Data Mapper - Basic: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('basic/inline/init.bal.txt', 'automation.bal'); + FileUtils.updateProjectFileSync('basic/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'main' }).click(); + + await webView.getByRole('heading', { name: 'Automation' }).waitFor(); + await webView.getByText('output = {}').click(); + await webView.getByRole('button', { name: 'Open in Data Mapper' }).click(); + } + + await TestScenarios.testBasicMappings(webView, 'automation.bal', 'inline', isDataMapperOpened); + + console.log('Inline Data Mapper - Basic: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Array Inner', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Inline Data Mapper - Array Inner: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('array-inner/inline/init.bal.txt', 'automation.bal'); + FileUtils.updateProjectFileSync('array-inner/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'main' }).click(); + + await webView.getByRole('heading', { name: 'Automation' }).waitFor(); + await webView.getByText('output = {}').click(); + await webView.getByRole('button', { name: 'Open in Data Mapper' }).click(); + } + + await TestScenarios.testArrayInnerMappings(webView, 'automation.bal', 'inline', isDataMapperOpened); + + console.log('Inline Data Mapper - Array Inner: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Array Root', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Inline Data Mapper - Array Root: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('array-root/inline/init.bal.txt', 'automation.bal'); + FileUtils.updateProjectFileSync('array-root/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'main' }).click(); + + await webView.getByRole('heading', { name: 'Automation' }).waitFor(); + await webView.getByText('output = []').click(); + await webView.getByRole('button', { name: 'Open in Data Mapper' }).click(); + } + + await TestScenarios.testArrayRootMappings(webView, 'automation.bal', 'inline', isDataMapperOpened); + + console.log('Inline Data Mapper - Array Root: COMPLETE TEST ATTEMPT', testAttempt); + }); + }); +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/reusable-data-mapper.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/reusable-data-mapper.spec.ts new file mode 100644 index 00000000000..a97e6201c1a --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/data-mapper/reusable-data-mapper.spec.ts @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { initTest, page } from '../utils/helpers'; +import { switchToIFrame } from '@wso2/playwright-vscode-tester'; +import { TestScenarios, FileUtils } from './DataMapperUtils'; + +export default function createTests() { + test.describe('Reusable Data Mapper Tests', { + tag: '@group1', + }, async () => { + initTest(); + test('Create', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Reusable Data Mapper - Create: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('basic/types.bal.txt', 'types.bal'); + FileUtils.updateProjectFileSync('empty.txt', 'data_mappings.bal'); + + console.log(' - Create reusable Data Mapper'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + await page.page.getByRole('treeitem', { name: 'Data Mappers' }).hover(); + await page.page.getByLabel('Add Data Mapper').click(); + + await webView.getByRole('textbox', { name: 'Data Mapper Name*Name of the' }).fill('output'); + + const outputType = webView.getByRole('textbox', { name: 'Output' }); + await outputType.click({ force: true }); + await webView.getByText('OutRoot').click({ force: true }); + await expect(outputType).toHaveValue('OutRoot'); + + await webView.getByText('Add Input').click(); + const inputType = webView.getByRole('textbox', { name: 'Type' }); + await inputType.click(); + await webView.getByText('InRoot').click(); + await expect(inputType).toHaveValue('InRoot'); + + await webView.getByRole('textbox', { name: 'Name*Name of the parameter' }).click(); + await webView.getByRole('textbox', { name: 'Name*Name of the parameter' }).fill('input'); + await webView.getByRole('button', { name: 'Add' }).click(); + await webView.getByTestId('input-item').waitFor(); + + await webView.getByRole('button', { name: 'Create', exact: true }).click(); + + console.log(' - Wait for Data Mapper to open'); + await webView.locator('#data-mapper-canvas-container').waitFor(); + + await FileUtils.verifyFileContent('basic/reusable/init.bal.txt', 'data_mappings.bal'); + + console.log('Reusable Data Mapper - Create: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Basic', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Reusable Data Mapper - Basic: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('basic/reusable/init.bal.txt', 'data_mappings.bal'); + FileUtils.updateProjectFileSync('basic/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'output' }).click(); + } + + await TestScenarios.testBasicMappings(webView, 'data_mappings.bal', 'reusable', isDataMapperOpened); + + console.log('Reusable Data Mapper - Basic: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Array Inner', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Reusable Data Mapper - Array Inner: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('array-inner/reusable/init.bal.txt', 'data_mappings.bal'); + FileUtils.updateProjectFileSync('array-inner/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'output' }).click(); + } + + await TestScenarios.testArrayInnerMappings(webView, 'data_mappings.bal', 'reusable', isDataMapperOpened); + + console.log('Reusable Data Mapper - Array Inner: COMPLETE TEST ATTEMPT', testAttempt); + }); + + test('Array Root', async ({ }, testInfo) => { + const testAttempt = testInfo.retry + 1; + + console.log('Reusable Data Mapper - Array Root: START TEST ATTEMPT', testAttempt); + + FileUtils.updateProjectFileSync('array-root/reusable/init.bal.txt', 'data_mappings.bal'); + FileUtils.updateProjectFileSync('array-root/types.bal.txt', 'types.bal'); + + const webView = await switchToIFrame('WSO2 Integrator: BI', page.page); + if (!webView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + + const isDataMapperOpened = await webView.getByRole('heading', { name: 'Data Mapper' }).isVisible(); + if (!isDataMapperOpened) { + await webView.getByRole('heading', { name: 'sample' }).waitFor(); + await page.page.getByRole('treeitem', { name: 'output' }).click(); + } + + await TestScenarios.testArrayRootMappings(webView, 'data_mappings.bal', 'reusable', isDataMapperOpened); + + console.log('Reusable Data Mapper - Array Root: COMPLETE TEST ATTEMPT', testAttempt); + }); + }); +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/azure.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/azure.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/azure.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/azure.spec.ts index 24b99831ed3..f9c75dfc4be 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/azure.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/azure.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Azure Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/github.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/github.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/github.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/github.spec.ts index fe9ec768a02..6926c4aa081 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/github.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/github.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Github Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/kafka.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/kafka.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/kafka.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/kafka.spec.ts index e5d7b0fde7c..58afe511c15 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/kafka.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/kafka.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Kafka Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/mqtt.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/mqtt.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/mqtt.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/mqtt.spec.ts index 85041e244c6..524bf8625e2 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/mqtt.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/mqtt.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('MQTT Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/rabbitmq.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/rabbitmq.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/rabbitmq.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/rabbitmq.spec.ts index 8f9dd4d7334..d8cf0c9d1b4 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/rabbitmq.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/rabbitmq.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('RabbitMQ Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/salesforce.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/salesforce.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/salesforce.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/salesforce.spec.ts index fe245089338..809705cf3b8 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/salesforce.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/salesforce.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Salesforce Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/twillio.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/twillio.spec.ts similarity index 98% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/twillio.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/twillio.spec.ts index 1cf2ce709b6..59364a12faa 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integrations/twillio.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/event-integration/twillio.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Twillio Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/expression-editor/expression-editor.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/expression-editor/expression-editor.spec.ts index 1f39c0e7004..f72c3765e47 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/expression-editor/expression-editor.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/expression-editor/expression-editor.spec.ts @@ -17,10 +17,9 @@ */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { Diagram } from '../components/Diagram'; -import { SidePanel } from '../components/SidePanel'; +import { Diagram, SidePanel } from '../utils/pages'; export default function createTests() { test.describe('Expression Editor Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/directory.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/directory.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/directory.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/directory.spec.ts index 4aa832770da..b873f309915 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/directory.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/directory.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Directory Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/ftp.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/ftp.spec.ts similarity index 97% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/ftp.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/ftp.spec.ts index 486d8dce359..59f0b9212d9 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integrations/ftp.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/file-integration/ftp.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('FTP Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/import-integration/import-integration.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/import-integration/import-integration.spec.ts index 99177dd24c1..7b1f6e0be6f 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/import-integration/import-integration.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/import-integration/import-integration.spec.ts @@ -19,7 +19,7 @@ import { test } from '@playwright/test'; import { Form } from '@wso2/playwright-vscode-tester'; import fs from 'fs'; import path from 'path'; -import { getWebview, initMigrationTest, page } from '../utils'; +import { getWebview, initMigrationTest, page } from '../utils/helpers'; export default function createTests() { test.describe('Import Integration Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/connection.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/connection.spec.ts index a65050eb2a7..ea40164a573 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/connection.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/connection.spec.ts @@ -18,9 +18,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Connection Artifact Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/data-mapper.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/data-mapper.spec.ts index 4bd5e99dc29..9ddeca96fd9 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/data-mapper.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/data-mapper.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Data Mapper Artifact Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/function.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/function.spec.ts index ab87ba4c617..7d2d39d5b33 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/function.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/function.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Function Artifact Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/np.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/np.spec.ts index 77aea89a927..d556b600a6d 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/np.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/np.spec.ts @@ -17,9 +17,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Natural Function Artifact Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/type.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/type.spec.ts index 7de82f3a02d..6466de905aa 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/type.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/other-artifacts/type.spec.ts @@ -18,9 +18,9 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page } from '../utils'; +import { addArtifact, initTest, page } from '../utils/helpers'; import { Form, switchToIFrame } from '@wso2/playwright-vscode-tester'; -import { ProjectExplorer } from '../ProjectExplorer'; +import { ProjectExplorer } from '../utils/pages'; export default function createTests() { test.describe('Type Diagram Artifact Tests', { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-class-designer/service-class.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-designer/service-class.spec.ts similarity index 99% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-class-designer/service-class.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-designer/service-class.spec.ts index 2326d863479..32846f6e833 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-class-designer/service-class.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-designer/service-class.spec.ts @@ -16,7 +16,7 @@ * under the License. */ import { test } from '@playwright/test'; -import { addArtifact, getWebview, initTest, page } from '../utils'; +import { addArtifact, getWebview, initTest, page } from '../utils/helpers'; import { ServiceClassEditorUtils } from './serviceEditorUtils'; export default function createTests() { diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-class-designer/serviceEditorUtils.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-designer/serviceEditorUtils.ts similarity index 100% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-class-designer/serviceEditorUtils.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/service-designer/serviceEditorUtils.ts diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/template/template.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/template/template.spec.ts deleted file mode 100644 index 34594150411..00000000000 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/template/template.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. - * - * 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 { test } from '@playwright/test'; -import { initTest, page } from '../utils'; -import { switchToIFrame } from '@wso2/playwright-vscode-tester'; - -export default function createTests() { - test.describe('Sample Tests', { - tag: '@group1', - }, async () => { - initTest(); - test('Sample Test', async ({ }, testInfo) => { - const testAttempt = testInfo.retry + 1; - console.log('Sample test attempt: ', testAttempt); - const artifactWebView = await switchToIFrame('WSO2 Integrator: BI', page.page, 30000); - if (!artifactWebView) { - throw new Error('WSO2 Integrator: BI webview not found'); - } - // Add test implementation here - }); - }); -} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/test.list.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/test.list.ts index b9fe8411782..03edc3d8b19 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/test.list.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/test.list.ts @@ -17,28 +17,28 @@ */ import { test } from '@playwright/test'; -import { page } from './utils'; +import { page } from './utils/helpers'; const fs = require('fs'); const path = require('path'); const videosFolder = path.join(__dirname, '..', 'test-resources', 'videos'); import automation from './automation/automation.spec'; -import httpService from './api-services/http-service.spec'; -import aiChatService from './api-services/ai-chat-service.spec'; -import graphqlService from './api-services/graphql-service.spec'; -import tcpService from './api-services/tcp-service.spec'; +import httpService from './api-integration/http-service.spec'; +import aiChatService from './api-integration/ai-chat-service.spec'; +import graphqlService from './api-integration/graphql-service.spec'; +import tcpService from './api-integration/tcp-service.spec'; -import kafkaIntegration from './event-integrations/kafka.spec'; -import rabbitmqIntegration from './event-integrations/rabbitmq.spec'; -import mqttIntegration from './event-integrations/mqtt.spec'; -import azureIntegration from './event-integrations/azure.spec'; -import salesforceIntegration from './event-integrations/salesforce.spec'; -import twillioIntegration from './event-integrations/twillio.spec'; -import githubIntegration from './event-integrations/github.spec'; +import kafkaIntegration from './event-integration/kafka.spec'; +import rabbitmqIntegration from './event-integration/rabbitmq.spec'; +import mqttIntegration from './event-integration/mqtt.spec'; +import azureIntegration from './event-integration/azure.spec'; +import salesforceIntegration from './event-integration/salesforce.spec'; +import twillioIntegration from './event-integration/twillio.spec'; +import githubIntegration from './event-integration/github.spec'; -import ftpIntegration from './file-integrations/ftp.spec'; -import directoryIntegration from './file-integrations/directory.spec'; +import ftpIntegration from './file-integration/ftp.spec'; +import directoryIntegration from './file-integration/directory.spec'; import functionArtifact from './other-artifacts/function.spec'; import naturalFunctionArtifact from './other-artifacts/np.spec'; @@ -46,11 +46,14 @@ import typeDiagramArtifact from './other-artifacts/type.spec'; import connectionArtifact from './other-artifacts/connection.spec'; import configuration from './configuration/configuration.spec'; -import typeTest from './type/type.spec'; -import serviceTest from './service-class-designer/service-class.spec'; +import typeTest from './type-editor/type.spec'; +import serviceTest from './service-designer/service-class.spec'; import importIntegration from './import-integration/import-integration.spec'; +import reusableDataMapper from './data-mapper/reusable-data-mapper.spec'; +import inlineDataMapper from './data-mapper/inline-data-mapper.spec'; + test.describe.configure({ mode: 'default' }); test.beforeAll(async () => { @@ -95,9 +98,14 @@ test.describe(connectionArtifact); test.describe(configuration); // TODO: This tests is failing due to https://github.com/wso2/product-ballerina-integrator/issues/1231. Enable after fixing the issue. test.describe(typeTest); // TODO: This tests is failing due to https://github.com/wso2/product-ballerina-integrator/issues/1222. Enable after fixing the issue. test.describe(serviceTest); + // <----Import Integration Test----> test.describe(importIntegration); +// <----Data Mapper Test----> +test.describe(reusableDataMapper); +test.describe(inlineDataMapper); + test.afterAll(async () => { console.log('\n' + '='.repeat(80)); console.log('✅ BI EXTENSION E2E TEST SUITE COMPLETED'); diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/TypeEditorUtils.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/TypeEditorUtils.ts similarity index 100% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/TypeEditorUtils.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/TypeEditorUtils.ts diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/testOutput.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/testOutput.bal similarity index 100% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/testOutput.bal rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/testOutput.bal diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/type.spec.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/type.spec.ts similarity index 99% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/type.spec.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/type.spec.ts index 040cfa52d65..59dc039921b 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type/type.spec.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/type-editor/type.spec.ts @@ -17,7 +17,7 @@ */ import { test } from '@playwright/test'; -import { addArtifact, initTest, page, getWebview, verifyGeneratedSource } from '../utils'; +import { addArtifact, initTest, page, getWebview, verifyGeneratedSource } from '../utils/helpers'; import { Form } from '@wso2/playwright-vscode-tester'; import { TypeEditorUtils } from './TypeEditorUtils'; import path from 'path'; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/Ballerina.toml b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/Ballerina.toml new file mode 100644 index 00000000000..82389a78257 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/Ballerina.toml @@ -0,0 +1,7 @@ +[package] +org = "nino" +name = "sample" +version = "0.1.0" + +[build-options] +sticky = true \ No newline at end of file diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/agents.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/agents.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/config.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/config.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/connections.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/connections.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/data_mappings.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/data_mappings.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/functions.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/functions.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/main.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/main.bal new file mode 100644 index 00000000000..9db45286b81 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/main.bal @@ -0,0 +1,13 @@ +import ballerina/http; + +listener http:Listener httpDefaultListener = http:getDefaultListener(); + +service /foo on httpDefaultListener { + resource function get greeting() returns error|json|http:InternalServerError { + do { + } on fail error err { + // handle error + return error("unhandled error", err); + } + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/types.bal b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/data/new-project/testProject/sample/types.bal new file mode 100644 index 00000000000..e69de29bb2d diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/artifacts.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/artifacts.ts new file mode 100644 index 00000000000..f7f10071f4b --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/artifacts.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { getWebview } from "./webview"; +import { page } from "./setup"; + +/** + * Add an artifact to the project + */ +export async function addArtifact(artifactName: string, testId: string) { + console.log(`Adding artifact: ${artifactName}`); + const artifactWebView = await getWebview('WSO2 Integrator: BI', page); + if (!artifactWebView) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + // Navigate to the overview page + await artifactWebView.getByRole('button', { name: ' Add Artifact' }).click(); + // how to get element by id + const addArtifactBtn = artifactWebView.locator(`#${testId}`); + await addArtifactBtn.waitFor(); + await addArtifactBtn.click(); +} + +/** + * Enable ICP (Integration Control Plane) + */ +export async function enableICP() { + console.log('Enabling ICP'); + const webview = await getWebview('WSO2 Integrator: BI', page); + if (!webview) { + throw new Error('WSO2 Integrator: BI webview not found'); + } + const icpToggle = webview.getByRole('checkbox', { name: 'Enable WSO2 Integrator: ICP' }); + await icpToggle.waitFor(); + if (!(await icpToggle.isChecked())) { + await icpToggle.click(); + } +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/index.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/index.ts new file mode 100644 index 00000000000..c761a2dc9d6 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/index.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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. + */ + +// Re-export from setup +export { + page, + vscode, + resourcesFolder, + newProjectPath, + initTest, + initMigrationTest, + createProject, + setupBallerinaIntegrator, + toggleNotifications +} from './setup'; + +// Re-export from webview +export { getWebview } from './webview'; + +// Re-export from artifacts +export { addArtifact, enableICP } from './artifacts'; + +// Re-export from verification +export { verifyGeneratedSource } from './verification'; diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/setup.ts similarity index 67% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/setup.ts index b95231e3c65..f7c96eb2361 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/setup.ts @@ -15,19 +15,21 @@ * specific language governing permissions and limitations * under the License. */ + import { ExtendedPage, Form, startVSCode, switchToIFrame } from "@wso2/playwright-vscode-tester"; import { test } from '@playwright/test'; import fs, { existsSync } from 'fs'; import path from 'path'; import { exec } from 'child_process'; import { promisify } from 'util'; +import { getWebview } from './webview'; -const dataFolder = path.join(__dirname, 'data'); -const extensionsFolder = path.join(__dirname, '..', '..', '..', 'vsix'); +const dataFolder = path.join(__dirname, '..', 'data'); +const extensionsFolder = path.join(__dirname, '..', '..', '..', '..', '..', 'vsix'); const vscodeVersion = 'latest'; -export const resourcesFolder = path.join(__dirname, '..', 'test-resources'); +export const resourcesFolder = path.join(__dirname, '..', '..', '..', 'test-resources'); export const newProjectPath = path.join(dataFolder, 'new-project', 'testProject'); -export let vscode; +export let vscode: any; export let page: ExtendedPage; const execAsync = promisify(exec); @@ -68,7 +70,7 @@ async function resumeVSCode() { await page.executePaletteCommand('Reload Window'); } else { console.log('Starting VSCode'); - vscode = await startVSCode(resourcesFolder, vscodeVersion, undefined, false, extensionsFolder, path.join(newProjectPath, 'testProject'), 'bi-test-profile'); + vscode = await startVSCode(resourcesFolder, vscodeVersion, undefined, false, extensionsFolder, path.join(newProjectPath, 'sample'), 'bi-test-profile'); await new Promise(resolve => setTimeout(resolve, 5000)); } page = new ExtendedPage(await vscode!.firstWindow({ timeout: 60000 })); @@ -120,47 +122,6 @@ export async function setupBallerinaIntegrator() { } } -export async function getWebview(viewName: string, page: ExtendedPage) { - let webview; - let retryCount = 0; - const maxRetries = 3; - - while (retryCount < maxRetries) { - try { - await page.page.waitForLoadState('domcontentloaded'); - await page.page.waitForTimeout(1000); - - webview = await switchToIFrame(viewName, page.page); - if (webview) { - return webview; - } - // If webview is falsy, treat it as a failed attempt - console.log(`Attempt ${retryCount + 1} failed: switchToIFrame returned ${webview}`); - } catch (error) { - const message = error instanceof Error ? error.message : String(error); - if (message.includes('Frame was detached')) { - console.log(`Frame was detached, retrying (${retryCount + 1}/${maxRetries})`); - } else { - console.log(`Attempt ${retryCount + 1} failed to access iframe:`, message); - } - } - - // Always increment retry count after each attempt - retryCount++; - - // Only retry if we haven't reached max retries - if (retryCount < maxRetries) { - await page.page.waitForTimeout(2000); - try { - await page.selectSidebarItem(viewName); - } catch (sidebarError) { - console.log('Failed to reselect sidebar item:', sidebarError); - } - } - } - throw new Error(`Failed to access iframe for ${viewName} after ${maxRetries} attempts`); -} - export async function createProject(page: ExtendedPage, projectName?: string) { console.log('Creating new project'); @@ -198,7 +159,7 @@ export async function createProject(page: ExtendedPage, projectName?: string) { export function initTest(newProject: boolean = false, skipProjectCreation: boolean = false, cleanupAfter?: boolean, projectName?: string) { test.beforeAll(async ({ }, testInfo) => { console.log(`\n▶️ STARTING TEST: ${testInfo.title} (Attempt ${testInfo.retry + 1})`); - if (!existsSync(path.join(newProjectPath, projectName ?? 'testProject')) || newProject) { + if (!existsSync(path.join(newProjectPath, projectName ?? 'sample')) || newProject) { if (fs.existsSync(newProjectPath)) { fs.rmSync(newProjectPath, { recursive: true }); } @@ -226,12 +187,11 @@ export function initTest(newProject: boolean = false, skipProjectCreation: boole }); } - export function initMigrationTest() { test.beforeAll(async ({ }, testInfo) => { console.log(`>>> Starting migration tests. Title: ${testInfo.title}, Attempt: ${testInfo.retry + 1}`); console.log('Setting up BI extension for migration testing'); - if (!existsSync(path.join(newProjectPath, 'testProject'))) { + if (!existsSync(path.join(newProjectPath, 'sample'))) { if (fs.existsSync(newProjectPath)) { fs.rmSync(newProjectPath, { recursive: true }); } @@ -261,73 +221,3 @@ export function initMigrationTest() { console.log('Migration test runner started'); }); } - - -export async function addArtifact(artifactName: string, testId: string) { - console.log(`Adding artifact: ${artifactName}`); - const artifactWebView = await getWebview('WSO2 Integrator: BI', page); - if (!artifactWebView) { - throw new Error('WSO2 Integrator: BI webview not found'); - } - // Navigate to the overview page - await artifactWebView.getByRole('button', { name: ' Add Artifact' }).click(); - // how to get element by id - const addArtifactBtn = artifactWebView.locator(`#${testId}`); - await addArtifactBtn.waitFor(); - await addArtifactBtn.click(); -} - -export async function enableICP() { - console.log('Enabling ICP'); - const webview = await getWebview('WSO2 Integrator: BI', page); - if (!webview) { - throw new Error('WSO2 Integrator: BI webview not found'); - } - const icpToggle = webview.getByRole('checkbox', { name: 'Enable WSO2 Integrator: ICP' }); - await icpToggle.waitFor(); - if (!(await icpToggle.isChecked())) { - await icpToggle.click(); - } -} - -/** - * Normalize source code for comparison - */ -function normalizeSource(source: string): string { - return source - .replace(/\r\n/g, '\n') // Normalize line endings - .replace(/\t/g, ' ') // Convert tabs to spaces - .split('\n') - .map(line => line.trimEnd()) // Remove trailing whitespace - .filter(line => line.trim() !== '') // Remove empty lines - .join('\n') - .trim(); -} - -/** - * Compare a generated .bal file with an expected .bal file - * @param generatedFileName - Name of the generated file (e.g., 'types.bal') - * @param expectedFilePath - Path to the expected file (e.g., path to testOutput.bal) - */ -export async function verifyGeneratedSource(generatedFileName: string, expectedFilePath: string): Promise { - const { expect } = await import('@playwright/test'); - - // Generated file is in the project sample folder - const generatedFilePath = path.join(newProjectPath, 'sample', generatedFileName); - - if (!fs.existsSync(generatedFilePath)) { - throw new Error(`Generated file not found at: ${generatedFilePath}`); - } - - if (!fs.existsSync(expectedFilePath)) { - throw new Error(`Expected file not found at: ${expectedFilePath}`); - } - - const actualContent = fs.readFileSync(generatedFilePath, 'utf-8'); - const expectedContent = fs.readFileSync(expectedFilePath, 'utf-8'); - - const normalizedActual = normalizeSource(actualContent); - const normalizedExpected = normalizeSource(expectedContent); - - expect(normalizedActual).toBe(normalizedExpected); -} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/verification.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/verification.ts new file mode 100644 index 00000000000..328c0dadb1c --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/verification.ts @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 fs from 'fs'; +import path from 'path'; +import { newProjectPath } from './setup'; + +/** + * Normalize source code for comparison + */ +function normalizeSource(source: string): string { + return source + .replace(/\r\n/g, '\n') // Normalize line endings + .replace(/\t/g, ' ') // Convert tabs to spaces + .split('\n') + .map(line => line.trimEnd()) // Remove trailing whitespace + .filter(line => line.trim() !== '') // Remove empty lines + .join('\n') + .trim(); +} + +/** + * Compare a generated .bal file with an expected .bal file + * @param generatedFileName - Name of the generated file (e.g., 'types.bal') + * @param expectedFilePath - Path to the expected file (e.g., path to testOutput.bal) + */ +export async function verifyGeneratedSource(generatedFileName: string, expectedFilePath: string): Promise { + const { expect } = await import('@playwright/test'); + + // Generated file is in the project sample folder + const generatedFilePath = path.join(newProjectPath, 'sample', generatedFileName); + + if (!fs.existsSync(generatedFilePath)) { + throw new Error(`Generated file not found at: ${generatedFilePath}`); + } + + if (!fs.existsSync(expectedFilePath)) { + throw new Error(`Expected file not found at: ${expectedFilePath}`); + } + + const actualContent = fs.readFileSync(generatedFilePath, 'utf-8'); + const expectedContent = fs.readFileSync(expectedFilePath, 'utf-8'); + + const normalizedActual = normalizeSource(actualContent); + const normalizedExpected = normalizeSource(expectedContent); + + expect(normalizedActual).toBe(normalizedExpected); +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/webview.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/webview.ts new file mode 100644 index 00000000000..f7a4487aa87 --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/helpers/webview.ts @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 { ExtendedPage, switchToIFrame } from "@wso2/playwright-vscode-tester"; + +/** + * Get webview frame with retry logic + */ +export async function getWebview(viewName: string, page: ExtendedPage) { + let webview; + let retryCount = 0; + const maxRetries = 3; + + while (retryCount < maxRetries) { + try { + await page.page.waitForLoadState('domcontentloaded'); + await page.page.waitForTimeout(1000); + + webview = await switchToIFrame(viewName, page.page); + if (webview) { + return webview; + } + // If webview is falsy, treat it as a failed attempt + console.log(`Attempt ${retryCount + 1} failed: switchToIFrame returned ${webview}`); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + if (message.includes('Frame was detached')) { + console.log(`Frame was detached, retrying (${retryCount + 1}/${maxRetries})`); + } else { + console.log(`Attempt ${retryCount + 1} failed to access iframe:`, message); + } + } + + // Always increment retry count after each attempt + retryCount++; + + // Only retry if we haven't reached max retries + if (retryCount < maxRetries) { + await page.page.waitForTimeout(2000); + try { + await page.selectSidebarItem(viewName); + } catch (sidebarError) { + console.log('Failed to reselect sidebar item:', sidebarError); + } + } + } + throw new Error(`Failed to access iframe for ${viewName} after ${maxRetries} attempts`); +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/ConfigEditor.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/ConfigEditor.ts similarity index 100% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/ConfigEditor.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/ConfigEditor.ts diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/components/Diagram.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/Diagram.ts similarity index 100% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/components/Diagram.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/Diagram.ts diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/ProjectExplorer.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/ProjectExplorer.ts similarity index 89% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/ProjectExplorer.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/ProjectExplorer.ts index 2277bc28b77..f05cc87359e 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/ProjectExplorer.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/ProjectExplorer.ts @@ -58,4 +58,10 @@ export class ProjectExplorer { await this.page.waitForTimeout(500); // To fix intermittent issues await locator.click(); } + + public async refresh(projectName: string) { + await this.page.getByRole('treeitem', { name: projectName }).hover(); + const refreshBtn = this.page.getByRole('button', { name: 'Refresh' }); + await refreshBtn.click(); + } } diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/components/SidePanel.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/SidePanel.ts similarity index 99% rename from workspaces/bi/bi-extension/src/test/e2e-playwright-tests/components/SidePanel.ts rename to workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/SidePanel.ts index 428dff66214..cd58963376d 100644 --- a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/components/SidePanel.ts +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/SidePanel.ts @@ -40,4 +40,4 @@ export class SidePanel { const nodeContainer = this.getLocator().getByTitle(nodeTitle); await nodeContainer.click(); } -} \ No newline at end of file +} diff --git a/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/index.ts b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/index.ts new file mode 100644 index 00000000000..7583905907b --- /dev/null +++ b/workspaces/bi/bi-extension/src/test/e2e-playwright-tests/utils/pages/index.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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. + */ + +export { ConfigEditor } from './ConfigEditor'; +export { ProjectExplorer } from './ProjectExplorer'; +export { Diagram } from './Diagram'; +export { SidePanel } from './SidePanel'; diff --git a/workspaces/bi/bi-extension/src/utils.ts b/workspaces/bi/bi-extension/src/utils.ts index 016a83c4e56..30fafddf9db 100644 --- a/workspaces/bi/bi-extension/src/utils.ts +++ b/workspaces/bi/bi-extension/src/utils.ts @@ -21,7 +21,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { extension } from "./biExtentionContext"; import { PackageTomlValues, WorkspaceTomlValues } from "@wso2/ballerina-core"; -import { parse } from "toml"; +import { parse } from "@iarna/toml"; export interface ProjectInfo { isBI: boolean; @@ -156,12 +156,12 @@ export async function checkIsBallerinaWorkspace(uri: Uri): Promise { * @returns A Promise that resolves to the parsed TOML values if successful, * or undefined if the file doesn't exist or parsing fails */ -async function getProjectTomlValues(projectPath: string): Promise { +async function getProjectTomlValues(projectPath: string): Promise | undefined> { const ballerinaTomlPath = path.join(projectPath, 'Ballerina.toml'); if (fs.existsSync(ballerinaTomlPath)) { const tomlContent = await fs.promises.readFile(ballerinaTomlPath, 'utf-8'); try { - return parse(tomlContent); + return parse(tomlContent) as Partial; } catch (error) { console.error("Failed to load Ballerina.toml content for project at path: ", projectPath, error); return; @@ -176,12 +176,12 @@ async function getProjectTomlValues(projectPath: string): Promise { +export async function getWorkspaceTomlValues(workspacePath: string): Promise | undefined> { const ballerinaTomlPath = path.join(workspacePath, 'Ballerina.toml'); if (fs.existsSync(ballerinaTomlPath)) { const tomlContent = await fs.promises.readFile(ballerinaTomlPath, 'utf-8'); try { - return parse(tomlContent); + return parse(tomlContent) as Partial; } catch (error) { console.error("Failed to load Ballerina.toml content for workspace at path: ", workspacePath, error); return; diff --git a/workspaces/bi/bi-extension/tsconfig.json b/workspaces/bi/bi-extension/tsconfig.json index 367fcb13f5b..03ab2643dce 100644 --- a/workspaces/bi/bi-extension/tsconfig.json +++ b/workspaces/bi/bi-extension/tsconfig.json @@ -4,7 +4,8 @@ "target": "es6", "outDir": "out", "lib": [ - "es2022" + "es2022", + "DOM" ], "sourceMap": true, "rootDirs": [ diff --git a/workspaces/common-libs/rpc-generator/index.js b/workspaces/common-libs/rpc-generator/index.js index e273ab6cf5f..a2c4bed7d6e 100644 --- a/workspaces/common-libs/rpc-generator/index.js +++ b/workspaces/common-libs/rpc-generator/index.js @@ -324,7 +324,6 @@ const handlerFunction = handlerSourceFile.addFunction({ }] }); handleImportStatment(handlerSourceFile, 'vscode-messenger', 'Messenger'); - // Add statements to the function const managerObject = `const rpcManger = new ${managerClassName}();` handlerFunction.addStatements(managerObject); @@ -332,6 +331,7 @@ typeMethods.forEach(value => { handleMessengerTypes(handlerFunction, value, handlerSourceFile); }) +console.log(`Adding handler function: ${headerComment}...`); handleImportStatment(handlerSourceFile, './rpc-manager', managerClassName); // Format imports into new lines diff --git a/workspaces/common-libs/rpc-generator/package.json b/workspaces/common-libs/rpc-generator/package.json index 6e2766b61dc..e4f03d514c3 100644 --- a/workspaces/common-libs/rpc-generator/package.json +++ b/workspaces/common-libs/rpc-generator/package.json @@ -4,11 +4,11 @@ "description": "Generate rpc-manager,rpc-handler and rpc-client ts files in relevant libraries", "main": "index.js", "config": { - "CORE_RPC_TYPE_FILE": "ai-panel/index.ts", - "CORE_RPC_TYPE_DIR": "../../ballerina/ballerina-core/", - "EXT_RPC_MANAGER_DIR": "../../ballerina/ballerina-extension/", - "RPC_CLIENT_DIR": "../../ballerina/ballerina-rpc-client/", - "CORE_MODULE_NAME": "@wso2/ballerina-core" + "CORE_RPC_TYPE_FILE": "main/index.ts", + "CORE_RPC_TYPE_DIR": "../../wi/wi-core/", + "EXT_RPC_MANAGER_DIR": "../../wi/wi-extension/", + "RPC_CLIENT_DIR": "../../wi/wi-rpc-client/", + "CORE_MODULE_NAME": "@wso2/wi-core" }, "scripts": { "generate": "node index.js" diff --git a/workspaces/common-libs/scripts/package-vsix.js b/workspaces/common-libs/scripts/package-vsix.js new file mode 100644 index 00000000000..99516c70eeb --- /dev/null +++ b/workspaces/common-libs/scripts/package-vsix.js @@ -0,0 +1,24 @@ +const { spawnSync } = require('child_process'); + +const isPreRelease = process.env.isPreRelease === 'true'; +const args = ['vsce', 'package', '--no-dependencies']; + +if (isPreRelease) { + args.push('--pre-release'); +} + +console.log(`Packaging VSIX with args: ${args.join(' ')}`); + +const result = spawnSync('npx', args, { stdio: 'inherit' }); + +if (result.error) { + console.error(`Failed to spawn vsce: ${result.error.message}`); + process.exit(1); +} + +if (result.status === null) { + console.error('vsce process was terminated by a signal'); + process.exit(1); +} + +process.exit(result.status); diff --git a/workspaces/common-libs/service-designer/src/definitions.ts b/workspaces/common-libs/service-designer/src/definitions.ts index f64001d2c24..3a699715289 100644 --- a/workspaces/common-libs/service-designer/src/definitions.ts +++ b/workspaces/common-libs/service-designer/src/definitions.ts @@ -73,6 +73,17 @@ export interface Resource { additionalActions?: Item[]; // Additional actions for the resource } +export interface Query { + name: string; + methods: any[]; + isOpen?: boolean; + expandable?: boolean; + additionalInfo?: JSX.Element; // Additional information to be displayed in the resource expanded view + additionalActions?: Item[]; // Additional actions for the resource + params?: ParameterConfig[]; + advancedParams?: Map; +} + export interface PathConfig { path: string; resources: ParameterConfig[]; diff --git a/workspaces/common-libs/ui-toolkit/src/components/Button/Button.tsx b/workspaces/common-libs/ui-toolkit/src/components/Button/Button.tsx index 4d71b2f4692..7f6984b0338 100644 --- a/workspaces/common-libs/ui-toolkit/src/components/Button/Button.tsx +++ b/workspaces/common-libs/ui-toolkit/src/components/Button/Button.tsx @@ -32,6 +32,8 @@ export interface ButtonProps { sx?: React.CSSProperties; buttonSx?: React.CSSProperties; onClick?: (() => void) | ((event: React.MouseEvent) => void); + onMouseDown?: (event: React.MouseEvent) => void; + onMouseUp?: (event: React.MouseEvent) => void; } export const IconLabel = styled.div` diff --git a/workspaces/common-libs/ui-toolkit/src/components/ErrorBoundary/Error/Error.tsx b/workspaces/common-libs/ui-toolkit/src/components/ErrorBoundary/Error/Error.tsx index 63cf2367d32..24687fab568 100644 --- a/workspaces/common-libs/ui-toolkit/src/components/ErrorBoundary/Error/Error.tsx +++ b/workspaces/common-libs/ui-toolkit/src/components/ErrorBoundary/Error/Error.tsx @@ -33,7 +33,7 @@ export interface ErrorProps { export function ErrorScreen(props: ErrorProps) { const classes = useStyles(); const { resetBoundary } = useErrorBoundary(); - const issueUrl = props.issueUrl || "https://github.com/wso2/ballerina-plugin-vscode/issues"; + const issueUrl = props.issueUrl || "https://github.com/wso2/vscode-extensions/issues"; return (
diff --git a/workspaces/common-libs/ui-toolkit/src/components/ExpressionEditor/components/Header/ExpressionEditor.tsx b/workspaces/common-libs/ui-toolkit/src/components/ExpressionEditor/components/Header/ExpressionEditor.tsx index 3241196f9d6..3e91ad39d1e 100644 --- a/workspaces/common-libs/ui-toolkit/src/components/ExpressionEditor/components/Header/ExpressionEditor.tsx +++ b/workspaces/common-libs/ui-toolkit/src/components/ExpressionEditor/components/Header/ExpressionEditor.tsx @@ -337,6 +337,10 @@ export const ExpressionEditor = forwardRef { + setCursor(inputRef, 'input', value, cursorPosition, manualFocusTrigger); + }; + const handleRefFocus = (manualTrigger?: boolean) => { if (document.activeElement !== elementRef.current) { manualFocusTrigger.current = manualTrigger ?? false; @@ -375,6 +379,7 @@ export const ExpressionEditor = forwardRef) => { await handleExpressionSaveMutation(value, ref); } @@ -419,22 +424,24 @@ export const ExpressionEditor = forwardRef - +
{ e.preventDefault(); }}> + +
void; }; diff --git a/workspaces/mcp-inspector/mcp-inspector-extension/package.json b/workspaces/mcp-inspector/mcp-inspector-extension/package.json index 80659e1768c..b410d3ac893 100644 --- a/workspaces/mcp-inspector/mcp-inspector-extension/package.json +++ b/workspaces/mcp-inspector/mcp-inspector-extension/package.json @@ -60,7 +60,7 @@ "lint": "eslint src", "test": "node ./out/test/runTest.js", "build": "pnpm run compile && pnpm run lint && pnpm run postbuild", - "package": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi", + "package": "node ../../common-libs/scripts/package-vsix.js", "rebuild": "pnpm run clean && pnpm run compile && pnpm run postbuild", "postbuild": "pnpm run package && pnpm run copyVSIX", "copyVSIX": "copyfiles *.vsix ./vsix", diff --git a/workspaces/mi/mi-core/src/state-machine-types.ts b/workspaces/mi/mi-core/src/state-machine-types.ts index 4328f4872b9..f8fa9b1a11b 100644 --- a/workspaces/mi/mi-core/src/state-machine-types.ts +++ b/workspaces/mi/mi-core/src/state-machine-types.ts @@ -65,7 +65,8 @@ export enum MACHINE_VIEW { DefaultEndpointForm = "Default Endpoint Form", DataServiceForm = "Data Service Form", DssDataSourceForm = "DSS Data Source Form", - DSSServiceDesigner = "Data Service Designer", + DSSResourceServiceDesigner = "DSS Resource Designer", + DSSQueryServiceDesigner = "DSS Query Designer", ProjectCreationForm = "Project Creation Form", ImportProjectForm = "Import Project Form", LocalEntryForm = "Local Entry Form", @@ -270,6 +271,7 @@ export interface VisualizerLocation { previousContext?: any; env?: { [key: string]: string | undefined }; isLoading?: boolean; + isLegacyRuntime?: boolean; } export interface PopupVisualizerLocation extends VisualizerLocation { diff --git a/workspaces/mi/mi-diagram/src/components/Form/common.ts b/workspaces/mi/mi-diagram/src/components/Form/common.ts index cfa787ac6cf..871514e565e 100644 --- a/workspaces/mi/mi-diagram/src/components/Form/common.ts +++ b/workspaces/mi/mi-diagram/src/components/Form/common.ts @@ -139,11 +139,13 @@ export const getParamManagerFromValues = (values: any[], keyIndex?: number, valu if (typeof value === 'object' && value !== null) { const paramValues = getParamValues(value); + const key = keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1; return { id: index, - key: keyIndex != undefined && keyIndex >= 0 ? typeof value[keyIndex] === 'object' ? value[keyIndex].value : value[keyIndex] : index + 1, - value: typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex], - icon: 'query', paramValues + key: key, + value: (key === "Query" && valueIndex == 4) ? (typeof value[1] === 'object' ? value[1].value : value[1]) : + (typeof value[valueIndex] === 'object' ? value[valueIndex].value : value[valueIndex]), + paramValues }; } else { return { value }; diff --git a/workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts b/workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts index 861678bbcdc..ff1589a5a8e 100644 --- a/workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts +++ b/workspaces/mi/mi-diagram/src/components/nodes/ReferenceNode/ReferenceNodeModel.ts @@ -56,7 +56,7 @@ export class ReferenceNodeModel extends BaseNodeModel { rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { - view: MACHINE_VIEW.DSSServiceDesigner, + view: MACHINE_VIEW.DSSResourceServiceDesigner, documentUri: uri } }); diff --git a/workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx b/workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx index 3ab6076e21e..529cb12fb59 100644 --- a/workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx +++ b/workspaces/mi/mi-diagram/src/components/sidePanel/dataServices/query.tsx @@ -68,8 +68,8 @@ const QueryForm = (props: AddMediatorProps) => { returnGeneratedKeys: sidePanelContext?.formValues?.returnGeneratedKeys || false, keyColumns: sidePanelContext?.formValues?.keyColumns || "", returnUpdatedRowCount: sidePanelContext?.formValues?.returnUpdatedRowCount || false, - forceStoredProc: sidePanelContext?.formValues?.forceStoredProc || false, - forceJdbcBatchRequests: sidePanelContext?.formValues?.forceJdbcBatchRequests || false, + forceStoredProc: sidePanelContext?.formValues?.forceStoredProc === "true" || false, + forceJDBCBatchRequests: sidePanelContext?.formValues?.forceJDBCBatchRequests === "true" || false, }); setIsLoading(false); }, []); @@ -89,7 +89,7 @@ const QueryForm = (props: AddMediatorProps) => { queryProperties.maxFieldSize = values.maxFieldSize; queryProperties.maxRows = values.maxRows; queryProperties.forceStoredProc = values.forceStoredProc; - queryProperties.forceJDBCBatchRequests = values.forceJdbcBatchRequests; + queryProperties.forceJDBCBatchRequests = values.forceJDBCBatchRequests; queryProperties = Object.entries(queryProperties) .filter(([_, value]) => value !== "").map(([key, value]) => ({ key, value })); const updatedQuery = sidePanelContext?.formValues?.queryObject; @@ -184,18 +184,6 @@ const QueryForm = (props: AddMediatorProps) => { <>
- - - ( - - )} - /> - {errors.queryId && {errors.queryId.message.toString()}} - - { ( { field.onChange(e.target.checked) }}>Force JDBC Batch Requests )} /> - {errors.forceJdbcBatchRequests && {errors.forceJdbcBatchRequests.message.toString()}} + {errors.forceJDBCBatchRequests && {errors.forceJDBCBatchRequests.message.toString()}} diff --git a/workspaces/mi/mi-diagram/src/components/sidePanel/mediators/ModuleSuggestions.tsx b/workspaces/mi/mi-diagram/src/components/sidePanel/mediators/ModuleSuggestions.tsx index c04787ecca3..958bc5b16b5 100644 --- a/workspaces/mi/mi-diagram/src/components/sidePanel/mediators/ModuleSuggestions.tsx +++ b/workspaces/mi/mi-diagram/src/components/sidePanel/mediators/ModuleSuggestions.tsx @@ -56,13 +56,16 @@ export function ModuleSuggestions(props: ModuleSuggestionProps) { setIsSearching(true); if (value) { try { + let data: any[] = []; const runtimeVersion = await rpcClient.getMiDiagramRpcClient().getMIVersionFromPom(); const response = await fetch(`${process.env.MI_CONNECTOR_STORE_BACKEND_SEARCH.replace('${searchValue}', value).replace('${version}', runtimeVersion.version)}`); - const data = await response.json(); + if (response.ok) { + data = await response.json(); + } setFilteredModules(data); } catch (e) { console.error("Error fetching modules", e); - setFilteredModules(undefined); + setFilteredModules([]); } } else { setFilteredModules([]); diff --git a/workspaces/mi/mi-diagram/src/components/sidePanel/modules/ModulesList.tsx b/workspaces/mi/mi-diagram/src/components/sidePanel/modules/ModulesList.tsx index 28d4f2cd0cf..c1bcf1c73ca 100644 --- a/workspaces/mi/mi-diagram/src/components/sidePanel/modules/ModulesList.tsx +++ b/workspaces/mi/mi-diagram/src/components/sidePanel/modules/ModulesList.tsx @@ -161,8 +161,7 @@ export function Modules(props: ModuleProps) { .filter(([_, values]: [string, any]) => !localConnectors || !localConnectors.some((c: any) => - ((c.displayName ? c.displayName === values.connectorName : c.name.toLowerCase() === values.connectorName.toLowerCase())) && - (c.version === values.version.tagName) + ((c.displayName ? c.displayName === values.connectorName : c.name.toLowerCase() === values.connectorName.toLowerCase())) ) ) .sort(([, a], [, b]) => a.connectorRank - b.connectorRank); diff --git a/workspaces/mi/mi-diagram/src/components/sidePanel/tryout/SetPayloads.tsx b/workspaces/mi/mi-diagram/src/components/sidePanel/tryout/SetPayloads.tsx index a50842ce452..5799cd1a9cc 100644 --- a/workspaces/mi/mi-diagram/src/components/sidePanel/tryout/SetPayloads.tsx +++ b/workspaces/mi/mi-diagram/src/components/sidePanel/tryout/SetPayloads.tsx @@ -49,9 +49,11 @@ export function SetPayloads(props: SetPayloadsProps) { const [requestsNames, setRequestsNames] = React.useState([]); const [isAPI, setIsAPI] = React.useState(false); const [supportPayload, setSupportPayload] = React.useState(false); + const [showLegacyRuntimeError, setShowLegacyRuntimeError] = React.useState(false); + const showNotSupportedError = artifactModel?.tag === 'query'; useEffect(() => { - rpcClient.getMiDiagramRpcClient().getInputPayloads({ documentUri, artifactModel }).then((res) => { + rpcClient.getMiDiagramRpcClient().getInputPayloads({ documentUri, artifactModel }).then(async (res) => { const requests = Array.isArray(res.payloads) ? res.payloads.map(payload => ({ name: payload.name, @@ -77,6 +79,7 @@ export function SetPayloads(props: SetPayloadsProps) { setIsLoading(false); setIsAPI(artifactModel.tag === 'resource'); setSupportPayload(supportsRequestBody('methods' in artifactModel ? artifactModel.methods as string[] : ["POST"])); + setShowLegacyRuntimeError((await rpcClient.getVisualizerState()).isLegacyRuntime); }); }, []); @@ -252,33 +255,45 @@ export function SetPayloads(props: SetPayloadsProps) { return ( - - {`Save Payload for Expression Completions and Mediator Tryouts`} - - - + {showNotSupportedError ? ( + + Try-Out feature is not supported for this artifact type. + + ) : showLegacyRuntimeError ? ( + + Please update your MI runtime to the latest version to use the tryout feature. + + ) : ( + <> + + {`Save Payload for Expression Completions and Mediator Tryouts`} + + + - - - - + + + + + + )} ); }; diff --git a/workspaces/mi/mi-extension/CHANGELOG.md b/workspaces/mi/mi-extension/CHANGELOG.md index 88d256f7c7c..04232606b56 100644 --- a/workspaces/mi/mi-extension/CHANGELOG.md +++ b/workspaces/mi/mi-extension/CHANGELOG.md @@ -2,13 +2,44 @@ All notable changes to the "micro-integrator" extension will be documented in this file. +## [3.1.0] - 2025-12-08 + +### New Features + +Added: Nested query support for data services via a seperate query view +Added: Oracle synonym support for data service resource generation + +### Fixed + +Fixed: .env file should be added to the gitignore by default ([#668](https://github.com/wso2/mi-vscode/issues/668)) +Fixed: Show a message when the CApp generation is successful ([#1289](https://github.com/wso2/mi-vscode/issues/1289)) +Fixed: Add parameter doesn't add parameter values to the xml in cdc inbound endpoint ([#1204](https://github.com/wso2/mi-vscode/issues/1204)) +Fixed: No error shown we retry connectors without internet connection ([#1314](https://github.com/wso2/mi-vscode/issues/1314)) +Fixed: Variables are not shown in the mediation debugger ([#1308](https://github.com/wso2/mi-vscode/issues/1308)) +Fixed: UI alignment issue in mock services ([#1042](https://github.com/wso2/mi-vscode/issues/1042)) +Fixed: Improve Marketplace Page for Micro Integrator Extension ([#1022](https://github.com/wso2/mi-vscode/issues/1022)) +Fixed: Issues in HTTP Endpoint Template create form ([#970](https://github.com/wso2/mi-vscode/issues/970)) +Fixed: Adding new connector version without validation breaks pom.xml ([#1259](https://github.com/wso2/mi-vscode/issues/1259)) +Fixed: Runtime services panel shows the versioned APIs when versioning is disabled ([#1343](https://github.com/wso2/mi-vscode/issues/1343)) +Fixed: Build CApp option ask about deployment.toml configs ([#1306](https://github.com/wso2/mi-vscode/issues/1306)) +Fixed: Remove Server Type in remote deployment settings page ([#1295](https://github.com/wso2/mi-vscode/issues/1295)) +Fixed: The groupId, artifactId of a project is not visible in the Project summary ([#1293](https://github.com/wso2/mi-vscode/issues/1293)) +Fixed: Error When Searching Mediators Offline ([#1098](https://github.com/wso2/mi-vscode/issues/1098)) +Fixed: "Maximum redelivery attempts" field in Message Forwarding Processors does not allow -1 as a value ([#695](https://github.com/wso2/mi-vscode/issues/695)) +Fixed: Dataservice resource diagram start node has the option to set a payload for tryout ([#715](https://github.com/wso2/mi-vscode/issues/715)) +Fixed: Can add TryOut payload to start node in 4.3.0 projects ([#1347](https://github.com/wso2/mi-vscode/issues/643)) +Fixed: Text editor does not provide synapse suggestions ([#643](https://github.com/wso2/mi-vscode/issues/1347)) +Fixed: Cannot delete a datamapper in Windows OS ([#1361](https://github.com/wso2/mi-vscode/issues/1361)) +Fixed: User given OpenAPI definition is not exposed by the MI server ([#1362](https://github.com/wso2/mi-vscode/issues/1362)) +Fixed: API update option not appearing after OpenAPI definition update ([#1363](https://github.com/wso2/mi-vscode/issues/1363)) + ## [3.0.1] - 2025-11-21 ### Fixed Fixed: Error when opening a diagram view on a new tab ([#1346](https://github.com/wso2/mi-vscode/issues/1346)) Fixed: Cannot add email connector operations after adding a foreach mediator ([#1348](https://github.com/wso2/mi-vscode/issues/1348)) -Fixed: Path level paramaters are not getting recognized in OpenAPI definition ([#1353](https://github.com/wso2/mi-vscode/issues/1353)) +Fixed: Path level parameters are not getting recognized in OpenAPI definition ([#1353](https://github.com/wso2/mi-vscode/issues/1353)) Fixed: Unit test execution command ignores the test.server.path argument ([#1354](https://github.com/wso2/mi-vscode/issues/1354)) ## [3.0.0] - 2025-11-03 diff --git a/workspaces/mi/mi-extension/README.md b/workspaces/mi/mi-extension/README.md index 9157b198a46..2ea88e178db 100644 --- a/workspaces/mi/mi-extension/README.md +++ b/workspaces/mi/mi-extension/README.md @@ -2,19 +2,6 @@ WSO2 Integrator: MI Visual Studio Code extension (MI for VSCode) is a comprehensive integration solution that simplifies your digital transformation journey. It streamlines connectivity among applications, services, data, and the cloud using a user-friendly low-code graphical designing experience and revolutionizes your integration development workflow. As an integration developer, you can execute all the development lifecycle phases using this tool. When your integration solutions are production-ready, you can easily push the artifacts to your continuous integration/continuous deployment pipeline. -## Prerequisites - -You need the following to work with the MI for VS Code extension. - -- Java Development Kit (JDK) -- WSO2 Integrator: MI runtime - -If these are not installed on your local machine, the WSO2 Integrator: MI for VS Code extension will automatically prompt you to download and configure them during the project creation step, depending on the project runtime version. - -If a different JDK or WSO2 MI version is installed on your local machine, you'll be prompted to download the required versions. - -If the required JDK and WSO2 MI versions are already installed, you can directly configure the Java Home and MI Home paths in this step. - ## Get Started 1. Launch VS Code with the WSO2 Integrator: MI for Visual Studio Code (MI for VS Code) extension installed. When the extension is installed properly, you can see the WSO2 Integrator: MI icon in the Activity Bar of the VS Code editor. diff --git a/workspaces/mi/mi-extension/package.json b/workspaces/mi/mi-extension/package.json index ac46d86ef0a..b69c3b201f8 100644 --- a/workspaces/mi/mi-extension/package.json +++ b/workspaces/mi/mi-extension/package.json @@ -3,7 +3,7 @@ "displayName": "WSO2 Integrator: MI", "description": "An extension which gives a development environment for designing, developing, debugging, and testing integration solutions.", "icon": "resources/images/wso2-micro-integrator-image.png", - "version": "3.0.1", + "version": "3.1.0", "publisher": "wso2", "engines": { "vscode": "^1.100.0" @@ -191,13 +191,15 @@ "micro-integrator": [ { "id": "MI.project-explorer", - "name": "Project Explorer" + "name": "Project Explorer", + "when": "!config.integrator.defaultIntegrator" } ], "test": [ { "id": "MI.mock-services", - "name": "Mock Services" + "name": "Mock Services", + "when": "MI.status == 'projectLoaded'" } ] }, @@ -205,26 +207,42 @@ { "view": "MI.project-explorer", "contents": "Loading...", - "when": "MI.status != 'unknownProject' && MI.status != 'projectLoaded' && MI.status != 'disabled' && MI.status != 'notSetUp'" + "when": "!config.integrator.defaultIntegrator && (MI.status != 'unknownProject' && MI.status != 'projectLoaded' && MI.status != 'disabled' && MI.status != 'notSetUp')" }, { "view": "MI.project-explorer", "contents": "Welcome to WSO2 Integrator: MI. You can open a folder containing a MI project or create a new project.\n[Open MI Project](command:MI.openProject)\n[Create New Project](command:MI.project-explorer.create-project)\nTo learn more about how to use WSO2 Integrator: MI in VS Code, [read our docs](https://mi.docs.wso2.com/en/4.3.0/develop/mi-for-vscode/mi-for-vscode-overview/).", - "when": "MI.status == 'unknownProject'" + "when": "!config.integrator.defaultIntegrator && MI.status == 'unknownProject'" }, { "view": "MI.project-explorer", "contents": "Some errors occurred while activating the extension. Please check the output channel for more information.", - "when": "MI.status == 'disabled'" + "when": "!config.integrator.defaultIntegrator && MI.status == 'disabled'" }, { - "view": "testing", - "contents": "[Add Unit Test](command:MI.test.add.suite)" + "view": "MI.project-explorer", + "contents": "WSO2 Integrator: MI is not set up. Please set up the MI server and Java home to continue.", + "when": "!config.integrator.defaultIntegrator && MI.status == 'notSetUp'" }, { - "view": "MI.project-explorer", + "view": "wso2-integrator.explorer", + "contents": "Loading...", + "when": "config.integrator.defaultIntegrator != '' && (MI.status != 'unknownProject' && MI.status != 'projectLoaded' && MI.status != 'disabled' && MI.status != 'notSetUp')" + }, + { + "view": "wso2-integrator.explorer", + "contents": "Some errors occurred while activating the extension. Please check the output channel for more information.", + "when": "config.integrator.defaultIntegrator != '' && MI.status == 'disabled'" + }, + { + "view": "wso2-integrator.explorer", "contents": "WSO2 Integrator: MI is not set up. Please set up the MI server and Java home to continue.", - "when": "MI.status == 'notSetUp'" + "when": "config.integrator.defaultIntegrator != '' && MI.status == 'notSetUp'" + }, + { + "view": "testing", + "contents": "[Add Unit Test](command:MI.test.add.suite)", + "when": "MI.status == 'projectLoaded'" } ], "commands": [ @@ -920,7 +938,7 @@ { "command": "MI.test.add.case", "group": "inline", - "when": "testId in test.suites" + "when": "MI.status == 'projectLoaded' && testId in test.suites" }, { "command": "MI.test.edit.case", @@ -961,7 +979,7 @@ "clean": "rimraf ./dist", "compile": "tsc -p .", "watch": "tsc -p . -w", - "package": "if [ $isPreRelease = true ]; then vsce package --no-dependencies --pre-release; else vsce package --no-dependencies; fi", + "package": "node ../../common-libs/scripts/package-vsix.js", "download-ls": "node ./scripts/download-ls.js", "build": "pnpm clean && pnpm run download-ls && pnpm run copyJSLibs && pnpm run copyLSLibs && pnpm run copyFonts && pnpm run copyDMUtils && pnpm run renameDMUtils && webpack --mode production --devtool hidden-source-map && pnpm run package && pnpm run postbuild", "compile-tests": "pnpm run compile", diff --git a/workspaces/mi/mi-extension/src/RPCLayer.ts b/workspaces/mi/mi-extension/src/RPCLayer.ts index fe9c2c70fca..8346ff94c5c 100644 --- a/workspaces/mi/mi-extension/src/RPCLayer.ts +++ b/workspaces/mi/mi-extension/src/RPCLayer.ts @@ -100,6 +100,7 @@ async function getContext(projectUri: string): Promise { dataMapperProps: context.dataMapperProps, errors: context.errors, isLoading: context.isLoading, + isLegacyRuntime: context.isLegacyRuntime, env: { MI_AUTH_ORG: process.env.MI_AUTH_ORG || '', MI_AUTH_CLIENT_ID: process.env.MI_AUTH_CLIENT_ID || '', diff --git a/workspaces/mi/mi-extension/src/constants/index.ts b/workspaces/mi/mi-extension/src/constants/index.ts index 9be0c37ae38..fafa6f1760a 100644 --- a/workspaces/mi/mi-extension/src/constants/index.ts +++ b/workspaces/mi/mi-extension/src/constants/index.ts @@ -53,6 +53,7 @@ export const COMMANDS = { OPEN_DSS_SERVICE_DESIGNER: "MI.project-explorer.open-dss-service-designer", ADD_MEDIATOR: "MI.addMediator", REFRESH_COMMAND: 'MI.project-explorer.refresh', + WI_PROJECT_EXPLORER_VIEW_REFRESH: 'wso2-integrator.explorer.refresh', ADD_COMMAND: 'MI.project-explorer.add', ADD_ARTIFACT_COMMAND: 'MI.project-explorer.add.artifact', ADD_API_COMMAND: 'MI.project-explorer.add-api', @@ -74,7 +75,6 @@ export const COMMANDS = { CREATE_PROJECT_COMMAND: 'MI.project-explorer.create-project', IMPORT_PROJECT_COMMAND: 'MI.project-explorer.import-project', REVEAL_ITEM_COMMAND: 'MI.project-explorer.revealItem', - FOCUS_PROJECT_EXPLORER: 'MI.project-explorer.focus', OPEN_SERVICE_DESIGNER: 'MI.project-explorer.open-service-designer', OPEN_PROJECT_OVERVIEW: 'MI.project-explorer.open-project-overview', ADD_REGISTERY_RESOURCE_COMMAND: 'MI.project-explorer.add-registry-resource', @@ -132,7 +132,7 @@ export const DEFAULT_PROJECT_VERSION = "1.0.0"; export const READONLY_MAPPING_FUNCTION_NAME = "mapFunction"; -export const REFRESH_ENABLED_DOCUMENTS = ["SynapseXml", "typescript", "markdown", "json"]; +export const REFRESH_ENABLED_DOCUMENTS = ["xml", "SynapseXml", "typescript", "markdown", "json"]; export enum EndpointTypes { DEFAULT_ENDPOINT = "DEFAULT_ENDPOINT", @@ -204,3 +204,7 @@ export const DEFAULT_ICON = "https://mi-connectors.wso2.com/icons/wordpress.gif" export const ERROR_MESSAGES = { ERROR_DOWNLOADING_MODULES: "Unable to download the default modules. These modules can be added after project creation. Do you wish to skip them now and proceed with the project creation?", }; + +export const WI_EXTENSION_ID = 'wso2.wso2-integrator'; +export const WI_PROJECT_EXPLORER_VIEW_ID = 'wso2-integrator.explorer'; +export const MI_PROJECT_EXPLORER_VIEW_ID = 'MI.project-explorer'; diff --git a/workspaces/mi/mi-extension/src/debugger/debugHelper.ts b/workspaces/mi/mi-extension/src/debugger/debugHelper.ts index 8787bb9ffea..effaae44f82 100644 --- a/workspaces/mi/mi-extension/src/debugger/debugHelper.ts +++ b/workspaces/mi/mi-extension/src/debugger/debugHelper.ts @@ -38,6 +38,7 @@ import { serverLog, showServerOutputChannel } from '../util/serverLogger'; import { getJavaHomeFromConfig, getServerPathFromConfig } from '../util/onboardingUtils'; import * as crypto from 'crypto'; import { Uri, workspace } from "vscode"; +import { MILanguageClient } from '../lang-client/activator'; const child_process = require('child_process'); const findProcess = require('find-process'); @@ -154,26 +155,28 @@ export async function executeCopyTask(task: vscode.Task) { export async function executeBuildTask(projectUri: string, serverPath: string, shouldCopyTarget: boolean = true, postBuildTask?: Function) { return new Promise(async (resolve, reject) => { - const isEqual = await compareFilesByMD5(path.join(serverPath, "conf", "deployment.toml"), - path.join(projectUri, "deployment", "deployment.toml")); - if (!isEqual) { - const copyConf = await vscode.window.showWarningMessage( - 'Deployment configurations in the runtime is different from the project. How do you want to proceed?', - { modal: true }, - "Use Project Configurations", "Use Server Configurations" - ); - if (copyConf === 'Use Project Configurations') { - fs.copyFileSync(path.join(serverPath, "conf", "deployment.toml"), path.join(serverPath, "conf", "deployment-backup.toml")); - fs.copyFileSync(path.join(projectUri, "deployment", "deployment.toml"), path.join(serverPath, "conf", "deployment.toml")); - vscode.window.showInformationMessage("A backup of the server configuration is stored at conf/deployment-backup.toml."); - } else if (copyConf === 'Use Server Configurations') { - fs.copyFileSync(path.join(serverPath, "conf", "deployment.toml"), path.join(projectUri, "deployment", "deployment.toml")); - DebuggerConfig.setConfigPortOffset(projectUri); - } else { - reject('Deployment configurations in the project should be as the same as the runtime.'); - return; + if (shouldCopyTarget) { + const isEqual = await compareFilesByMD5(path.join(serverPath, "conf", "deployment.toml"), + path.join(projectUri, "deployment", "deployment.toml")); + if (!isEqual) { + const copyConf = await vscode.window.showWarningMessage( + 'Deployment configurations in the runtime is different from the project. How do you want to proceed?', + { modal: true }, + "Use Project Configurations", "Use Server Configurations" + ); + if (copyConf === 'Use Project Configurations') { + fs.copyFileSync(path.join(serverPath, "conf", "deployment.toml"), path.join(serverPath, "conf", "deployment-backup.toml")); + fs.copyFileSync(path.join(projectUri, "deployment", "deployment.toml"), path.join(serverPath, "conf", "deployment.toml")); + vscode.window.showInformationMessage("A backup of the server configuration is stored at conf/deployment-backup.toml."); + } else if (copyConf === 'Use Server Configurations') { + fs.copyFileSync(path.join(serverPath, "conf", "deployment.toml"), path.join(projectUri, "deployment", "deployment.toml")); + DebuggerConfig.setConfigPortOffset(projectUri); + } else { + reject('Deployment configurations in the project should be as the same as the runtime.'); + return; + } } - } + } const buildCommand = getBuildCommand(projectUri); const envVariables = { @@ -187,6 +190,16 @@ export async function executeBuildTask(projectUri: string, serverPath: string, s serverLog(data.toString('utf8')); }); + if (shouldCopyTarget) { + buildProcess.on('close', async (code) => { + if (code === 0) { + vscode.window.showInformationMessage('Project build was successful'); + } else { + vscode.window.showErrorMessage('Failed to build integration project.'); + } + }); + } + buildProcess.stderr.on('data', (data) => { serverLog(`Build error:\n${data.toString('utf8')}`); }); @@ -410,7 +423,8 @@ export async function stopServer(projectUri: string, serverPath: string, isWindo export async function executeTasks(projectUri: string, serverPath: string, isDebug: boolean): Promise { const maxTimeout = 120000; return new Promise(async (resolve, reject) => { - const isTerminated = await getStateMachine(projectUri).context().langClient?.shutdownTryoutServer(); + const langClient = await MILanguageClient.getInstance(projectUri); + const isTerminated = await langClient.shutdownTryoutServer(); if (!isTerminated) { reject('Failed to terminate the tryout server. Kill the server manually and try again.'); } diff --git a/workspaces/mi/mi-extension/src/debugger/debugger.ts b/workspaces/mi/mi-extension/src/debugger/debugger.ts index b882dac6e2f..665d0d7e6cf 100644 --- a/workspaces/mi/mi-extension/src/debugger/debugger.ts +++ b/workspaces/mi/mi-extension/src/debugger/debugger.ts @@ -27,6 +27,7 @@ import { webviews } from '../visualizer/webview'; import { extension } from '../MIExtensionContext'; import { reject } from 'lodash'; import { LogLevel, logDebug } from '../util/logger'; +import { MILanguageClient } from '../lang-client/activator'; export interface RuntimeBreakpoint { id: number; @@ -87,7 +88,7 @@ export class Debugger extends EventEmitter { return; } const projectUri = workspace.uri.fsPath; - const langClient = getStateMachine(projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const breakpointPerFile: RuntimeBreakpoint[] = []; // To maintain the valid and invalid breakpoints in the vscode const vscodeBreakpointsPerFile: RuntimeBreakpoint[] = []; @@ -191,7 +192,7 @@ export class Debugger extends EventEmitter { return; } const projectUri = workspace.uri.fsPath; - const langClient = getStateMachine(projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const stepOverBreakpoints: RuntimeBreakpoint[] = []; if (path) { // create BreakpointPosition array @@ -278,7 +279,7 @@ export class Debugger extends EventEmitter { throw new Error(`No workspace found for path: ${filePath}`); } const projectUri = workspace.uri.fsPath; - const langClient = getStateMachine(projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); // create BreakpointPosition[] array const breakpointPositions = breakpoints.map((breakpoint) => { return { line: breakpoint.line, column: breakpoint?.column }; @@ -296,7 +297,7 @@ export class Debugger extends EventEmitter { public async getNextMediatorBreakpoint(): Promise { try { - const langClient = getStateMachine(this.projectUri).context().langClient; + const langClient = await MILanguageClient.getInstance(this.projectUri); if (!langClient) { throw new Error('Language client is not initialized'); } @@ -620,18 +621,24 @@ export class Debugger extends EventEmitter { } public async sendPropertiesCommand(): Promise { - const contextList = ["axis2", "axis2-client", "transport", "operation", "synapse"]; + const contextList = ["axis2", "axis2-client", "transport", "operation", "synapse", "variable"]; const variables: JSON[] = []; const propertyMapping = { "axis2Transport-properties": "Transport Scope Properties", "axis2Operation-properties": "Operation Scope Properties", "axis2Client-properties": "Axis2-Client Scope Properties", "axis2-properties": "Axis2 Scope Properties", - "synapse-properties": "Synapse Scope Properties" + "synapse-properties": "Synapse Scope Properties", + "message-variables": "Variables" }; for (const context of contextList) { - let propertiesCommand: any = { "command": "get", "command-argument": "properties", "context": context }; + let propertiesCommand: any; + if (context === "variable") { + propertiesCommand = { "command": "get", "command-argument": "variables", "context": context}; + } else { + propertiesCommand = { "command": "get", "command-argument": "properties", "context": context }; + } try { const response = await this.sendRequest(JSON.stringify(propertiesCommand)); const jsonResponse = JSON.parse(response); diff --git a/workspaces/mi/mi-extension/src/extension.ts b/workspaces/mi/mi-extension/src/extension.ts index 1598808384f..16b0c474dc3 100644 --- a/workspaces/mi/mi-extension/src/extension.ts +++ b/workspaces/mi/mi-extension/src/extension.ts @@ -34,6 +34,7 @@ import { webviews } from './visualizer/webview'; import { v4 as uuidv4 } from 'uuid'; import path from 'path'; import { COMMANDS } from './constants'; +import { enableLS } from './util/workspace'; const os = require('os'); export async function activate(context: vscode.ExtensionContext) { @@ -92,12 +93,16 @@ export async function activate(context: vscode.ExtensionContext) { activateRuntimeService(context, firstProject); activateVisualizer(context, firstProject); activateAiPanel(context); + + workspace.workspaceFolders?.forEach(folder => { + context.subscriptions.push(...enableLS()); + }); } export async function deactivate(): Promise { const clients = await MILanguageClient.getAllInstances(); clients.forEach(async client => { - await client?.languageClient?.stop(); + await client?.stop(); }); // close all webviews diff --git a/workspaces/mi/mi-extension/src/lang-client/activator.ts b/workspaces/mi/mi-extension/src/lang-client/activator.ts index fca9269af51..e193334d44a 100644 --- a/workspaces/mi/mi-extension/src/lang-client/activator.ts +++ b/workspaces/mi/mi-extension/src/lang-client/activator.ts @@ -101,8 +101,11 @@ const versionRegex = /(\d+\.\d+\.?\d*)/g; export class MILanguageClient { private static _instances: Map = new Map(); - private static lsChannelCache: Map = new Map(); - public languageClient: ExtendedLanguageClient | undefined; + private static lsChannels: Map = new Map(); + private static stopTimers: Map = new Map(); + private static stoppingInstances: Set = new Set(); + private static readonly STOP_DEBOUNCE_MS = 30000; // 30 seconds + private languageClient: ExtendedLanguageClient | undefined; // eslint-disable-next-line @typescript-eslint/naming-convention private COMPATIBLE_JDK_VERSION = "11"; // Minimum JDK version required to run the language server @@ -110,21 +113,55 @@ export class MILanguageClient { constructor(private projectUri: string) { } - public static async getInstance(projectUri: string): Promise { + public static async getInstance(projectUri: string): Promise { + // Cancel any pending stop operation for this project + const existingTimer = this.stopTimers.get(projectUri); + if (existingTimer) { + clearTimeout(existingTimer); + this.stopTimers.delete(projectUri); + } + + // If instance is currently stopping, wait for it to complete and create a new one + if (this.stoppingInstances.has(projectUri)) { + // Wait a bit for the stop operation to complete + await new Promise(resolve => setTimeout(resolve, 100)); + this.stoppingInstances.delete(projectUri); + } + if (!this._instances.has(projectUri)) { const instance = new MILanguageClient(projectUri); await instance.launch(projectUri); this._instances.set(projectUri, instance); } - return this._instances.get(projectUri)!; + const languageClient = this._instances.get(projectUri)!.languageClient; + if (!languageClient) { + const errorMessage = "Language client failed to initialize"; + window.showErrorMessage(errorMessage); + throw new Error(errorMessage); + } + return languageClient; } public static async stopInstance(projectUri: string) { - const instance = this._instances.get(projectUri); - if (instance) { - await instance.stop(); - this._instances.delete(projectUri); + // Cancel any existing timer for this project + const existingTimer = this.stopTimers.get(projectUri); + if (existingTimer) { + clearTimeout(existingTimer); } + + // Schedule the stop operation with debounce + const timer = setTimeout(async () => { + this.stoppingInstances.add(projectUri); + const instance = this._instances.get(projectUri); + if (instance) { + await instance.stop(); + this._instances.delete(projectUri); + } + this.stopTimers.delete(projectUri); + this.stoppingInstances.delete(projectUri); + }, this.STOP_DEBOUNCE_MS); + + this.stopTimers.set(projectUri, timer); } public static async getAllInstances(): Promise { @@ -136,10 +173,10 @@ export class MILanguageClient { } public static getOrCreateOutputChannel(projectUri: string): vscode.OutputChannel { - let channel = this.lsChannelCache.get(projectUri); + let channel = this.lsChannels.get(projectUri); if (!channel) { channel = vscode.window.createOutputChannel(`Synapse Language Server - ${path.basename(projectUri)}`); - this.lsChannelCache.set(projectUri, channel); + this.lsChannels.set(projectUri, channel); } return channel; } diff --git a/workspaces/mi/mi-extension/src/project-explorer/activate.ts b/workspaces/mi/mi-extension/src/project-explorer/activate.ts index dbd74d9f170..cd7e52c33f6 100644 --- a/workspaces/mi/mi-extension/src/project-explorer/activate.ts +++ b/workspaces/mi/mi-extension/src/project-explorer/activate.ts @@ -34,26 +34,32 @@ import { compareVersions } from '../util/onboardingUtils'; import { removeFromHistory } from '../history'; import * as fs from "fs"; import { webviews } from '../visualizer/webview'; -import { log } from '../util/logger'; import { MILanguageClient } from '../lang-client/activator'; let isProjectExplorerInitialized = false; -export async function activateProjectExplorer(context: ExtensionContext, lsClient: ExtendedLanguageClient) { +export async function activateProjectExplorer(treeviewId: string, context: ExtensionContext, projectUri: string, isInWI: boolean) { if (isProjectExplorerInitialized) { return; } isProjectExplorerInitialized = true; + const lsClient: ExtendedLanguageClient = await MILanguageClient.getInstance(projectUri); const projectExplorerDataProvider = new ProjectExplorerEntryProvider(context); await projectExplorerDataProvider.refresh(); let registryExplorerDataProvider; - const projectTree = window.createTreeView('MI.project-explorer', { treeDataProvider: projectExplorerDataProvider }); + const projectTree = window.createTreeView(treeviewId, { treeDataProvider: projectExplorerDataProvider }); - const projectDetailsRes = await lsClient?.getProjectDetails(); + const projectDetailsRes = await lsClient.getProjectDetails(); const runtimeVersion = projectDetailsRes.primaryDetails.runtimeVersion.value; const isRegistrySupported = compareVersions(runtimeVersion, RUNTIME_VERSION_440) < 0; - commands.registerCommand(COMMANDS.REFRESH_COMMAND, () => { return projectExplorerDataProvider.refresh(); }); + commands.registerCommand(COMMANDS.REFRESH_COMMAND, () => { + if (isInWI) { + commands.executeCommand(COMMANDS.WI_PROJECT_EXPLORER_VIEW_REFRESH); + return; + } + return projectExplorerDataProvider.refresh(); + }); commands.registerCommand(COMMANDS.ADD_ARTIFACT_COMMAND, (entry: ProjectExplorerEntry) => { openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.ADD_ARTIFACT, projectUri: entry.info?.path }); @@ -377,7 +383,7 @@ export async function activateProjectExplorer(context: ExtensionContext, lsClien commands.registerCommand(COMMANDS.OPEN_DSS_SERVICE_DESIGNER, async (entry: ProjectExplorerEntry | Uri) => { revealWebviewPanel(false); const documentUri = entry instanceof ProjectExplorerEntry ? entry.info?.path : entry.fsPath; - openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.DSSServiceDesigner, documentUri }); + openView(EVENT_TYPE.OPEN_VIEW, { view: MACHINE_VIEW.DSSResourceServiceDesigner, documentUri }); }); commands.registerCommand(COMMANDS.EDIT_K8_CONFIGURATION_COMMAND, async () => { @@ -507,7 +513,7 @@ export async function activateProjectExplorer(context: ExtensionContext, lsClien window.showErrorMessage('Cannot find workspace folder'); return; } - const langClient = getStateMachine(workspace.uri.fsPath).context().langClient; + const langClient = await MILanguageClient.getInstance(workspace.uri.fsPath); if (!langClient) { window.showErrorMessage('Language client not found.'); return; @@ -566,7 +572,7 @@ export async function activateProjectExplorer(context: ExtensionContext, lsClien if (filePath !== "") { const fileName = path.basename(filePath); const langClient = await MILanguageClient.getInstance(workspace.uri.fsPath); - const fileUsageIdentifiers = await langClient?.languageClient?.getResourceUsages(filePath); + const fileUsageIdentifiers = await langClient.getResourceUsages(filePath); const fileUsageMessage = fileUsageIdentifiers?.length && fileUsageIdentifiers?.length > 0 ? "It is used in:\n" + fileUsageIdentifiers.join(", ") : "No usage found"; window.showInformationMessage("Do you want to delete : " + fileName + "\n\n" + fileUsageMessage, { modal: true }, "Yes") .then(async answer => { @@ -635,7 +641,7 @@ export async function activateProjectExplorer(context: ExtensionContext, lsClien if (projectUri) { const currentLocation = getStateMachine(projectUri).context(); if (currentLocation.documentUri === file) { - openView(EVENT_TYPE.REPLACE_VIEW, { view: MACHINE_VIEW.Overview, projectUri }); + openView(EVENT_TYPE.REPLACE_VIEW, { view: MACHINE_VIEW.Overview, projectUri }); } else if (currentLocation?.view === MACHINE_VIEW.Overview) { refreshUI(projectUri); } @@ -654,7 +660,7 @@ export async function activateProjectExplorer(context: ExtensionContext, lsClien window.showErrorMessage('Cannot find workspace folder'); throw new Error('Cannot find workspace folder'); } - const langClient = getStateMachine(workspace.uri.fsPath).context().langClient; + const langClient = await MILanguageClient.getInstance(workspace.uri.fsPath); // Read the POM file const workspaceFolder = vscode.workspace.getWorkspaceFolder(Uri.file(filePath)); diff --git a/workspaces/mi/mi-extension/src/project-explorer/project-explorer-provider.ts b/workspaces/mi/mi-extension/src/project-explorer/project-explorer-provider.ts index 6161b15c4e5..c67e621e8ab 100644 --- a/workspaces/mi/mi-extension/src/project-explorer/project-explorer-provider.ts +++ b/workspaces/mi/mi-extension/src/project-explorer/project-explorer-provider.ts @@ -145,8 +145,8 @@ async function getProjectStructureData(): Promise { continue; } const langClient = await MILanguageClient.getInstance(rootPath); - const resp = await langClient?.languageClient?.getProjectExplorerModel(rootPath); - const projectDetailsRes = await langClient?.languageClient?.getProjectDetails(); + const resp = await langClient.getProjectExplorerModel(rootPath); + const projectDetailsRes = await langClient.getProjectDetails(); const runtimeVersion = projectDetailsRes.primaryDetails.runtimeVersion.value; const projectTree = await generateTreeData(workspace, resp, runtimeVersion); diff --git a/workspaces/mi/mi-extension/src/rpc-managers/ai-panel/rpc-manager.ts b/workspaces/mi/mi-extension/src/rpc-managers/ai-panel/rpc-manager.ts index b27a86cab72..d76570a97d7 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/ai-panel/rpc-manager.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/ai-panel/rpc-manager.ts @@ -50,6 +50,7 @@ import { codeDiagnostics } from "../../ai-panel/copilot/diagnostics/diagnostics" import { getLoginMethod } from '../../ai-panel/auth'; import { LoginMethod } from '@wso2/mi-core'; import { logInfo, logWarn, logError, logDebug } from '../../ai-panel/copilot/logger'; +import { MILanguageClient } from '../../lang-client/activator'; export class MIAIPanelRpcManager implements MIAIPanelAPI { private eventHandler: CopilotEventHandler; @@ -374,13 +375,7 @@ export class MIAIPanelRpcManager implements MIAIPanelAPI { this.eventHandler.handleCodeDiagnosticStart(xmlCodes); // Get diagnostics using existing RPC infrastructure - const { getStateMachine } = await import('../../stateMachine'); - const stateMachine = getStateMachine(this.projectUri); - if (!stateMachine) { - throw new Error('State machine not found for project'); - } - - const langClient = stateMachine.context().langClient; + const langClient = await MILanguageClient.getInstance(this.projectUri); if (!langClient) { throw new Error('Language client not available'); } diff --git a/workspaces/mi/mi-extension/src/rpc-managers/mi-data-mapper/rpc-manager.ts b/workspaces/mi/mi-extension/src/rpc-managers/mi-data-mapper/rpc-manager.ts index e0986507e3c..81a1a8a475e 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/mi-data-mapper/rpc-manager.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/mi-data-mapper/rpc-manager.ts @@ -57,6 +57,7 @@ import { DM_OPERATORS_FILE_NAME, DM_OPERATORS_IMPORT_NAME, READONLY_MAPPING_FUNC import { readTSFile, removeMapFunctionEntry, showMappingEndNotification } from "../../util/ai-datamapper-utils"; import { compareVersions } from "../../util/onboardingUtils"; import { mapDataMapper } from "../../ai-panel/copilot/data-mapper/mapper"; +import { MILanguageClient } from "../../lang-client/activator"; const undoRedoManager = new UndoRedoManager(); @@ -331,7 +332,7 @@ export class MiDataMapperRpcManager implements MIDataMapperAPI { const workspaceFolder = workspace.getWorkspaceFolder(Uri.file(filePath)); let miDiagramRpcManager: MiDiagramRpcManager = new MiDiagramRpcManager(this.projectUri); - const langClient = getStateMachine(this.projectUri).context().langClient; + const langClient = await MILanguageClient.getInstance(this.projectUri); const projectDetailsRes = await langClient?.getProjectDetails(); const runtimeVersion = projectDetailsRes.primaryDetails.runtimeVersion.value; const isResourceContentUsed = compareVersions(runtimeVersion, RUNTIME_VERSION_440) >= 0; diff --git a/workspaces/mi/mi-extension/src/rpc-managers/mi-debugger/rpc-manager.ts b/workspaces/mi/mi-extension/src/rpc-managers/mi-debugger/rpc-manager.ts index 8594322cf9f..1957ff755bd 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/mi-debugger/rpc-manager.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/mi-debugger/rpc-manager.ts @@ -33,13 +33,14 @@ import { } from "@wso2/mi-core"; import * as vscode from "vscode"; import { getStateMachine, refreshUI } from "../../stateMachine"; +import { MILanguageClient } from "../../lang-client/activator"; export class MiDebuggerRpcManager implements MiDebuggerAPI { constructor(private projectUri: string) { } async validateBreakpoints(params: ValidateBreakpointsRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const definition = await langClient.validateBreakpoints(params); resolve(definition); @@ -48,7 +49,7 @@ export class MiDebuggerRpcManager implements MiDebuggerAPI { async getBreakpointInfo(params: GetBreakpointInfoRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const breakpointInfo = await langClient.getBreakpointInfo(params); resolve(breakpointInfo); @@ -113,7 +114,7 @@ export class MiDebuggerRpcManager implements MiDebuggerAPI { async getStepOverBreakpoint(params: StepOverBreakpointRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const breakpointInfo = await langClient.getStepOverBreakpoint(params); resolve(breakpointInfo); diff --git a/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-handler.ts b/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-handler.ts index 3732e1f468f..acc2695b5e9 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-handler.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-handler.ts @@ -319,7 +319,7 @@ import { updatePropertiesInArtifactXML, getPropertiesFromArtifactXML, formatPomFile - // getBackendRootUrl - REMOVED: Backend URLs deprecated, all AI features use local LLM + // getBackendRootUrl - REMOVED: Backend URLs deprecated, all AI features use local LLM, } from "@wso2/mi-core"; import { Messenger } from "vscode-messenger"; import { MiDiagramRpcManager } from "./rpc-manager"; diff --git a/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts b/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts index b044e61ffa5..9542dde79cc 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.ts @@ -339,6 +339,7 @@ import { MiVisualizerRpcManager } from "../mi-visualizer/rpc-manager"; import { DebuggerConfig } from "../../debugger/config"; import { getKubernetesConfiguration, getKubernetesDataConfiguration } from "../../util/template-engine/mustach-templates/KubernetesConfiguration"; import { parseStringPromise, Builder } from "xml2js"; +import { MILanguageClient } from "../../lang-client/activator"; const AdmZip = require('adm-zip'); const { XMLParser, XMLBuilder } = require("fast-xml-parser"); @@ -473,7 +474,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { async tryOutMediator(params: MediatorTryOutRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.tryOutMediator(params); resolve(res); }); @@ -481,7 +482,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { async shutDownTryoutServer(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.shutdownTryoutServer(); resolve(res); }); @@ -499,7 +500,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { const payloadPath = path.join(this.projectUri, ".tryout", "input.json"); const payload = fs.readFileSync(payloadPath, "utf8"); params.inputPayload = payload - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getMediatorInputOutputSchema(params); resolve(res); }); @@ -526,7 +527,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { } return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getSyntaxTree({ documentIdentifier: { uri: documentUri @@ -631,12 +632,12 @@ export class MiDiagramRpcManager implements MiDiagramAPI { const getSwaggerName = (swaggerDefPath: string) => { const ext = path.extname(swaggerDefPath); - return `${name}${apiVersion !== "" ? `_v${apiVersion}` : ''}${ext}`; + return `${name}${apiVersion !== "" ? `_v${apiVersion}` : ''}${ext === ".yml" ? ".yaml" : ext }`; }; let fileName: string; let response: GenerateAPIResponse = { apiXml: "", endpointXml: "" }; if (!xmlData) { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const projectDetailsRes = await langClient?.getProjectDetails(); const runtimeVersion = projectDetailsRes.primaryDetails.runtimeVersion.value; const isRegistrySupported = compareVersions(runtimeVersion, RUNTIME_VERSION_440) < 0; @@ -679,10 +680,11 @@ export class MiDiagramRpcManager implements MiDiagramAPI { fileName = `${name}${apiVersion !== "" ? `_v${apiVersion}` : ''}`; if (saveSwaggerDef && swaggerDefPath) { + const ext = path.extname(swaggerDefPath); const swaggerRegPath = path.join( this.projectUri, SWAGGER_REL_DIR, - fileName + path.extname(swaggerDefPath) + fileName + (ext === ".yml" ? ".yaml" : ext) ); fs.mkdirSync(path.dirname(swaggerRegPath), { recursive: true }); fs.copyFileSync(swaggerDefPath, swaggerRegPath); @@ -1507,7 +1509,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { async getEndpointsAndSequences(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const resp = await langClient.getProjectStructure(this.projectUri); const artifacts = (resp.directoryMap as any).src.main.wso2mi.artifacts; @@ -1536,7 +1538,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { async getAllAPIcontexts(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const resp = await langClient.getProjectStructure(this.projectUri); const artifacts = (resp.directoryMap as any).src.main.wso2mi.artifacts; @@ -1552,7 +1554,7 @@ export class MiDiagramRpcManager implements MiDiagramAPI { async getTemplates(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const resp = await langClient.getProjectStructure(this.projectUri); const artifacts = (resp.directoryMap as any).src.main.wso2mi.artifacts; @@ -2648,6 +2650,10 @@ ${endpointAttributes} } await workspace.applyEdit(edit); + const file = Uri.file(params.documentUri); + let document = workspace.textDocuments.find(doc => doc.uri.fsPath === params.documentUri) + || await workspace.openTextDocument(file); + await document.save(); if (!params.disableFormatting) { const formatEdits = (editRequest: ExtendedTextEdit) => { @@ -3123,7 +3129,7 @@ ${endpointAttributes} async getESBConfigs(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const resp = await langClient.getProjectStructure(this.projectUri); const ESBConfigs: string[] = []; @@ -3436,7 +3442,7 @@ ${endpointAttributes} async convertPdfToBase64Images(params: string): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const images = await langClient.pdfToImagesBase64(params) resolve(images); }); @@ -3874,7 +3880,7 @@ ${endpointAttributes} async getDefinition(params: GetDefinitionRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const definition = await langClient.getDefinition(params); resolve(definition); @@ -3896,11 +3902,11 @@ ${endpointAttributes} } async getDiagnostics(params: GetDiagnosticsReqeust): Promise { - return getStateMachine(this.projectUri).context().langClient!.getDiagnostics(params); + return (await MILanguageClient.getInstance(this.projectUri)).getDiagnostics(params); } async getAvailableResources(params: GetAvailableResourcesRequest): Promise { - return getStateMachine(this.projectUri).context().langClient!.getAvailableResources(params); + return (await MILanguageClient.getInstance(this.projectUri)).getAvailableResources(params); } async browseFile(params: BrowseFileRequest): Promise { @@ -4201,7 +4207,7 @@ ${endpointAttributes} async getAvailableConnectors(params: GetAvailableConnectorRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getAvailableConnectors({ documentUri: params.documentUri, connectorName: params.connectorName @@ -4213,7 +4219,7 @@ ${endpointAttributes} async updateConnectors(params: UpdateConnectorRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.updateConnectors({ documentUri: params.documentUri }); @@ -4351,7 +4357,7 @@ ${endpointAttributes} async saveInboundEPUischema(params: SaveInboundEPUischemaRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.saveInboundEPUischema({ connectorName: params.connectorName, uiSchema: params.uiSchema @@ -4363,7 +4369,7 @@ ${endpointAttributes} async getInboundEPUischema(params: GetInboundEPUischemaRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getInboundEPUischema({ connectorName: params.connectorName, documentPath: params.documentPath @@ -4576,7 +4582,7 @@ ${keyValuesXML}`; async getConnectorConnections(params: GetConnectorConnectionsRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getConnectorConnections({ documentUri: params.documentUri, connectorName: params.connectorName @@ -4616,7 +4622,7 @@ ${keyValuesXML}`; async getAllRegistryPaths(params: GetAllRegistryPathsRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getRegistryFiles(params.path); resolve({ registryPaths: res.map(element => element.split(path.sep).join("/")) }); }); @@ -4624,7 +4630,7 @@ ${keyValuesXML}`; async getAllResourcePaths(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getResourceFiles(); resolve({ resourcePaths: res }); }); @@ -4632,7 +4638,7 @@ ${keyValuesXML}`; async getConfigurableEntries(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getConfigurableEntries(); resolve({ configurableEntries: res }); }); @@ -4640,7 +4646,7 @@ ${keyValuesXML}`; async getAllArtifacts(params: GetAllArtifactsRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getArifactFiles(params.path); resolve({ artifacts: res }); }); @@ -4648,7 +4654,7 @@ ${keyValuesXML}`; async getArtifactType(params: GetArtifactTypeRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getArtifactType(params.filePath); resolve({ artifactType: res.artifactType, artifactFolder: res.artifactFolder }); }); @@ -4865,7 +4871,7 @@ ${keyValuesXML}`; extName: "Devant", }; - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let integrationType: string | undefined; if (params.componentDir) { @@ -5041,7 +5047,7 @@ ${keyValuesXML}`; fs.mkdirSync(path.dirname(openAPISpecPath), { recursive: true }); }; - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const { swagger } = await langClient.swaggerFromAPI({ apiPath }); if (!fs.existsSync(openAPISpecPath)) { // Create the file if not exists @@ -5098,7 +5104,7 @@ ${keyValuesXML}`; return resolve({ swaggerExists: false }); } - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const { swagger: generatedSwagger } = await langClient.swaggerFromAPI({ apiPath: apiPath, swaggerPath: swaggerPath }); const swaggerContent = fs.readFileSync(swaggerPath, 'utf-8'); const isEqualSwagger = isEqualSwaggers({ @@ -5126,7 +5132,7 @@ ${keyValuesXML}`; let generatedSwagger = params.generatedSwagger; let existingSwagger = params.existingSwagger; if (!generatedSwagger || !existingSwagger) { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const response = await langClient.swaggerFromAPI({ apiPath: apiPath, ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) }); generatedSwagger = response.swagger; existingSwagger = fs.readFileSync(swaggerPath, 'utf-8'); @@ -5153,7 +5159,7 @@ ${keyValuesXML}`; let generatedSwagger = params.generatedSwagger; let existingSwagger = params.existingSwagger; if (!generatedSwagger || !existingSwagger) { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const response = await langClient.swaggerFromAPI({ apiPath }); generatedSwagger = response.swagger; existingSwagger = fs.readFileSync(swaggerPath, 'utf-8'); @@ -5272,7 +5278,7 @@ ${keyValuesXML}`; let range; if (!params.range) { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const st = await langClient.getSyntaxTree({ documentIdentifier: { uri: filePath @@ -5417,10 +5423,10 @@ ${keyValuesXML}`; async getOpenAPISpec(params: SwaggerTypeRequest): Promise { const swaggerPath = path.join(this.projectUri, SWAGGER_REL_DIR, `${path.basename(params.apiPath, ".xml")}.yaml`); - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response; if (params.isRuntimeService) { - const versionedUrl = exposeVersionedServices(this.projectUri); + const versionedUrl = await exposeVersionedServices(this.projectUri); response = await langClient.swaggerFromAPI({ apiPath: params.apiPath, port: DebuggerConfig.getServerPort(), projectPath: versionedUrl ? this.projectUri : "", ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) }); } else { response = await langClient.swaggerFromAPI({ apiPath: params.apiPath, ...(fs.existsSync(swaggerPath) && { swaggerPath: swaggerPath }) }); @@ -5542,7 +5548,7 @@ ${keyValuesXML}`; async testDbConnection(req: TestDbConnectionRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient; + const langClient = await MILanguageClient.getInstance(this.projectUri); const response = await langClient?.testDbConnection(req); resolve({ success: response ? response.success : false }); }); @@ -5608,7 +5614,7 @@ ${keyValuesXML}`; async checkDBDriver(className: string): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.checkDBDriver(className); resolve(res); }); @@ -5616,7 +5622,7 @@ ${keyValuesXML}`; async addDBDriver(params: AddDriverRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.addDBDriver(params); resolve(res); }); @@ -5624,7 +5630,7 @@ ${keyValuesXML}`; async removeDBDriver(params: AddDriverRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.removeDBDriver(params); resolve(res); }); @@ -5632,7 +5638,7 @@ ${keyValuesXML}`; async modifyDBDriver(params: AddDriverRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.modifyDBDriver(params); resolve(res); }); @@ -5641,7 +5647,7 @@ ${keyValuesXML}`; async generateDSSQueries(params: ExtendedDSSQueryGenRequest): Promise { const { documentUri, position, ...genQueryParams } = params; return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const xml = await langClient.generateQueries(genQueryParams); if (!xml) { @@ -5667,7 +5673,7 @@ ${keyValuesXML}`; async fetchDSSTables(params: DSSFetchTablesRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.fetchTables({ ...params, tableData: "", datasourceName: "" }); @@ -5677,7 +5683,7 @@ ${keyValuesXML}`; async getMediators(param: GetMediatorsRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.getMediators(param); resolve(response); }); @@ -5685,7 +5691,7 @@ ${keyValuesXML}`; async getMediator(param: GetMediatorRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.getMediator(param); resolve(response); }); @@ -5693,7 +5699,7 @@ ${keyValuesXML}`; async updateMediator(param: UpdateMediatorRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.generateSynapseConfig(param); if (response && response.textEdits) { let edits = response.textEdits; @@ -5717,7 +5723,7 @@ ${keyValuesXML}`; async getLocalInboundConnectors(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.getLocalInboundConnectors(); resolve(response); }); @@ -5725,7 +5731,7 @@ ${keyValuesXML}`; async getConnectionSchema(param: GetConnectionSchemaRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.getConnectionSchema(param); resolve(response); }); @@ -5734,7 +5740,7 @@ ${keyValuesXML}`; async getExpressionCompletions(params: ExpressionCompletionsRequest): Promise { return new Promise(async (resolve, reject) => { try { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getExpressionCompletions(params); if (!res.isIncomplete) { resolve(res); @@ -5751,7 +5757,7 @@ ${keyValuesXML}`; async getHelperPaneInfo(params: GetHelperPaneInfoRequest): Promise { return new Promise(async (resolve, reject) => { try { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); let response = await langClient.getHelperPaneInfo(params); resolve(response); } catch (error) { @@ -5763,7 +5769,7 @@ ${keyValuesXML}`; async testConnectorConnection(params: TestConnectorConnectionRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.testConnectorConnection(params); resolve(res); }); @@ -5887,7 +5893,7 @@ ${keyValuesXML}`; async getValueOfEnvVariable(variableName: string): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const response = await langClient.getConfigurableList(); const envVariable = response.find(variable => variable.key === variableName); if (envVariable && envVariable.value != null && envVariable.value !== "") { @@ -6121,7 +6127,13 @@ ${keyValuesXML}`; } } -function exposeVersionedServices(projectUri: string): boolean { +async function exposeVersionedServices(projectUri: string): Promise { + const langClient = await MILanguageClient.getInstance(projectUri); + const projectDetailsRes = await langClient?.getProjectDetails(); + const isVersionedDeploymentEnabled = projectDetailsRes?.buildDetails?.versionedDeployment?.value; + if (!isVersionedDeploymentEnabled) { + return false; + } const config = vscode.workspace.getConfiguration('MI', vscode.Uri.file(projectUri)); const serverPath = config.get('SERVER_PATH') || undefined; const configPath = serverPath ? path.join(serverPath, 'conf', 'deployment.toml') : ''; diff --git a/workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts b/workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts index f36f8f72b44..e8e95286fd0 100644 --- a/workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts +++ b/workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts @@ -92,6 +92,7 @@ import { TextEdit } from "vscode-languageclient"; import { downloadJavaFromMI, downloadMI, getProjectSetupDetails, getSupportedMIVersionsHigherThan, setPathsInWorkSpace, updateRuntimeVersionsInPom, getMIVersionFromPom } from '../../util/onboardingUtils'; import { extractCAppDependenciesAsProjects } from "../../visualizer/activate"; import { findMultiModuleProjectsInWorkspaceDir } from "../../util/migrationUtils"; +import { MILanguageClient } from "../../lang-client/activator"; Mustache.escape = escapeXml; @@ -145,7 +146,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async getProjectStructure(params: ProjectStructureRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getProjectStructure(this.projectUri); resolve(res); @@ -154,7 +155,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async getProjectDetails(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getProjectDetails(); resolve(res); }); @@ -162,7 +163,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async setDeployPlugin(params: MavenDeployPluginDetails): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.setDeployPlugin(params); await this.updatePom([res.textEdit]); resolve(res); @@ -171,7 +172,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async getDeployPluginDetails(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getDeployPluginDetails(); resolve(res); }); @@ -179,7 +180,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async removeDeployPlugin(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.removeDeployPlugin(); if (res.range.start.line !== 0 && res.range.start.character !== 0) { await this.updatePom([res]); @@ -196,7 +197,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { */ async updateProperties(params: UpdatePropertiesRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.updateProperties(params); await this.updatePom(res.textEdits); resolve(true); @@ -212,7 +213,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async reloadDependencies(params?: ReloadDependenciesRequest): Promise { return new Promise(async (resolve) => { let reloadDependenciesResult = true; - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const updateDependenciesResult = await langClient?.updateConnectorDependencies(); if (!updateDependenciesResult.toLowerCase().startsWith("success")) { const connectorsNotDownloaded: string[] = []; @@ -324,7 +325,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async updateDependencies(params: UpdateDependenciesRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const projectDetails = await langClient.getProjectDetails(); const existingDependencies = projectDetails.dependencies || []; @@ -367,7 +368,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async getDependencyStatusList(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getDependencyStatusList(); resolve(res); }); @@ -423,7 +424,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async updateConnectorDependencies(): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.updateConnectorDependencies(); await extractCAppDependenciesAsProjects(this.projectUri); resolve(res); @@ -432,7 +433,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async updateDependenciesFromOverview(params: UpdateDependenciesRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.updateDependencies({ dependencies: params.dependencies }); await this.updatePom(res.textEdits); resolve(true); @@ -775,7 +776,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { } async getProjectOverview(params: ProjectStructureRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const res = await langClient.getOverviewModel(); resolve(res); }); @@ -861,7 +862,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async importOpenAPISpec(params: ImportOpenAPISpecRequest): Promise { const { filePath } = params; - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); if (filePath && filePath.length > 0) { const connectorGenRequest = { openAPIPath: filePath, @@ -903,7 +904,7 @@ export class MiVisualizerRpcManager implements MIVisualizerAPI { async updateAiDependencies(params: UpdateAiDependenciesRequest): Promise { return new Promise(async (resolve) => { - const langClient = getStateMachine(this.projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(this.projectUri); const projectDetails = await langClient.getProjectDetails(); const existingDependencies = projectDetails.dependencies || []; diff --git a/workspaces/mi/mi-extension/src/stateMachine.ts b/workspaces/mi/mi-extension/src/stateMachine.ts index 94e29008ffd..22d9a3f4d06 100644 --- a/workspaces/mi/mi-extension/src/stateMachine.ts +++ b/workspaces/mi/mi-extension/src/stateMachine.ts @@ -14,41 +14,40 @@ import { VisualizerLocation, webviewReady } from '@wso2/mi-core'; -import { ExtendedLanguageClient } from './lang-client/ExtendedLanguageClient'; import { VisualizerWebview, webviews } from './visualizer/webview'; import { RPCLayer } from './RPCLayer'; import { history } from './history/activator'; -import { COMMANDS } from './constants'; +import { COMMANDS, MI_PROJECT_EXPLORER_VIEW_ID, WI_EXTENSION_ID, WI_PROJECT_EXPLORER_VIEW_ID, RUNTIME_VERSION_440 } from './constants'; import { activateProjectExplorer } from './project-explorer/activate'; import { MockService, STNode, UnitTest, Task, InboundEndpoint } from '../../syntax-tree/lib/src'; -import { logDebug } from './util/logger'; +import { log, logDebug } from './util/logger'; import { deriveConfigName, getSources } from './util/dataMapper'; import { fileURLToPath } from 'url'; import path = require('path'); import { activateTestExplorer } from './test-explorer/activator'; import { DMProject } from './datamapper/DMProject'; -import { setupEnvironment } from './util/onboardingUtils'; +import { setupEnvironment, getMIVersionFromPom, compareVersions } from './util/onboardingUtils'; import { getPopupStateMachine } from './stateMachinePopup'; import { askForProject } from './util/workspace'; import { containsMultiModuleNatureInProjectFile, containsMultiModuleNatureInPomFile, findMultiModuleProjectsInWorkspaceDir } from './util/migrationUtils'; const fs = require('fs'); interface MachineContext extends VisualizerLocation { - langClient: ExtendedLanguageClient | null; dependenciesResolved?: boolean; + isInWI: boolean; + isLegacyRuntime?: boolean; } const stateMachine = createMachine({ - /** @xstate-layout N4IgpgJg5mDOIC5QFsCWA6VA7VAXVAhgDaoBeYAxBAPZZiZYBu1A1vQMYAWY7LACgCdqAKx64A2gAYAuolAAHarDypackAA9EAJm0A2dJICs2yQE49k7QEYT1vXoA0IAJ469ADnTWPAdiOSDkY+gX4AvmHOaAwqxGSUNHQMzGzoXDz8QqLsEtaySCCKyvhqBVoINgbGphZWtpVOrojW-uhGetomehYWHtpmRhFRGNixJORUtPTYKRzcvIIiYuLa+QpKKqWg5aZVJuaWNnYOzm4IfehmAMy+ACz+vleS1mbaV9pDINGj+HETidMmKw5hlFtkJFc1oUNiUsOodlc9jVDvV7I0zlcBug7k9btdfHpbHjPt8cL9xgkpslgWl5pkljlxLcoUVNnCyjpbkiDnVjujEITtOgPCKRf1Xo9jCSRmTCBSKGABEIBOh5EQCLgAGbUATIWmgrLLGTqVmw+GIEynZoedroLmPW67PoEjzStK0Og5HUASTJkySMxp0XYHrEPrJCED7A1qiwUmk8ZNMNj5oQvjMt0Mt3svg8xl8L35FSMV28RjMjxMHgs7w8ejd8kNOQAImBcGJIP7AbN0NFGwzcK32zlIJGgdHYfHEwVTSmOQgOlaEPYWpc9I8M9ZbpJbqK3dQiBAwWIhx2IF3qalogej03B22z2PmBPY1PjTPk1tNIhfNol7ZfEkO112zHcrm3FpfDdIhYF9PAL0DK8MBguDcCfagX1oN8WU-dltkQe4jGxQCPExDxbluTEzGsf8iXQJ4jBLSwAj0K4Xmg2C-QBS96GiFCIyjGMsJkcQ8iTYo53whAuSI3wSLIiiqJoppl0Cax0E8Yx2kRG1JFdSIvmQzj4MVZVVXVLUdT1PjjLQwTJxE991gkr9ykI4i9IUyizGo-9CQMbo9BLEtAiMPo3QEMACAgFx0AIHJUEYDUwAAeVwbgBAAMSi3AAFdItgBCgSQ9BIui2L4vwJL2zSjLso1fK4HQzC40cnCXLw79VOubxbjCm4rhFDpJF8f9fy8UijD68jrCsfRBgM6Iypi9BGFQMAAHcABlqGi7AoCKnslqila1s2na9qwKBmqE1qEyc6EOtTWwOmFPRpu0G08QGUaVPsIxfHQbRfwzbcnjzFoIpO2Kzo2zLsAgfbDqDDBlph9a4YR-aboc+72rZZ6My8V5uhuEUKxuIw-PA7FZsdDxbERK4rgW4ZSuh1aMYAZVweKWCR7jEN41GOdhnm+ex+zXza8SCfnN4bDtewKLkl5Qb8gGgZBijJHB54oMWkXys5zaAFV5AgZLz0F4rhfZ43YfNy32wgHHpbx2WzXnFpWOFZmXkkQOt06P8-sU4DdfA9MOlJqGHYxgA5Ag1qgK3kZKtGTY2pOU6tt3hI9j8nvl951Ozd77gLHyKP-d4hW8rkgjCkw49OjGACVoYoFK+AAUQTgB9AA1b1e4AdWnZy5ak2aeq3frHiG0xfrOexmaB2abgeaj3tZwz7bbzbO-Kih297vgtoAQQAYV74fR4nh7Z1c5pzFLefSMXutl--EtAeb-oIEGZWH0mzTOsNj4xQoAnS+I8ADil8AAqvdJ6PWnl1We79poDSXiNf8FF1K1BZiHIK5Y97HXjkfLumVvRbTvr3Zs3pEGoOfp1comDeoL0Gt-PBf1TBAR8BmQk9xtykWsK3dGm1e6I3wFdCgDCmED2bClBOKCn64Wei8UsZhqxBXXBWOs1hQ6ry3GYDS1ZsxvApgDchGA6AbWPDkLOF1EZyJtkdOxm1HG4GcbtVx10pYFxYRo+cDN1KWEdC0AYg0WYrx-FYei9wbAZmop9DMbp7HeKzpAlw3c+6DxHuPYJxcpLfzaGxYGgR9C2GuEuSwBhfy6FmjYfwoMIgGSwNQCAcB1BoE9pJLqABaIswzDCB3GRMoOW43Q-DlPEfpL9pLGJ-LoNo1hMSfReFNVitw3QhiwJ6XA4Y8ALLYRaN4Gl54+WIdYZWS5OjqW4dROm2ZfwswbHeU8I4ICnOejueu9xqIUUdGFe5wR6Lk1uTuV5bxbHoBvN4r5LtfnzmCKWYR5Zrh2DuSpBm3gHDrlmoHLemIOKoRRVJYGQpej+CsISNeyzlzlnReBYwEFczMQkRSrqjwDCYjCv0Fo-RcweH-FUtougGb9CmuBBwEi4oJWqqldKip6p5QKty8ouZMz8r6NREGIqxo7jaHUHwn1WmgP3uAjGLj9qauaMzMxfgAgMyjqYq41NqWYksJiPSLR3jythvDLA-j7XLgJKWUibEzDjODpaP6rEvVEJjQzR4HxDYH0kRtcWvA7VF3QTsW5hCfLkXAv1KanrLjet1im-16awGiwxk7K2YaXpeCeKYIxu5tzbPwdmcxAxZqMT0npS1FDD7Z2TqgVOyL81e0pcEPlFcTA2EpoyrcFFvDVmCFpEdIpA0d2hmG6sgNA79D6l29ZBJaKvTrHmZ4LNmZsQPVImReap7zowY64UtLXX3HdbRMKWtgYlmos8PqbpEawAIAAIyIJAMNu8N5+FzKYci5Fbj-lImYhwfguRckCCCjJXi7xhuCpcvqjx-adFBSpYIZjGKMQ2UK+wY7PEOLvL4y6UAyOkQowDJ9RjGKipUoSJ1Qm2U7OBsRjjA5slHrnQM9hzwhQAzSc8Ewry6k3DenmKa5YCwvANhEIAA */ id: 'mi', initial: 'initialize', predictableActionArguments: true, context: { projectUri: "", - langClient: null, errors: [], view: MACHINE_VIEW.Welcome, - dependenciesResolved: false + dependenciesResolved: false, + isInWI: false }, states: { initialize: { @@ -73,7 +72,7 @@ const stateMachine = createMachine({ view: (context, event) => MACHINE_VIEW.UnsupportedProject, projectUri: (context, event) => event.data.projectUri, isOldProject: (context, event) => true, - displayOverview: (context, event) => true, + displayOverview: (context, event) => true }) }, { @@ -84,7 +83,7 @@ const stateMachine = createMachine({ actions: assign({ view: (context, event) => MACHINE_VIEW.UnsupportedWorkspace, projectUri: (context, event) => event.data.projectUri, - displayOverview: (context, event) => true, + displayOverview: (context, event) => true }) }, { @@ -96,13 +95,15 @@ const stateMachine = createMachine({ customProps: (context, event) => event.data.customProps, projectUri: (context, event) => event.data.projectUri, isOldProject: (context, event) => event.data.isOldProject, - displayOverview: (context, event) => event.data.displayOverview + displayOverview: (context, event) => event.data.displayOverview, + isLegacyRuntime: (context, event) => event.data.isLegacyRuntime + }) }, { target: 'newProject', // Assuming false means new project - cond: (context, event) => event.data.isProject === false && event.data.isOldProject === false, + cond: (context, event) => !context.isInWI && event.data.isProject === false && event.data.isOldProject === false, actions: assign({ view: (context, event) => MACHINE_VIEW.Welcome }) @@ -113,7 +114,7 @@ const stateMachine = createMachine({ target: 'disabled', actions: assign({ view: (context, event) => MACHINE_VIEW.Disabled, - errors: (context, event) => event.data + errors: (context, event) => event.data, }) } } @@ -170,14 +171,12 @@ const stateMachine = createMachine({ target: 'ready', cond: (context, event) => context.displayOverview === true, actions: assign({ - langClient: (context, event) => event.data }) }, { target: 'ready.viewReady', cond: (context, event) => context.displayOverview === false, actions: assign({ - langClient: (context, event) => event.data, isLoading: (context, event) => false }) } @@ -391,13 +390,9 @@ const stateMachine = createMachine({ return new Promise(async (resolve, reject) => { console.log("Waiting for LS to be ready " + new Date().toLocaleTimeString()); try { - vscode.commands.executeCommand(COMMANDS.FOCUS_PROJECT_EXPLORER); - const instance = await MILanguageClient.getInstance(context.projectUri!); - const errors = instance.getErrors(); - if (errors.length) { - return reject(errors); - } - const ls = instance.languageClient; + const treeViewId = context.isInWI ? WI_PROJECT_EXPLORER_VIEW_ID : MI_PROJECT_EXPLORER_VIEW_ID; + vscode.commands.executeCommand(`${treeViewId}.focus`); + const ls = await MILanguageClient.getInstance(context.projectUri!); vscode.commands.executeCommand('setContext', 'MI.status', 'projectLoaded'); resolve(ls); @@ -414,6 +409,7 @@ const stateMachine = createMachine({ if (!context?.projectUri) { return reject(new Error("Project URI is not defined")); } + if (!webviews.has(context.projectUri)) { const panel = new VisualizerWebview(context.view!, context.projectUri, extension.webviewReveal); webviews.set(context.projectUri!, panel); @@ -460,7 +456,7 @@ const stateMachine = createMachine({ }, findView: (context, event): Promise => { return new Promise(async (resolve, reject) => { - const langClient = context.langClient!; + const langClient = await MILanguageClient.getInstance(context.projectUri!); const viewLocation = context; if (context.view === MACHINE_VIEW.IdpConnectorSchemaGeneratorForm) { @@ -600,7 +596,7 @@ const stateMachine = createMachine({ } } if (viewLocation.view === MACHINE_VIEW.ResourceView) { - const res = await langClient!.getDiagnostics({ documentUri: context.documentUri! }); + const res = await langClient.getDiagnostics({ documentUri: context.documentUri! }); if (res.diagnostics && res.diagnostics.length > 0) { viewLocation.diagnostics = res.diagnostics; } @@ -652,8 +648,8 @@ const stateMachine = createMachine({ }, activateOtherFeatures: (context, event) => { return new Promise(async (resolve, reject) => { - const ls = await MILanguageClient.getInstance(context.projectUri!); - await activateProjectExplorer(extension.context, ls.languageClient!); + const treeviewId = context.isInWI ? WI_PROJECT_EXPLORER_VIEW_ID : MI_PROJECT_EXPLORER_VIEW_ID; + await activateProjectExplorer(treeviewId, extension.context, context.projectUri!, context.isInWI); await activateTestExplorer(extension.context); resolve(true); }); @@ -667,7 +663,8 @@ const stateMachine = createMachine({ }, focusProjectExplorer: (context, event) => { return new Promise(async (resolve, reject) => { - vscode.commands.executeCommand(COMMANDS.FOCUS_PROJECT_EXPLORER); + const treeViewId = context.isInWI ? WI_PROJECT_EXPLORER_VIEW_ID : MI_PROJECT_EXPLORER_VIEW_ID; + vscode.commands.executeCommand(`${treeViewId}.focus`); resolve(true); }); } @@ -691,11 +688,12 @@ export const getStateMachine = (projectUri: string, context?: VisualizerLocation if (!workspaces) { console.warn('No workspace folder is open.'); } + stateService = interpret(stateMachine.withContext({ projectUri: projectUri, - langClient: null, errors: [], view: MACHINE_VIEW.Overview, + isInWI: vscode.extensions.getExtension(WI_EXTENSION_ID) ? true : false, ...context })).start(); stateMachines.set(projectUri, stateService); @@ -826,7 +824,7 @@ function updateProjectExplorer(location: VisualizerLocation | undefined) { async function checkIfMiProject(projectUri: string, view: MACHINE_VIEW = MACHINE_VIEW.Overview) { console.log(`Detecting project in ${projectUri} - ${new Date().toLocaleTimeString()}`); - let isProject = false, isOldProject = false, isOldWorkspace = false, displayOverview = true, isEnvironmentSetUp = false; + let isProject = false, isOldProject = false, isOldWorkspace = false, displayOverview = true, isEnvironmentSetUp = false, isLegacyRuntime = true; const customProps: any = {}; try { // Check for pom.xml files excluding node_modules directory @@ -873,6 +871,9 @@ async function checkIfMiProject(projectUri: string, view: MACHINE_VIEW = MACHINE } } + const runtimeVersion = await getMIVersionFromPom(projectUri); + isLegacyRuntime = runtimeVersion ? compareVersions(runtimeVersion, RUNTIME_VERSION_440) < 0 : true; + vscode.commands.executeCommand('setContext', 'MI.status', 'projectDetected'); vscode.commands.executeCommand('setContext', 'MI.projectType', 'miProject'); // for command enablements await extension.context.workspaceState.update('projectType', 'miProject'); @@ -910,7 +911,8 @@ async function checkIfMiProject(projectUri: string, view: MACHINE_VIEW = MACHINE projectUri, // Return the path of the detected project view, customProps, - isEnvironmentSetUp + isEnvironmentSetUp, + isLegacyRuntime }; } diff --git a/workspaces/mi/mi-extension/src/test-explorer/activator.ts b/workspaces/mi/mi-extension/src/test-explorer/activator.ts index dfe4952ea6c..7b3d8c7cac0 100644 --- a/workspaces/mi/mi-extension/src/test-explorer/activator.ts +++ b/workspaces/mi/mi-extension/src/test-explorer/activator.ts @@ -97,7 +97,7 @@ export async function activateTestExplorer(extensionContext: ExtensionContext) { const fileUri = `${id.split('.xml/')[0]}.xml`; const testCaseName = id.split('.xml/')[1]; const langClient = await MILanguageClient.getInstance(getProjectRoot(Uri.parse(fileUri))!); - const st = await langClient?.languageClient?.getSyntaxTree({ + const st = await langClient.getSyntaxTree({ documentIdentifier: { uri: fileUri }, @@ -160,7 +160,7 @@ export async function activateTestExplorer(extensionContext: ExtensionContext) { try { const projectRoot = getProjectRoot(Uri.file(fileUri)); const langClient = await MILanguageClient.getInstance(projectRoot!); - const st = await langClient?.languageClient?.getSyntaxTree({ + const st = await langClient.getSyntaxTree({ documentIdentifier: { uri: fileUri }, @@ -271,7 +271,7 @@ export async function activateTestExplorer(extensionContext: ExtensionContext) { export async function createTests(uri: Uri) { const projectRoot = getProjectRoot(uri); const langClient = await MILanguageClient.getInstance(projectRoot!); - const projectDetails = await langClient?.languageClient?.getProjectDetails(); + const projectDetails = await langClient.getProjectDetails(); const projectName = projectDetails?.primaryDetails?.projectName?.value ?? getProjectName(uri); if (!testController || !projectRoot || !projectName) { @@ -351,7 +351,7 @@ async function getTestCaseNamesAndTestSuiteType(uri: Uri) { } const langClient = await MILanguageClient.getInstance(projectUri); - const st = await langClient?.languageClient?.getSyntaxTree({ + const st = await langClient.getSyntaxTree({ documentIdentifier: { uri: uri.fsPath }, @@ -363,7 +363,7 @@ async function getTestCaseNamesAndTestSuiteType(uri: Uri) { const unitTestST: UnitTest = st?.syntaxTree["unit-test"]; const testArtifact = unitTestST?.unitTestArtifacts?.testArtifact?.artifact?.textNode; - const projectStructure = await langClient.languageClient!.getProjectStructure(projectUri); + const projectStructure = await langClient!.getProjectStructure(projectUri); const artifacts = projectStructure.directoryMap.src?.main?.wso2mi?.artifacts; const apis = artifacts?.apis?.map((api: ProjectStructureArtifactResponse) => { return { name: api.name, path: api.path.split(projectUri)[1], type: "Api" } }); @@ -397,7 +397,7 @@ async function getTestCases(uri: Uri) { const projectRoot = getProjectRoot(uri); const langClient = await MILanguageClient.getInstance(projectRoot!); - const st = await langClient?.languageClient?.getSyntaxTree({ + const st = await langClient.getSyntaxTree({ documentIdentifier: { uri: uri.fsPath }, diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts index 50c31504b8e..ced5973eed6 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts @@ -43,7 +43,7 @@ export class API { } catch (error) { console.error("Error retrieving iframe title:", error); iframeTitle = null; - } + } if (iframeTitle != MACHINE_VIEW.ADD_ARTIFACT) { const projectExplorer = new ProjectExplorer(this._page); await projectExplorer.goToOverview(projectName); @@ -212,6 +212,9 @@ export class API { console.log("Navigating to project overview"); const apiProjectName = `NewTestAPI${attemptId}:v1.0.2`; const item = await projectExplorer.findItem(['Project testProject', 'APIs', apiProjectName], true); + if (!item) { + throw new Error(`Tree item "${apiProjectName}" not found in Project Explorer`); + } console.log("Found project testProject"); await item.getByRole('button', { name: 'Open Service Designer' }).click(); } @@ -244,7 +247,7 @@ export class API { // 2s wait (2000ms) to avoid the intermittent issue of the button not being clickable console.log("Waiting for 2s before clicking on delete API button"); await page.page.waitForTimeout(2000); - await vscodeButton.click({force: true}); + await vscodeButton.click({ force: true }); const deleteBtn = webview.getByText('Delete'); console.log("Clicked on delete API from overview"); await deleteBtn.waitFor(); @@ -326,7 +329,7 @@ export class API { await apiFormFrame.getByRole('textbox', { name: 'WSDL URL' }).fill('https://www.w3schools.com/xml/tempconvert.asmx?WSDL'); const submitBtn = await getVsCodeButton(apiFormFrame, 'Create', "primary"); expect(await submitBtn.isEnabled()).toBeTruthy(); - await submitBtn.click({force: true}); + await submitBtn.click({ force: true }); console.log("Clicked on create"); const webView = await switchToIFrame('Service Designer', this._page, 90000); if (!webView) { @@ -399,7 +402,7 @@ export class API { console.log("Switched to Service Designer iframe"); } - public async openDiagramView(name: string, resourcePath : string) { + public async openDiagramView(name: string, resourcePath: string) { const projectExplorer = new ProjectExplorer(this._page); await projectExplorer.findItem(['Project testProject', 'APIs', name, resourcePath], true); const webView = await switchToIFrame('Resource View', this._page); diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts index 3ed2121a8a0..42a0d54188a 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/DataService.ts @@ -67,9 +67,9 @@ export class DataService { await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'Data Services', prevName], true); - const webView = await switchToIFrame('Data Service Designer', this._page); + const webView = await switchToIFrame('DSS Resource Designer', this._page); if (!webView) { - throw new Error("Failed to switch to Data Service Designer iframe"); + throw new Error("Failed to switch to DSS Resource Designer iframe"); } const frame = webView.locator('div#root'); await frame.getByTestId('edit-button').getByLabel('Icon Button').click(); @@ -156,9 +156,9 @@ export class DataService { await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'Data Services', prevName], true); - const webView = await switchToIFrame('Data Service Designer', this._page); + const webView = await switchToIFrame('DSS Resource Designer', this._page); if (!webView) { - throw new Error("Failed to switch to Data Service Designer iframe"); + throw new Error("Failed to switch to DSS Resource Designer iframe"); } const frame = webView.locator('div#root'); await frame.waitFor(); @@ -292,9 +292,9 @@ export class DataService { await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'Data Services', prevName], true); - const webView = await switchToIFrame('Data Service Designer', this._page); + const webView = await switchToIFrame('DSS Resource Designer', this._page); if (!webView) { - throw new Error("Failed to switch to Data Service Designer iframe"); + throw new Error("Failed to switch to DSS Resource Designer iframe"); } const frame = webView.locator('div#root'); await frame.waitFor(); @@ -413,9 +413,9 @@ export class DataService { await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'Data Services', prevName], true); - const webView = await switchToIFrame('Data Service Designer', this._page); + const webView = await switchToIFrame('DSS Resource Designer', this._page); if (!webView) { - throw new Error("Failed to switch to Data Service Designer iframe"); + throw new Error("Failed to switch to DSS Resource Designer iframe"); } const frame = webView.locator('div#root'); await frame.waitFor(); @@ -514,9 +514,9 @@ export class DataService { await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'Data Services', prevName], true); - const webView = await switchToIFrame('Data Service Designer', this._page); + const webView = await switchToIFrame('DSS Resource Designer', this._page); if (!webView) { - throw new Error("Failed to switch to Data Service Designer iframe"); + throw new Error("Failed to switch to DSS Resource Designer iframe"); } const frame = webView.locator('div#root'); await frame.waitFor(); diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ProjectExplorer.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ProjectExplorer.ts index ab7cd0a6567..61a112909d8 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ProjectExplorer.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ProjectExplorer.ts @@ -33,8 +33,8 @@ export class ProjectExplorer { await this.explorer.waitFor(); } - public async findItem(path: string[], click: boolean = false) { - let currentItem; + public async findItem(path: string[], click: boolean = false): Promise { + let currentItem: Locator | undefined = undefined; for (let i = 0; i < path.length; i++) { currentItem = this.explorer.locator(`div[role="treeitem"][aria-label="${path[i]}"]`); diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/UnitTest.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/UnitTest.ts index 0a9704a75ed..e19eb1bb4b9 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/UnitTest.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/UnitTest.ts @@ -16,7 +16,7 @@ * under the License. */ -import { Page } from "@playwright/test"; +import { Locator, Page } from "@playwright/test"; import { Form } from "./Form"; import { ProjectExplorer } from "./ProjectExplorer"; @@ -92,9 +92,15 @@ export class UnitTest { public async init() { console.log('Selecting Testing section in VS Code'); - const testBtn = this._page.getByRole('tab', { name: 'Testing' }).locator('a'); - await testBtn.waitFor(); - await testBtn.click(); + const testActivity = this._page.getByRole('tab', { name: 'Testing' }); + await testActivity.waitFor(); + if ((await testActivity.getAttribute('aria-selected')) !== 'true') { + const testBtn = testActivity.locator('a'); + await testBtn.waitFor(); + await testBtn.click(); + } else { + console.log('Testing section is already selected'); + } } public async openUnitTestFormByMainBtn() { @@ -126,7 +132,7 @@ export class UnitTest { console.log('Opening Mock Service Form'); const form = new Form(this._page, 'Mock Service'); await form.switchToFormView(); - return form; + return form; } private async addSupportiveArtifacts(parentForm: Form, artifacts: string[]) { @@ -134,14 +140,14 @@ export class UnitTest { for (const artifact of artifacts) { console.log('Adding supportive artifact: ', artifact); const paramManager = await parentForm.getSimpleParamManager('Supportive Artifact', 'testSuiteSupportiveArtifactsSection'); - const form = await paramManager.getAddNewForm(); + const form = await paramManager.getAddNewForm(); await form.fill({ - values: { - 'Name': { - type: 'combo', - value: artifact + values: { + 'Name': { + type: 'combo', + value: artifact + } } - } }); await form.submit('Save'); } @@ -189,7 +195,7 @@ export class UnitTest { values: { 'Name*': { type: 'input', - value: testCase.name + value: testCase.name }, 'Resource path*': { type: 'input', @@ -197,7 +203,7 @@ export class UnitTest { }, 'Resource method': { type: 'dropdown', - value: testCase.resourceMethod + value: testCase.resourceMethod }, 'Resource Protocol': { type: 'dropdown', @@ -260,7 +266,7 @@ export class UnitTest { }); } } - + private async addTestCases(parentForm: Form, testCases: TestCaseData[]) { console.log('Adding test cases to Unit Test'); for (const testCase of testCases) { @@ -311,7 +317,7 @@ export class UnitTest { const requestHeaderForm = await requestHeaderParamManager.getAddNewForm(); await this.fillResourceHeaderForm(requestHeaderForm, header); await requestHeaderForm.submit('Save'); - } + } console.log('Adding mock service response headers'); for (const header of resource.expectedResponse.headers ?? []) { const responseHeaderParamManager = await resourceForm.getDefaultParamManager('Response', 'Add Header', 'card-select-mockResourceResponseCard'); @@ -445,10 +451,13 @@ export class UnitTest { const testExplorer = new ProjectExplorer(this._page, 'Test Explorer'); await testExplorer.init(); await this._page.waitForTimeout(1000); - await testExplorer.findItem([`${this.projectName} (Not yet run)`, `${name} (Not yet run)`]); + const treeItem = await testExplorer.findItem([`${this.projectName} (Not yet run)`, `${name} (Not yet run)`]) as Locator; + if (!treeItem) { + throw new Error(`Unit test "${name}" not found in Test Explorer`); + } console.log(`Expand the explorer to ensure the unit test "${name}" is visible`); - await this._page.getByLabel('Add test case').waitFor(); - await this._page.getByLabel('Add test case').click(); + await treeItem.getByLabel('Add test case').waitFor(); + await treeItem.getByLabel('Add test case').click(); console.log(`Clicked on "Add test case" button for unit test "${name}"`); } @@ -456,14 +465,17 @@ export class UnitTest { console.log('Opening Edit view of Unit Test:', name); const testExplorer = new ProjectExplorer(this._page, 'Test Explorer'); await testExplorer.init(); - await testExplorer.findItem([`${this.projectName} (Not yet run)`, `${name} (Not yet run)`]); - await this._page.getByText(name, { exact: true }).click(); - await this._page.getByRole('button', { name: 'Edit test suite' }).click(); + const treeItem = await testExplorer.findItem([`${this.projectName} (Not yet run)`, `${name} (Not yet run)`]) as Locator; + if (!treeItem) { + throw new Error(`Unit test "${name}" not found in Test Explorer`); + } + await treeItem.getByText(name, { exact: true }).click(); + await treeItem.getByRole('button', { name: 'Edit test suite' }).click(); } private async openEditViewOfMockService(name: string) { console.log('Opening Edit view of Mock Service:', name); - const mockServiceExplorer = new ProjectExplorer(this._page, 'Mock Services'); + const mockServiceExplorer = new ProjectExplorer(this._page, 'Mock Services'); await mockServiceExplorer.init(); await mockServiceExplorer.findItem([this.projectName + ' ', name + ' '], true); await this._page.getByRole('button', { name: 'Edit mock service' }).click(); @@ -471,7 +483,7 @@ export class UnitTest { public async addMockServiceFromSidePanel(data: MockServiceData) { console.log('Adding Mock Service from side panel'); - const mockServiceExplorer = new ProjectExplorer(this._page, 'Mock Services'); + const mockServiceExplorer = new ProjectExplorer(this._page, 'Mock Services'); await mockServiceExplorer.init(); await mockServiceExplorer.findItem([this.projectName + ' '], true); await this._page.getByLabel('Add mock service').waitFor(); diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/unitTestSuite.spec.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/unitTestSuite.spec.ts index 7f941102ee2..d7ca2025985 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/unitTestSuite.spec.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/unitTestSuite.spec.ts @@ -100,6 +100,28 @@ export default function createTests() { }); }); + await test.step('Add a unit test by Button click', async () => { + const unitTest = new UnitTest(page.page); + await unitTest.init(); + await unitTest.openUnitTestFormByMainBtn(); + await unitTest.createUnitTest({ + name: `unitTestByBtn1-${testAttempt}`, + artifactType: 'API', + artifact: 'unitTestAPI1-' + testAttempt, + supportiveArtifacts: ['unitTestSeq1-' + testAttempt, 'unitTestSeq2-' + testAttempt], + registryResources: ['xsltForUnitTest1-' + testAttempt, 'xsltForUnitTest2-' + testAttempt], + testCases: [ + { + name: 'TestCase1-' + testAttempt, + resourcePath: '/testCase1', + resourceMethod: 'GET', + resourceProtocol: 'HTTP', + inputPayload: '{ "key": "value" }', + } + ] + }); + }); + await test.step('Add a unit test', async () => { const unitTest = new UnitTest(page.page); await unitTest.init(); diff --git a/workspaces/mi/mi-extension/src/util/fileOperations.ts b/workspaces/mi/mi-extension/src/util/fileOperations.ts index f4f6da17906..c790d60c764 100644 --- a/workspaces/mi/mi-extension/src/util/fileOperations.ts +++ b/workspaces/mi/mi-extension/src/util/fileOperations.ts @@ -616,7 +616,7 @@ export function deleteDataMapperResources(filePath: string): Promise<{ status: b removeEntryFromArtifactXML(projectDir, artifactXmlSavePath, dmName + '_inputSchema.json'); removeEntryFromArtifactXML(projectDir, artifactXmlSavePath, dmName + '_outputSchema.json'); removeEntryFromArtifactXML(projectDir, artifactXmlSavePath, dmName + '.dmc'); - workspace.fs.delete(Uri.parse(projectDirPath), { recursive: true, useTrash: true }); + workspace.fs.delete(Uri.file(projectDirPath), { recursive: true, useTrash: true }); resolve({ status: true, info: "Datamapper resources removed" }); } }); diff --git a/workspaces/mi/mi-extension/src/util/index.ts b/workspaces/mi/mi-extension/src/util/index.ts index 5f2c8fd58d5..35c2effe754 100644 --- a/workspaces/mi/mi-extension/src/util/index.ts +++ b/workspaces/mi/mi-extension/src/util/index.ts @@ -178,6 +178,7 @@ export function createGitignoreFile(targetPath: string): Promise { // Common .gitignore patterns const gitignoreContent = ` .wso2mi/ +.env ############################## ## Java ############################## @@ -204,6 +205,8 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties .mvn/wrapper/maven-wrapper.jar +mvnw +mvnw.cmd ############################## ## Visual Studio Code diff --git a/workspaces/mi/mi-extension/src/util/schemaBuilder.ts b/workspaces/mi/mi-extension/src/util/schemaBuilder.ts index 7b4c58d1a9f..b92175abdc0 100644 --- a/workspaces/mi/mi-extension/src/util/schemaBuilder.ts +++ b/workspaces/mi/mi-extension/src/util/schemaBuilder.ts @@ -19,6 +19,7 @@ import { JSONSchema3or4 } from "to-json-schema"; import { getStateMachine } from "../stateMachine"; import { IOType } from "@wso2/mi-core"; +import { MILanguageClient } from "../lang-client/activator"; export function convertToJSONSchema(fileContent: JSONSchema3or4): JSONSchema3or4 { let schema = JSON.parse(fileContent); @@ -26,7 +27,7 @@ export function convertToJSONSchema(fileContent: JSONSchema3or4): JSONSchema3or4 } export async function generateSchema(ioType: IOType, schemaType: string, filePath: string, projectUri: string): Promise { - const langClient = getStateMachine(projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(projectUri); const response = await langClient.generateSchema({ filePath: filePath, delimiter: "", @@ -41,7 +42,7 @@ export async function generateSchema(ioType: IOType, schemaType: string, filePat } export async function generateSchemaFromContent(projectUri: string, ioType: IOType, content: string, fileType: string, csvDelimiter?: string): Promise { - const langClient = getStateMachine(projectUri).context().langClient!; + const langClient = await MILanguageClient.getInstance(projectUri); const response = await langClient.generateSchemaFromContent({ fileContent: content, delimiter: csvDelimiter ?? "", diff --git a/workspaces/mi/mi-extension/src/util/swagger.ts b/workspaces/mi/mi-extension/src/util/swagger.ts index fbdb406de3b..66f893a72c2 100644 --- a/workspaces/mi/mi-extension/src/util/swagger.ts +++ b/workspaces/mi/mi-extension/src/util/swagger.ts @@ -24,6 +24,7 @@ import path from "path"; import * as vscode from 'vscode'; import { deleteRegistryResource } from "./fileOperations"; import { getStateMachine } from "../stateMachine"; +import { MILanguageClient } from "../lang-client/activator"; const fs = require('fs'); @@ -296,7 +297,7 @@ export function generateSwagger(apiPath: string): Promise { const addDeploymentType = compareVersions(miVersion, RUNTIME_VERSION_450) >= 0; @@ -417,7 +417,7 @@ export const rootPomXmlContent = (projectName: string, groupID: string, artifact org.wso2.maven synapse-unit-test-maven-plugin - 5.4.12 + 5.4.13 synapse-unit-test diff --git a/workspaces/mi/mi-extension/src/util/workspace.ts b/workspaces/mi/mi-extension/src/util/workspace.ts index 82026ab46c5..2112fffc582 100644 --- a/workspaces/mi/mi-extension/src/util/workspace.ts +++ b/workspaces/mi/mi-extension/src/util/workspace.ts @@ -16,12 +16,12 @@ * under the License. */ -import { Position, Range, Uri, WorkspaceEdit, commands, workspace, window } from "vscode"; +import { Position, Range, Uri, WorkspaceEdit, commands, workspace, window, TabInputText, Disposable } from "vscode"; import * as fs from "fs"; import { COMMANDS } from "../constants"; import path from "path"; import { MILanguageClient } from "../lang-client/activator"; -import { extension } from "../MIExtensionContext"; +import { webviews } from "../visualizer/webview"; export async function replaceFullContentToFile(documentUri: string, content: string) { // Create the file if not present @@ -40,12 +40,18 @@ export async function replaceFullContentToFile(documentUri: string, content: str edit.replace(Uri.file(documentUri), fullRange, content); } + await workspace.applyEdit(edit); + const file = Uri.file(documentUri); + let document = workspace.textDocuments.find(doc => doc.uri.fsPath === documentUri) + || await workspace.openTextDocument(file); + await document.save(); + if (isNewFile) { // Wait for the file to be fully created and accessible const maxRetries = 5; const retryDelay = 100; - + let retries = 0; while (retries < maxRetries) { try { @@ -69,7 +75,7 @@ export async function askForProject(): Promise { for (const wrkspace of workspace.workspaceFolders!) { const lsClient = await MILanguageClient.getInstance(wrkspace.uri.fsPath); if (lsClient) { - const projectDetails = await lsClient.languageClient?.getProjectDetails(); + const projectDetails = await lsClient.getProjectDetails(); if (projectDetails?.primaryDetails?.projectName?.value) { if (projects.has(projectDetails.primaryDetails.projectName.value)) { projects.set(wrkspace.uri.fsPath, wrkspace.uri.fsPath); @@ -91,12 +97,12 @@ export async function askForProject(): Promise { return projects.get(quickPick)!; } -export async function saveIdpSchemaToFile(folderPath: string, fileName:string, fileContent?: string,imageOrPdf?:string): Promise { - const documentUri = path.join(folderPath, fileName +".json"); +export async function saveIdpSchemaToFile(folderPath: string, fileName: string, fileContent?: string, imageOrPdf?: string): Promise { + const documentUri = path.join(folderPath, fileName + ".json"); if (!fs.existsSync(folderPath)) { fs.mkdirSync(folderPath, { recursive: true }); } - if(fileContent){ + if (fileContent) { fs.writeFileSync(documentUri, fileContent, 'utf-8'); } if (imageOrPdf) { @@ -110,27 +116,77 @@ export async function saveIdpSchemaToFile(folderPath: string, fileName:string, f } const mimeTypeMatch = imageOrPdf.match(/^data:(.*?);base64,/); if (mimeTypeMatch) { - const mimeType = mimeTypeMatch[1]; + const mimeType = mimeTypeMatch[1]; let extension = ""; if (mimeType === "application/pdf") { extension = ".pdf"; } else if (mimeType.startsWith("image/")) { - extension = mimeType.split("/")[1]; + extension = mimeType.split("/")[1]; extension = `.${extension}`; } else { console.error("Unsupported MIME type:", mimeType); - return false; + return false; } - const base64Data = imageOrPdf.replace(/^data:.*;base64,/, ""); + const base64Data = imageOrPdf.replace(/^data:.*;base64,/, ""); const binaryData = Buffer.from(base64Data, "base64"); const filePath = path.join(folderPath, fileName + extension); fs.writeFileSync(filePath, binaryData); } else { console.error("Invalid base64 string format."); - return false; + return false; } } commands.executeCommand(COMMANDS.REFRESH_COMMAND); return true; } +export function enableLS(): Disposable[] { + const disposables: Disposable[] = []; + + const disposable1 = window.onDidChangeActiveTextEditor(async (event) => { + if (!event) { + return; + } + const document = event.document; + const projectUri = workspace.getWorkspaceFolder(document.uri)?.uri.fsPath; + if (!projectUri) { + return; + } + const hasActiveDocument = hasOpenedDocumentInProject(projectUri); + + if (hasActiveDocument) { + await MILanguageClient.getInstance(projectUri); + } + }); + + const disposable2 = workspace.onDidCloseTextDocument(async (document) => { + const projectUri = workspace.getWorkspaceFolder(document.uri)?.uri.fsPath; + if (!projectUri) { + return; + } + const hasActiveWebview = webviews.has(projectUri); + + if (hasActiveWebview) { + return; + } + const hasActiveDocument = hasOpenedDocumentInProject(projectUri); + + if (!hasActiveDocument) { + await MILanguageClient.stopInstance(projectUri); + } + }); + disposables.push(disposable1, disposable2); + return disposables; +} + +export function hasOpenedDocumentInProject(projectUri: string): boolean { + const artifactsPath = path.join(projectUri, 'src', 'main', 'wso2mi', 'artifacts'); + for (const tabGroup of window.tabGroups.all) { + for (const tab of tabGroup.tabs) { + if (tab.input instanceof TabInputText && tab.input.uri.fsPath.startsWith(artifactsPath)) { + return true; + } + } + } + return false; +} diff --git a/workspaces/mi/mi-extension/src/visualizer/activate.ts b/workspaces/mi/mi-extension/src/visualizer/activate.ts index a1d53917360..fc5696bce83 100644 --- a/workspaces/mi/mi-extension/src/visualizer/activate.ts +++ b/workspaces/mi/mi-extension/src/visualizer/activate.ts @@ -36,68 +36,84 @@ import { MiDiagramRpcManager } from '../rpc-managers/mi-diagram/rpc-manager'; import { log } from '../util/logger'; import { CACHED_FOLDER, INTEGRATION_PROJECT_DEPENDENCIES_DIR } from '../util/onboardingUtils'; import { getHash } from '../util/fileOperations'; +import { MILanguageClient } from '../lang-client/activator'; export function activateVisualizer(context: vscode.ExtensionContext, firstProject: string) { context.subscriptions.push( - vscode.commands.registerCommand(COMMANDS.OPEN_PROJECT, () => { - window.showOpenDialog({ canSelectFolders: true, canSelectFiles: true, filters: { 'CAPP': ['car', 'zip'] }, openLabel: 'Open MI Project' }) - .then(uri => { - if (uri && uri[0]) { - const handleOpenProject = (folderUri: vscode.Uri) => { - window.showInformationMessage('Where would you like to open the project?', - { modal: true }, - 'Current Window', - 'New Window' - ).then(selection => { - if (selection === "Current Window") { - const workspaceFolders = workspace.workspaceFolders || []; - if (!workspaceFolders.some(folder => folder.uri.fsPath === folderUri.fsPath)) { - workspace.updateWorkspaceFolders(workspaceFolders.length, 0, { uri: folderUri }); - } - } else if (selection === "New Window") { - commands.executeCommand('vscode.openFolder', folderUri); + vscode.commands.registerCommand(COMMANDS.OPEN_PROJECT, (providedUri?: vscode.Uri) => { + const processUri = (uri: vscode.Uri[] | undefined) => { + if (uri && uri[0]) { + const handleOpenProject = (folderUri: vscode.Uri) => { + window.showInformationMessage('Where would you like to open the project?', + { modal: true }, + 'Current Window', + 'New Window' + ).then(selection => { + if (selection === "Current Window") { + const workspaceFolders = workspace.workspaceFolders || []; + if (!workspaceFolders.some(folder => folder.uri.fsPath === folderUri.fsPath)) { + workspace.updateWorkspaceFolders(workspaceFolders.length, 0, { uri: folderUri }); } - }); - }; - if (uri[0].fsPath.endsWith('.car') || uri[0].fsPath.endsWith('.zip')) { - window.showInformationMessage('A car file (CAPP) is selected.\n Do you want to extract it?', { modal: true }, 'Extract') - .then(option => { - if (option === 'Extract') { - window.showOpenDialog({ canSelectFolders: true, canSelectFiles: false, title: 'Select the location to extract the CAPP', openLabel: 'Select Folder' }) - .then(extractUri => { - if (extractUri && extractUri[0]) { - importCapp({ source: uri[0].fsPath, directory: extractUri[0].fsPath, open: false }); - handleOpenProject(extractUri[0]); + } else if (selection === "New Window") { + commands.executeCommand('vscode.openFolder', folderUri); + } + }); + }; + if (uri[0].fsPath.endsWith('.car') || uri[0].fsPath.endsWith('.zip')) { + window.showInformationMessage('A car file (CAPP) is selected.\n Do you want to extract it?', { modal: true }, 'Extract') + .then(option => { + if (option === 'Extract') { + window.showOpenDialog({ canSelectFolders: true, canSelectFiles: false, title: 'Select the location to extract the CAPP', openLabel: 'Select Folder' }) + .then(async extractUri => { + if (extractUri && extractUri[0]) { + try { + const result = await importCapp({ source: uri[0].fsPath, directory: extractUri[0].fsPath, open: false }); + if (result.filePath) { + handleOpenProject(extractUri[0]); + } else { + window.showErrorMessage('Failed to import CAPP. Please check the file and try again.'); + } + } catch (error: any) { + window.showErrorMessage(`CAPP import failed: ${error.message}`); } - }); - } - }); + } + }); + } + }); + } else { + const webview = [...webviews.values()].find(webview => webview.getWebview()?.active) || [...webviews.values()][0]; + const projectUri = webview ? webview.getProjectUri() : firstProject; + const projectOpened = getStateMachine(projectUri).context().projectOpened; + if (projectOpened) { + handleOpenProject(uri[0]); } else { - const webview = [...webviews.values()].find(webview => webview.getWebview()?.active) || [...webviews.values()][0]; - const projectUri = webview ? webview.getProjectUri() : firstProject; - const projectOpened = getStateMachine(projectUri).context().projectOpened; - if (projectOpened) { - handleOpenProject(uri[0]); - } else { - commands.executeCommand('vscode.openFolder', uri[0]); - } + commands.executeCommand('vscode.openFolder', uri[0]); } } - }); + } + }; + + if (providedUri) { + processUri([providedUri]); + } else { + window.showOpenDialog({ canSelectFolders: true, canSelectFiles: true, filters: { 'CAPP': ['car', 'zip'] }, openLabel: 'Open MI Project' }) + .then(processUri); + } }), commands.registerCommand(COMMANDS.CREATE_PROJECT_COMMAND, async (args) => { if (args && args.name && args.path && args.scope) { const rpcManager = new MiDiagramRpcManager(""); if (rpcManager) { - await rpcManager.createProject( + const result = await rpcManager.createProject( { directory: path.dirname(args.path), name: path.basename(args.path), - open: false, + open: args.open ?? false, miVersion: "4.4.0" } ); await createSettingsFile(args); + return result; } async function createSettingsFile(args) { @@ -193,9 +209,8 @@ export function activateVisualizer(context: vscode.ExtensionContext, firstProjec // Listen for pom changes and update dependencies context.subscriptions.push( // Handle the text change and diagram update with rpc notification - vscode.workspace.onDidChangeTextDocument(async function (document) { - const projectUri = vscode.workspace.getWorkspaceFolder(document.document.uri)?.uri.fsPath; - + vscode.workspace.onDidChangeTextDocument(async function (e : vscode.TextDocumentChangeEvent) { + const projectUri = vscode.workspace.getWorkspaceFolder(e.document.uri)?.uri.fsPath; if (!projectUri) { return; } @@ -206,20 +221,20 @@ export function activateVisualizer(context: vscode.ExtensionContext, firstProjec return; } - if (!REFRESH_ENABLED_DOCUMENTS.includes(document.document.languageId) || !projectUri) { + if (!REFRESH_ENABLED_DOCUMENTS.includes(e.document.languageId) || !projectUri) { return; } if (webview?.getWebview()?.active || AiPanelWebview.currentPanel?.getWebview()?.active) { - await document.document.save(); - if (!getStateMachine(projectUri).context().view?.endsWith('Form') && document?.document?.uri?.fsPath?.includes(artifactsDir)) { + await e.document.save(); + if (!getStateMachine(projectUri).context().view?.endsWith('Form') && e?.document?.uri?.fsPath?.includes(artifactsDir)) { refreshDiagram(projectUri); } } - if (document.document.uri.fsPath.endsWith('pom.xml')) { - const projectUri = vscode.workspace.getWorkspaceFolder(document.document.uri)?.uri.fsPath; - const langClient = getStateMachine(projectUri!).context().langClient; + if (e.document.uri.fsPath.endsWith('pom.xml')) { + const projectUri = vscode.workspace.getWorkspaceFolder(e.document.uri)?.uri.fsPath; + const langClient = await MILanguageClient.getInstance(projectUri!); const confirmUpdate = await vscode.window.showInformationMessage( 'The pom.xml file has been modified. Do you want to update the dependencies?', @@ -328,6 +343,62 @@ export function activateVisualizer(context: vscode.ExtensionContext, firstProjec generateSwagger(document.uri.fsPath); } + const swaggerDir = path.join(projectUri!, "src", "main", "wso2mi", "resources", "api-definitions"); + if (document?.uri.fsPath.includes(swaggerDir)) { + const rpcManager = new MiDiagramRpcManager(projectUri!); + const langClient = await MILanguageClient.getInstance(projectUri!); + const apiPath = path.join(apiDir, path.basename(document?.uri.fsPath, path.extname(document?.uri.fsPath)) + '.xml'); + const apiName = path.basename(document?.uri.fsPath).split("_v")[0]; + langClient?.getSyntaxTree({ + documentIdentifier: { + uri: apiPath + } + }).then(st => { + rpcManager.compareSwaggerAndAPI({ + apiName: apiName, + apiPath: apiPath + }).then(async response => { + if (response.swaggerExists && !response.isEqual) { + const confirmUpdate = await vscode.window.showInformationMessage( + 'The OpenAPI definition is different from the Synapse API.', + { modal: true }, + "Update API", "Update Swagger" + ); + switch (confirmUpdate) { + case "Update Swagger": + rpcManager.updateSwaggerFromAPI({ + apiName: apiName, + apiPath: apiPath, + existingSwagger: response.existingSwagger, + generatedSwagger: response.generatedSwagger + }); + break; + case "Update API": + const resources = getResources(st); + rpcManager.updateAPIFromSwagger({ + apiName: apiName, + apiPath: apiPath, + existingSwagger: response.existingSwagger, + generatedSwagger: response.generatedSwagger, + resources: resources.map(r => ({ + path: r.path, + methods: r.methods, + position: r.position + })), + insertPosition: { + line: st.syntaxTree.api.range.endTagRange.start.line, + character: st.syntaxTree.api.range.endTagRange.start.character + } + }); + break; + default: + break; + } + } + }) + }); + } + if (currentView !== 'Connector Store Form' && document?.uri?.fsPath?.includes(artifactsDir) || currentView === MACHINE_VIEW.IdpConnectorSchemaGeneratorForm) { refreshDiagram(projectUri!); } @@ -400,3 +471,18 @@ export const refreshDiagram = debounce(async (projectUri: string, refreshDiagram refreshUI(projectUri); } }, 500); + +const getResources = (st: any): any[] => { + const resources: any[] = st?.syntaxTree?.api?.resource ?? []; + return resources.map((resource) => ({ + methods: resource.methods, + path: resource.uriTemplate || resource.urlMapping, + position: { + startLine: resource.range.startTagRange.start.line, + startColumn: resource.range.startTagRange.start.character, + endLine: resource.range.endTagRange.end.line, + endColumn: resource.range.endTagRange.end.character, + }, + expandable: false + })); +}; diff --git a/workspaces/mi/mi-extension/src/visualizer/webview.ts b/workspaces/mi/mi-extension/src/visualizer/webview.ts index 41805e0baa2..eac6d9bd21c 100644 --- a/workspaces/mi/mi-extension/src/visualizer/webview.ts +++ b/workspaces/mi/mi-extension/src/visualizer/webview.ts @@ -29,6 +29,7 @@ import { MACHINE_VIEW } from '@wso2/mi-core'; import { refreshDiagram } from './activate'; import { MILanguageClient } from '../lang-client/activator'; import { deletePopupStateMachine } from '../stateMachinePopup'; +import { hasOpenedDocumentInProject } from '../util/workspace'; export const webviews: Map = new Map(); export class VisualizerWebview { @@ -124,7 +125,7 @@ export class VisualizerWebview { // The JS file from the React build output const jsFiles = getComposerJSFiles(extension.context, 'Visualizer', webview); console.debug('JS files to be included:', jsFiles); - + const scriptUri = jsFiles.map(jsFile => { const scriptTag = ''; console.debug('Generated script tag:', scriptTag); @@ -277,7 +278,12 @@ export class VisualizerWebview { deleteStateMachine(this.projectUri); deletePopupStateMachine(this.projectUri); RPCLayer._messengers.delete(this.projectUri); - await MILanguageClient.stopInstance(this.projectUri); + const hasActiveDocument = hasOpenedDocumentInProject(this.projectUri); + + if (!hasActiveDocument) { + await MILanguageClient.stopInstance(this.projectUri); + } + this._panel?.dispose(); while (this._disposables.length) { diff --git a/workspaces/mi/mi-visualizer/src/MainPanel.tsx b/workspaces/mi/mi-visualizer/src/MainPanel.tsx index 445a833fd34..0fc83e8fa5a 100644 --- a/workspaces/mi/mi-visualizer/src/MainPanel.tsx +++ b/workspaces/mi/mi-visualizer/src/MainPanel.tsx @@ -2,7 +2,8 @@ import React, { useEffect, useState, Suspense } from 'react'; import { POPUP_EVENT_TYPE, PopupMachineStateValue, MACHINE_VIEW, Platform, VisualizerLocation } from '@wso2/mi-core'; import { useVisualizerContext } from '@wso2/mi-rpc-client'; import { ServiceDesignerView } from './views/ServiceDesigner'; -import { DSSServiceDesignerView } from './views/Forms/DataServiceForm/ServiceDesigner'; +import { DSSResourceServiceDesignerView } from './views/Forms/DataServiceForm/ResourceServiceDesigner'; +import { DSSQueryServiceDesignerView } from './views/Forms/DataServiceForm/QueryServiceDesigner'; import { APIWizard, APIWizardProps } from './views/Forms/APIform'; import { EndpointWizard } from './views/Forms/EndpointForm'; import { SequenceWizard } from './views/Forms/SequenceForm'; @@ -376,8 +377,11 @@ const MainPanel = (props: MainPanelProps) => { case MACHINE_VIEW.MockService: setViewComponent(); break; - case MACHINE_VIEW.DSSServiceDesigner: - setViewComponent(); + case MACHINE_VIEW.DSSResourceServiceDesigner: + setViewComponent(); + break; + case MACHINE_VIEW.DSSQueryServiceDesigner: + setViewComponent(); break; case MACHINE_VIEW.Welcome: setViewComponent(); diff --git a/workspaces/mi/mi-visualizer/src/constants/index.ts b/workspaces/mi/mi-visualizer/src/constants/index.ts index 1a7734909bf..b125d643885 100644 --- a/workspaces/mi/mi-visualizer/src/constants/index.ts +++ b/workspaces/mi/mi-visualizer/src/constants/index.ts @@ -69,6 +69,10 @@ export const DSS_TEMPLATES = { EDIT_OPERATION: "edit-dss-operation", EDIT_DESCRIPTION: "edit-dss-description", ADD_QUERY: "add-dss-query", + ADD_FULL_QUERY: "add-full-dss-query", + UPDATE_QUERY_CONFIG: "update-query-config", + UPDATE_QUERY: "update-query", + EDIT_QUERY_REFERENCE: "edit-query-reference" } as const; export enum EndpointTypes { diff --git a/workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts b/workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts index 086d6d1ca66..b7f393ec2de 100644 --- a/workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts +++ b/workspaces/mi/mi-visualizer/src/utils/DSSResourceForm.ts @@ -15,12 +15,13 @@ * specific language governing permissions and limitations * under the License. */ -import { Range, DSSResource, DSSOperation } from "@wso2/mi-syntax-tree/lib/src"; +import { Range, DSSResource, DSSOperation, DSSQuery } from "@wso2/mi-syntax-tree/lib/src"; import { RpcClient } from "@wso2/mi-rpc-client"; import { DSS_TEMPLATES } from "../constants"; import { getXML } from "./template-engine/mustache-templates/templateUtils"; import { ResourceFormData, ResourceType } from "../views/Forms/DataServiceForm/SidePanelForms/ResourceForm"; import { OperationFormData, OperationType } from "../views/Forms/DataServiceForm/SidePanelForms/OperationForm"; +import { QueryFormData, QueryType } from "../views/Forms/DataServiceForm/SidePanelForms/QueryForm"; export const generateResourceData = (model: DSSResource): ResourceType => { @@ -29,7 +30,8 @@ export const generateResourceData = (model: DSSResource): ResourceType => { resourceMethod: model.method, description: model.description, enableStreaming: model.enableStreaming, - returnRequestStatus: model.returnRequestStatus + returnRequestStatus: model.returnRequestStatus, + queryId: model.queryId }; return resourceData; }; @@ -39,14 +41,26 @@ export const generateOperationData = (model: DSSOperation): OperationType => { const operationData: OperationType = { operationName: model.name, description: model.description, - enableStreaming: model.enableStreaming + enableStreaming: model.enableStreaming, + queryId: model.queryId }; return operationData; }; +export const generateQueryData = (model: DSSQuery): QueryType => { + + const queryData: QueryType = { + name: model.name, + datasource: model.datasource, + query: model.query, + }; + return queryData; +}; + export const onResourceCreate = (data: ResourceFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => { - const queryName = data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query"; + const queryName = data.queryId !== "" ? data.queryId : data.resourceMethod.toLowerCase() + "_" + data.resourcePath.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query"; + const shouldCreateQuery = data.queryId === ""; const formValues = { path: data.resourcePath, @@ -57,7 +71,7 @@ export const onResourceCreate = (data: ResourceFormData, range: Range, documentU query: queryName }; - const queryContent = getXML(DSS_TEMPLATES.ADD_QUERY, { name: queryName, dbName: dbName }); + const queryContent = shouldCreateQuery ? getXML(DSS_TEMPLATES.ADD_QUERY, { name: queryName, dbName: dbName }) : ""; const resourceContent = getXML(DSS_TEMPLATES.ADD_RESOURCE, formValues); rpcClient.getMiDiagramRpcClient().applyEdit({ text: queryContent + resourceContent, @@ -77,7 +91,8 @@ export const onResourceCreate = (data: ResourceFormData, range: Range, documentU export const onOperationCreate = (data: OperationFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => { - const queryName = data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query"; + const queryName = data.queryId !== "" ? data.queryId : data.operationName.replace(/[^a-zA-Z]/g, '').toLowerCase() + "_query"; + const shouldCreateQuery = data.queryId === ""; const formValues = { name: data.operationName, @@ -86,7 +101,7 @@ export const onOperationCreate = (data: OperationFormData, range: Range, documen query: queryName }; - const queryContent = getXML(DSS_TEMPLATES.ADD_QUERY, { name: queryName, dbName: dbName }); + const queryContent = shouldCreateQuery ? getXML(DSS_TEMPLATES.ADD_QUERY, { name: queryName, dbName: dbName }) : ""; const operationContent = getXML(DSS_TEMPLATES.ADD_OPERATION, formValues); rpcClient.getMiDiagramRpcClient().applyEdit({ text: queryContent + operationContent, @@ -104,10 +119,45 @@ export const onOperationCreate = (data: OperationFormData, range: Range, documen }); }; +export const onQueryCreate = (data: QueryFormData, range: Range, documentUri: string, rpcClient: RpcClient, dbName: string) => { + + const formValues = { + name: data.name, + datasource: data.datasource, + query: data.query + }; + + getQueryType(rpcClient, documentUri, data.datasource) + .then((queryType) => { + const queryContent = getXML(DSS_TEMPLATES.ADD_FULL_QUERY, { + ...formValues, + isExpression: queryType === "expression" + }); + + return rpcClient.getMiDiagramRpcClient().applyEdit({ + text: queryContent, + documentUri, + range: { + start: { + line: range.end.line, + character: range.end.character, + }, + end: { + line: range.end.line, + character: range.end.character, + } + } + }); + }); + +}; + export const onResourceEdit = (data: ResourceFormData, selectedResource: any, documentUri: string, rpcClient: RpcClient) => { const resourceStartTagRange = selectedResource.range.startTagRange; const descriptionStartTagRange = selectedResource.description ? selectedResource.description.range.startTagRange : undefined; const descriptionEndTagRange = selectedResource.description ? selectedResource.description.range.endTagRange : undefined; + const referenceQueryTagRange = selectedResource.callQuery ? selectedResource.callQuery.range.startTagRange : undefined; + const isReferenceSelfClosed = selectedResource.callQuery?.selfClosed ?? true; const formValues = { path: data.resourcePath, method: data.resourceMethod, @@ -118,11 +168,20 @@ export const onResourceEdit = (data: ResourceFormData, selectedResource: any, do const resourceXML = getXML(DSS_TEMPLATES.EDIT_RESOURCE, formValues); const descriptionXML = data.description === "" ? "" : getXML(DSS_TEMPLATES.EDIT_DESCRIPTION, {description: data.description}); + const queryReferenceXML = getXML(DSS_TEMPLATES.EDIT_QUERY_REFERENCE, { queryId: data.queryId, isSelfClosed: isReferenceSelfClosed }); rpcClient.getMiDiagramRpcClient().applyEdit({ text: resourceXML, documentUri: documentUri, range: resourceStartTagRange + }).then(async () => { + if (referenceQueryTagRange) { + await rpcClient.getMiDiagramRpcClient().applyEdit({ + text: queryReferenceXML, + documentUri: documentUri, + range: referenceQueryTagRange + }); + } }).then(async () => { await rpcClient.getMiDiagramRpcClient().applyEdit({ text: descriptionXML, @@ -131,14 +190,16 @@ export const onResourceEdit = (data: ResourceFormData, selectedResource: any, do start: descriptionStartTagRange ? descriptionStartTagRange.start : resourceStartTagRange.end, end: descriptionEndTagRange ? descriptionEndTagRange.end : resourceStartTagRange.end } - }) - }) + }); + }); }; export const onOperationEdit = (data: OperationFormData, selectedOperation: any, documentUri: string, rpcClient: RpcClient) => { const operationStartTagRange = selectedOperation.range.startTagRange; const descriptionStartTagRange = selectedOperation.description ? selectedOperation.description.range.startTagRange : undefined; const descriptionEndTagRange = selectedOperation.description ? selectedOperation.description.range.endTagRange : undefined; + const referenceQueryTagRange = selectedOperation.callQuery ? selectedOperation.callQuery.range.startTagRange : undefined; + const isReferenceSelfClosed = selectedOperation.callQuery?.selfClosed ?? true; const formValues = { name: data.operationName, enableStreaming: data.enableStreaming ? undefined : !data.enableStreaming, @@ -147,19 +208,80 @@ export const onOperationEdit = (data: OperationFormData, selectedOperation: any, const operationXML = getXML(DSS_TEMPLATES.EDIT_OPERATION, formValues); const descriptionXML = data.description === "" ? "" : getXML(DSS_TEMPLATES.EDIT_DESCRIPTION, {description: data.description}); + const queryReferenceXML = getXML(DSS_TEMPLATES.EDIT_QUERY_REFERENCE, { queryId: data.queryId, isSelfClosed: isReferenceSelfClosed }); rpcClient.getMiDiagramRpcClient().applyEdit({ text: operationXML, documentUri: documentUri, range: operationStartTagRange, }).then(async () => { - await rpcClient.getMiDiagramRpcClient().applyEdit({ + if (referenceQueryTagRange) { + await rpcClient.getMiDiagramRpcClient().applyEdit({ + text: queryReferenceXML, + documentUri: documentUri, + range: referenceQueryTagRange + }); + } + }).then(async () => { + await rpcClient.getMiDiagramRpcClient().applyEdit({ text: descriptionXML, documentUri: documentUri, range: { start: descriptionStartTagRange ? descriptionStartTagRange.start : operationStartTagRange.end, end: descriptionEndTagRange ? descriptionEndTagRange.end : operationStartTagRange.end } - }) - }) + }); + }); +}; + +export const onQueryEdit = (data: QueryFormData, selectedQuery: any, documentUri: string, rpcClient: RpcClient) => { + const sqlOrExpressionStartTagRange = selectedQuery?.sql ? selectedQuery.sql?.range?.startTagRange : + selectedQuery?.expression ? selectedQuery.expression?.range?.startTagRange : undefined; + const sqlOrExpressionEndTagRange = selectedQuery?.sql ? selectedQuery.sql?.range?.endTagRange : + selectedQuery?.expression ? selectedQuery.expression?.range?.endTagRange : undefined; + const formValues = { + name: data.name, + datasource: data.datasource, + query: data.query + }; + + getQueryType(rpcClient, documentUri, data.datasource) + .then((queryType) => { + return rpcClient.getMiDiagramRpcClient().applyEdit({ + text: getXML(DSS_TEMPLATES.UPDATE_QUERY_CONFIG, formValues), + documentUri, + range: selectedQuery.range.startTagRange, + }).then(() => ({ queryType })); + }) + .then(({ queryType }) => { + return rpcClient.getMiDiagramRpcClient().applyEdit({ + text: getXML(DSS_TEMPLATES.UPDATE_QUERY, { + query: data.query, + isExpression: queryType === "expression" + }), + documentUri, + range: { + start: sqlOrExpressionStartTagRange ? sqlOrExpressionStartTagRange.start : selectedQuery.range.startTagRange.end, + end: sqlOrExpressionEndTagRange ? sqlOrExpressionEndTagRange.end : selectedQuery.range.startTagRange.end + } + }); + }); + }; + +async function getQueryType(rpcClient: RpcClient, documentUri: string, datasource: string): Promise { + let queryType = "sql"; + const existingDataService = await rpcClient.getMiDiagramRpcClient().getDataService({ path: documentUri }); + existingDataService.datasources.forEach((ds) => { + if (ds.dataSourceName === datasource) { + const propertyKeys: string[] = []; + ds.datasourceProperties.forEach((attr: any) => { + propertyKeys.push(attr.key); + }); + if (propertyKeys.includes("mongoDB_servers")) { + queryType = "expression"; + } + } + }); + return queryType; +} diff --git a/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts b/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts index 78a052f0027..41ae3b61f5f 100644 --- a/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts +++ b/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/core/DSS.ts @@ -40,6 +40,24 @@ export function getAddQuery() { ` } +export function getAddFullQuery() { + return ` +{{#isExpression}}{{query}}{{/isExpression}}{{^isExpression}}{{query}}{{/isExpression}} +` +} + +export function getQueryConfig() { + return `` +} + +export function getSQLQuery() { + return `{{query}}` +} + +export function getExpressionQuery() { + return `{{query}}` +} + export function getEditOperationTemplate() { return `` } @@ -47,3 +65,7 @@ export function getEditOperationTemplate() { export function getEditDescriptionTemplate() { return `{{description}}` } + +export function getEditQueryReferenceTemplate() { + return `` +} diff --git a/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts b/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts index 15d6de6821b..f0bbabeaade 100644 --- a/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts +++ b/workspaces/mi/mi-visualizer/src/utils/template-engine/mustache-templates/templateUtils.ts @@ -33,7 +33,12 @@ import { getEditOperationTemplate, getEditResourceTemplate, getEditDescriptionTemplate, - getAddQuery + getEditQueryReferenceTemplate, + getAddQuery, + getAddFullQuery, + getQueryConfig, + getExpressionQuery, + getSQLQuery } from "./core/DSS"; export function getXML(name: string, data: { [key: string]: any }) { @@ -62,8 +67,16 @@ export function getXML(name: string, data: { [key: string]: any }) { return Mustache.render(getEditOperationTemplate(), data); case DSS_TEMPLATES.EDIT_DESCRIPTION: return Mustache.render(getEditDescriptionTemplate(), data); + case DSS_TEMPLATES.EDIT_QUERY_REFERENCE: + return Mustache.render(getEditQueryReferenceTemplate(), data); case DSS_TEMPLATES.ADD_QUERY: return Mustache.render(getAddQuery(), data); + case DSS_TEMPLATES.ADD_FULL_QUERY: + return Mustache.render(getAddFullQuery(), data); + case DSS_TEMPLATES.UPDATE_QUERY_CONFIG: + return Mustache.render(getQueryConfig(), data); + case DSS_TEMPLATES.UPDATE_QUERY: + return data.isExpression ? Mustache.render(getExpressionQuery(), data) : Mustache.render(getSQLQuery(), data); default: return ""; } diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/AddressEndpointForm.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/AddressEndpointForm.tsx index 8a796ebcac7..5b189b62726 100644 --- a/workspaces/mi/mi-visualizer/src/views/Forms/AddressEndpointForm.tsx +++ b/workspaces/mi/mi-visualizer/src/views/Forms/AddressEndpointForm.tsx @@ -240,7 +240,8 @@ export function AddressEndpointWizard(props: AddressEndpointWizardProps) { id: 0, type: "TextField", label: "Parameter", - defaultValue: "parameter_value", + placeholder: "parameter_value", + defaultValue: "", isRequired: true }] } diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/index.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/index.tsx index 60adeb1e9d7..971b6199fd1 100644 --- a/workspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/index.tsx +++ b/workspaces/mi/mi-visualizer/src/views/Forms/ConnectionForm/index.tsx @@ -235,6 +235,7 @@ export function ConnectionWizard(props: ConnectionStoreProps) { } catch (e) { setStoreConnectors(null); console.error("Error fetching connectors", e); + rpcClient.getMiVisualizerRpcClient().showNotification({message: "Error occurred while fetching connectors", type: "error"}); } setIsFetchingStoreConnectors(false); }; diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx index df1110cdf23..3e0b336a8a8 100644 --- a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx +++ b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/MainPanelForms/index.tsx @@ -273,7 +273,7 @@ export function DataServiceWizard(props: DataServiceWizardProps) { } else if (isNewDataService) { rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.Overview } }); } else { - rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DSSServiceDesigner, documentUri: props.path } }); + rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DSSResourceServiceDesigner, documentUri: props.path } }); } }; diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx new file mode 100644 index 00000000000..ff615c352df --- /dev/null +++ b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/QueryServiceDesigner.tsx @@ -0,0 +1,227 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * 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 React, { useEffect } from "react"; +import { EVENT_TYPE, MACHINE_VIEW } from "@wso2/mi-core"; +import { useVisualizerContext } from "@wso2/mi-rpc-client"; +import { Resource, Service, ServiceDesigner } from "@wso2/service-designer"; +import { Item } from "@wso2/ui-toolkit"; +import { View, ViewHeader, ViewContent } from "../../../components/View"; +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"; +import { Codicon } from "@wso2/ui-toolkit"; +import { generateQueryData, onQueryCreate, onQueryEdit } from "../../../utils/DSSResourceForm"; +import { QueryForm, QueryFormData } from "../../Forms/DataServiceForm/SidePanelForms/QueryForm"; + +interface ServiceDesignerProps { + syntaxTree: any; + documentUri: string; +} +export function DSSQueryServiceDesignerView({ syntaxTree, documentUri }: ServiceDesignerProps) { + const { rpcClient } = useVisualizerContext(); + const [queryServiceModel, setQueryServiceModel] = React.useState(null); + const [isQueryFormOpen, setQueryFormOpen] = React.useState(false); + const [queryBodyRange, setQueryBodyRange] = React.useState(null); + const [formData, setFormData] = React.useState(null); + const [mode, setMode] = React.useState<"create" | "edit">("create"); + const [selectedQuery, setSelectedQuery] = React.useState(null); + + const getQueries = (st: any): Resource[] => { + let queries: any = st.data.queries ?? []; + return queries.map((query: any) => { + const value: any = { + methods: [query.useConfig], + path: query.id, + position: { + startLine: query.range.startTagRange.start.line, + startColumn: query.range.startTagRange.start.character, + endLine: query.range.endTagRange.end.line, + endColumn: query.range.endTagRange.end.character, + }, + expandable: false, + }; + const currentQuery: any = { + name: query.id, + datasource: query.useConfig, + query: query.sql?.value ?? query.expression?.value ?? "", + position: { + startLine: query.range.startTagRange.start.line, + startColumn: query.range.startTagRange.start.character, + endLine: query.range.endTagRange.end.line, + endColumn: query.range.endTagRange.end.character, + }, + expandable: false, + }; + const goToSourceAction: Item = { + id: "go-to-source", + label: "Go to Source", + onClick: () => highlightCode(value, true), + }; + const editAction: Item = { + id: "edit", + label: "Edit", + onClick: () => { + setFormData(generateQueryData(currentQuery)); + setSelectedQuery(query); + setMode("edit"); + setQueryFormOpen(true); + }, + }; + const deleteAction: Item = { + id: "delete", + label: "Delete", + onClick: () => handleDelete(query) + }; + const moreActions: Item[] = [goToSourceAction, editAction, deleteAction]; + return { + ...value, + additionalActions: moreActions, + }; + }); + }; + + useEffect(() => { + const st = syntaxTree; + + const queries: Resource[] = getQueries(st); + setQueryBodyRange({ + start: st.data.range.startTagRange.end, + end: st.data.range.endTagRange.start + }); + const queryModel: Service = { + path: st.context, + resources: queries + } + setQueryServiceModel(queryModel); + + }, [syntaxTree, documentUri]); + + const highlightCode = (query: Resource, force?: boolean) => { + rpcClient.getMiDiagramRpcClient().highlightCode({ + range: { + start: { + line: query.position.startLine, + character: query.position.startColumn, + + }, + end: { + line: query.position.endLine, + character: query.position.endColumn, + }, + }, + force: force, + }); + }; + + const openDiagram = (query: Resource) => { + const href = query.path; + if (!href) { + rpcClient.getMiDiagramRpcClient().showErrorMessage({ message: "Cannot find the query for selected resource" }); + return; + } + rpcClient.getMiVisualizerRpcClient().openView({ type: EVENT_TYPE.OPEN_VIEW, location: { view: MACHINE_VIEW.DataServiceView, documentUri: documentUri, identifier: href } }) + } + + const handleManageResources = () => { + rpcClient.getMiVisualizerRpcClient().openView({ + type: EVENT_TYPE.OPEN_VIEW, + location: { + view: MACHINE_VIEW.DSSResourceServiceDesigner, + documentUri: documentUri + } + }); + } + + const handleQueryAdd = () => { + setMode("create"); + setQueryFormOpen(true); + }; + + const handleCancel = () => { + setQueryFormOpen(false); + }; + + const handleQueryCreate = (formData: QueryFormData) => { + switch (formData.mode) { + case "create": + let dbName = ""; + if (syntaxTree.data.configs !== undefined && syntaxTree.data.configs !== null && syntaxTree.data.configs.length > 0) { + dbName = syntaxTree.data.configs[0].id; + } + onQueryCreate(formData, queryBodyRange, documentUri, rpcClient, dbName); + break; + case "edit": + onQueryEdit(formData, selectedQuery, documentUri, rpcClient); + break; + } + setQueryFormOpen(false); + }; + + const handleDelete = (currentQuery: any) => { + rpcClient.getMiDiagramRpcClient().applyEdit({ + text: "", + documentUri: documentUri, + range: { + start: { + line: currentQuery.range.startTagRange.start.line, + character: currentQuery.range.startTagRange.start.character, + }, + end: { + line: currentQuery.range.endTagRange.end.line, + character: currentQuery.range.endTagRange.end.character, + }, + }, + }); + }; + + const handleQueryClick = (query: Resource) => { + highlightCode(query); + openDiagram(query); + }; + + return ( + <> + {queryServiceModel && ( + + + + Manage Resources + + + Add Query + + + + + + + )} + + + ); +} diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ServiceDesigner.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx similarity index 94% rename from workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ServiceDesigner.tsx rename to workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx index edddcc6f553..14c9917257d 100644 --- a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ServiceDesigner.tsx +++ b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/ResourceServiceDesigner.tsx @@ -33,7 +33,7 @@ interface ServiceDesignerProps { syntaxTree: any; documentUri: string; } -export function DSSServiceDesignerView({ syntaxTree, documentUri }: ServiceDesignerProps) { +export function DSSResourceServiceDesignerView({ syntaxTree, documentUri }: ServiceDesignerProps) { const { rpcClient } = useVisualizerContext(); const [resourceServiceModel, setResourceServiceModel] = React.useState(null); const [operationServiceModel, setOperationServiceModel] = React.useState(null); @@ -68,6 +68,7 @@ export function DSSServiceDesignerView({ syntaxTree, documentUri }: ServiceDesig description: resource.description ? resource.description.textNode : "", enableStreaming: !resource.disableStreaming, returnRequestStatus: resource.returnRequestStatus ?? false, + queryId: resource.callQuery ? resource.callQuery.href : "", position: { startLine: resource.range.startTagRange.start.line, startColumn: resource.range.startTagRange.start.character, @@ -120,6 +121,7 @@ export function DSSServiceDesignerView({ syntaxTree, documentUri }: ServiceDesig }; const currentOperation: any = { name: operation.name, + queryId: operation.callQuery ? operation.callQuery.href : "", description: operation.description ? operation.description.textNode : "", enableStreaming: !operation.disableStreaming, position: { @@ -232,6 +234,16 @@ export function DSSServiceDesignerView({ syntaxTree, documentUri }: ServiceDesig setOperationFormOpen(true); }; + const handleManageQueries = () => { + rpcClient.getMiVisualizerRpcClient().openView({ + type: EVENT_TYPE.OPEN_VIEW, + location: { + view: MACHINE_VIEW.DSSQueryServiceDesigner, + documentUri: documentUri + } + }); + } + const handleCancel = () => { setResourceFormOpen(false); setOperationFormOpen(false); @@ -306,7 +318,10 @@ export function DSSServiceDesignerView({ syntaxTree, documentUri }: ServiceDesig <> {(resourceServiceModel || operationServiceModel) && ( - + + + Manage Queries + {showResources ? ( diff --git a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx index 188d1671805..9fb8a167e1e 100644 --- a/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx +++ b/workspaces/mi/mi-visualizer/src/views/Forms/DataServiceForm/SidePanelForms/OperationForm.tsx @@ -21,8 +21,11 @@ import { Button, TextField, SidePanel, SidePanelTitleContainer, SidePanelBody, C import * as yup from "yup"; import styled from "@emotion/styled"; import { SIDE_PANEL_WIDTH } from "../../../../constants"; -import { useForm } from "react-hook-form"; +import { useForm, Controller } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; +import { Keylookup } from "@wso2/mi-diagram"; +import { openPopup } from "@wso2/mi-diagram/lib/components/Form/common"; +import { useVisualizerContext } from '@wso2/mi-rpc-client'; const ActionContainer = styled.div` display: flex; @@ -60,20 +63,31 @@ namespace Section { type OperationFields = { operationName: string; + queryId?: string; description: string; enableStreaming: boolean; + useExistingQuery?: boolean; }; const newOperation: OperationFields = { operationName: "", + queryId: "", description: "", - enableStreaming: false + enableStreaming: false, + useExistingQuery: false }; const schema = yup.object({ operationName: yup.string().required("Operation name is required"), + queryId: yup.string().when("useExistingQuery", { + is: true, + then: (schema) => + schema.required("Query ID is required"), + otherwise: (schema) => schema.notRequired(), + }), description: yup.string().notRequired(), - enableStreaming: yup.boolean().notRequired() + enableStreaming: yup.boolean().notRequired(), + useExistingQuery: yup.boolean().notRequired() }); export type OperationType = yup.InferType; @@ -90,10 +104,11 @@ type OperationFormProps = { onSave: (data: OperationFormData) => void; }; -export const OperationForm = ({ isOpen, onCancel, onSave, formData }: OperationFormProps) => { +export const OperationForm = ({ isOpen, onCancel, onSave, formData, documentUri }: OperationFormProps) => { const { control, handleSubmit, + watch, formState: { errors, isDirty }, register, reset @@ -103,6 +118,8 @@ export const OperationForm = ({ isOpen, onCancel, onSave, formData }: OperationF mode: "onChange", }); + const { rpcClient } = useVisualizerContext(); + useEffect(() => { if (isOpen && formData) { reset(formData); @@ -152,6 +169,31 @@ export const OperationForm = ({ isOpen, onCancel, onSave, formData }: OperationF size={150} {...renderProps('operationName')} /> + { !formData && ( + + )} + + { (formData || watch("useExistingQuery")) && ( + ( + { + openPopup(rpcClient, "dssQuery", fetchItems, handleValueChange, documentUri, { datasource: undefined }); + }} + onValueChange={field.onChange} + required={true} + /> + )} + /> + )}